def cnf_1bitadder(cnf: Formula, a: Variable, b: Variable, c: Variable) -> Tuple[Variable, Variable]: res = cnf.new_var() res_carry = cnf.new_var() # (d|a|~b|~c)&(d|~a|b|~c)&(d|~a|~b|c)&(d|~a|~b|~c)&(~d|a|b|c)&(~d|a|b|~c)&(~d|a|~b|c)&(~d|~a|b|c) cnf.add([res_carry, a, ~b, ~c]) cnf.add([res_carry, ~a, b, ~c]) cnf.add([res_carry, ~a, ~b, c]) cnf.add([res_carry, ~a, ~b, ~c]) cnf.add([~res_carry, a, b, c]) cnf.add([~res_carry, a, b, ~c]) cnf.add([~res_carry, a, ~b, c]) cnf.add([~res_carry, ~a, b, c]) # (d|a|b|~c)&(d|a|~b|c)&(d|~a|b|c)&(d|~a|~b|~c)&(~d|a|b|c)&(~d|a|~b|~c)&(~d|~a|b|~c)&(~d|~a|~b|c) cnf.add([res, a, b, ~c]) cnf.add([res, a, ~b, c]) cnf.add([res, ~a, b, c]) cnf.add([res, ~a, ~b, ~c]) cnf.add([~res, a, b, c]) cnf.add([~res, a, ~b, ~c]) cnf.add([~res, ~a, b, ~c]) cnf.add([~res, ~a, ~b, c]) return res, res_carry
def cnf_1bitmultiplier(cnf: Formula, a: Variable, b: Variable) -> Variable: #according to wolfie: CNF | (¬a ∨ ¬b ∨ d) ∧ (a ∨ ¬d) ∧ (b ∨ ¬d) d = cnf.new_var() cnf.add([~a, ~b, d]) cnf.add([a, ~d]) cnf.add([b, ~d]) return d
def commander_variable(cnf: Formula, group: List[Variable]) -> Variable: at_most_one(cnf, group) var = cnf.new_var() # var <=> (a or b or c ...) for i in range(len(group)): cnf.add([~group[i], var]) clause = group[:] clause.append(~var) cnf.add(clause) return var
def new_bitmap(cnf: Formula, width: int, height: int) -> List[List[Variable]]: return [[cnf.new_var() for i in range(width)] for j in range(height)]
def new_integer(cnf: Formula, bits: int) -> List[Variable]: return [cnf.new_var() for i in range(bits)]