def cnf_enforce_pyth_trip(cnf: Formula, a: List[Variable], b: List[Variable], c: List[Variable], primitive: bool) -> None: assert (len(a) == len(b)) assert (len(a) == len(c)) bitdepth = len(a) m = new_integer(cnf, bitdepth) n = new_integer(cnf, bitdepth) m2 = cnf_square(cnf, m) n2 = cnf_square(cnf, n) m2n2 = cnf_add(cnf, m2, n2) two = [cnf.const_false(), cnf.const_true()] mn = cnf_mult(cnf, m, n) mn2 = cnf_mult(cnf, mn, two) # a disgusting way to do subtraction. fix me please m2subn2 = new_integer(cnf, bitdepth) m2_tmp = cnf_add(cnf, m2subn2, n2) cnf_equal(cnf, m2_tmp, m2) if not primitive: k = new_integer(cnf, bitdepth) m2subn2 = cnf_mult(cnf, m2subn2, k) mn2 = cnf_mult(cnf, mn2, k) m2n2 = cnf_mult(cnf, m2n2, k) cnf_equal(cnf, a, m2subn2) cnf_equal(cnf, b, mn2) cnf_equal(cnf, c, m2n2)
def index(): form = Formula(request.form) if request.method == 'POST' and form.validate(): result = compute(form) else: result = None # Group form into pure numbers and numbers with a boolean form_pure_numbers = [] form_numbers_wbools = [] for field in form: # See if field with name 'include_' + field.name exists number_wbool = False for field2 in form: if field2.name == 'include_' + field.name: number_wbool = True break if number_wbool: form_numbers_wbools.append((field, field2)) elif not field.name.startswith('include_'): form_pure_numbers.append(field) return render_template("view.html", result=result, form_pure_numbers=form_pure_numbers, form_numbers_wbools=form_numbers_wbools)
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 cnf_constant(cnf: Formula, n: List[Variable], c: int) -> None: for i in range(len(n)): b = c & 1 c >>= 1 if b: cnf.add([n[i]]) else: cnf.add([~n[i]]) if c > 0: print("WARNING: overflow in cnf_constant!")
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 pad(cnf: Formula, a: List[Variable], b: List[Variable]) -> Tuple[List[Variable], List[Variable]]: aa = a[:] bb = b[:] if len(aa) < len(bb): for i in range(len(aa), len(bb)): aa.append(cnf.const_false()) elif len(bb) < len(aa): for i in range(len(bb), len(aa)): bb.append(cnf.const_false()) assert (len(aa) == len(bb)) return aa, bb
def one_of_k_commander(cnf: Formula, varlist: List[Variable], group_size: int) -> None: at_least_one(cnf, varlist) length = len(varlist) if length == 1: cnf.add([varlist[0]]) return assert (length % group_size == 0) treevars = [] #type: List[Variable] for i in range(int(length / group_size)): idx = group_size * i group = varlist[idx:idx + group_size] treevar = commander_variable(cnf, group) treevars.append(treevar) one_of_k_commander(cnf, treevars, group_size)
def cnf_add(cnf: Formula, a: List[Variable], b: List[Variable]) -> List[Variable]: #if the lengths are incorrect, just pad up with zero variables a, b = cnf_padout(a, b) carry = cnf.const_false() # The first carry is always 0 out = [] for (ai, bi) in zip(a, b): res, carry = cnf_1bitadder(cnf, ai, bi, carry) out.append(res) out.append(carry) return out
def cnf_odd2(cnf: Formula, a: List[Variable], b: List[Variable], c: List[Variable]) -> None: x = a[0] y = c[0] z = b[0] cnf.add([~x, ~y, ~z]) cnf.add([x, y]) cnf.add([x, z]) cnf.add([y, z])
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)]
def cnf_1bitequal(cnf: Formula, a: Variable, b: Variable) -> None: cnf.add([a, ~b]) cnf.add([~a, b])
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_div4(cnf: Formula, a: List[Variable], b: List[Variable], c: List[Variable]) -> None: x = a[0] y = a[1] z = b[0] w = b[1] p = c[0] q = c[1] cnf.add([~x, ~z]) cnf.add([~x, ~w]) cnf.add([~x, ~p]) cnf.add([~x, ~q]) cnf.add([~y, ~z]) cnf.add([~y, ~w]) cnf.add([~y, ~p]) cnf.add([~y, ~q]) cnf.add([~z, ~p]) cnf.add([~z, ~q]) cnf.add([~w, ~p]) cnf.add([~w, ~q])
def cnf_1div16(cnf: Formula, a: List[Variable]) -> None: cnf.add([~a[0]]) cnf.add([~a[1]]) cnf.add([~a[2]]) cnf.add([~a[3]])
m2_tmp = cnf_add(cnf, m2subn2, n2) cnf_equal(cnf, m2_tmp, m2) if not primitive: k = new_integer(cnf, bitdepth) m2subn2 = cnf_mult(cnf, m2subn2, k) mn2 = cnf_mult(cnf, mn2, k) m2n2 = cnf_mult(cnf, m2n2, k) cnf_equal(cnf, a, m2subn2) cnf_equal(cnf, b, mn2) cnf_equal(cnf, c, m2n2) if __name__ == "__main__": cnf = Formula() bitdepth = 14 a = new_integer(cnf, bitdepth) b = new_integer(cnf, bitdepth) c = new_integer(cnf, bitdepth) d = new_integer(cnf, bitdepth) e = new_integer(cnf, bitdepth) f = new_integer(cnf, bitdepth) g = new_integer(cnf, bitdepth) a2 = cnf_square(cnf, a) b2 = cnf_square(cnf, b) c2 = cnf_square(cnf, c)