code: def convert_to_binary(variables, domains, constraints):
      
  
      def wdiff(vars_):
          def diff(variables, values):
              hidden, other = variables
              if hidden.startswith('hidden'):
                  idx = vars_.index(other)
                  return values[1] == values[0][idx]
              else:
                  idx = vars_.index(hidden)
                  return values[0] == values[1][idx]
          diff.no_wrap = True  # so it's not wrapped to swap values
          return diff
  
      new_constraints = []
      new_domains = copy(domains)
      new_variables = list(variables)
      last = 0
  
      for vars_, const in constraints:
          if len(vars_) == 2:
              new_constraints.append((vars_, const))
              continue
  
          hidden = 'hidden%d' % last
          new_variables.append(hidden)
          last += 1
          new_domains[hidden] = [t for t in product(*map(domains.get, vars_)) if const(vars_, t)]
          for var in vars_:
              new_constraints.append(((hidden, var), wdiff(vars_)))
      return new_variables, new_domains, new_constraints
docs: Returns new constraint list, all binary, using hidden variables.
  
      You can use it as previous step when creating a problem.