minr = Function('minr', fgsort, intsort) maxr = Function('maxr', fgsort, intsort) bst = RecFunction('bst', fgsort, boolsort) hbst = RecFunction('hbst', fgsort, fgsetsort) AddRecDefinition(minr, x, If(x == nil, 100, min_intsort(key(x), minr(lft(x)), minr(rght(x))))) AddRecDefinition(maxr, x, If(x == nil, -1, max_intsort(key(x), maxr(lft(x)), maxr(rght(x))))) AddRecDefinition(bst, x, If(x == nil, True, And(0 < key(x), And(key(x) < 100, And(bst(lft(x)), And(bst(rght(x)), And(maxr(lft(x)) <= key(x), key(x) <= minr(rght(x))))))))) AddRecDefinition(hbst, x, If(x == nil, fgsetsort.lattice_bottom, SetAdd(SetUnion(hbst(lft(x)), hbst(rght(x))), x))) AddAxiom((), lft(nil) == nil) AddAxiom((), rght(nil) == nil) # Problem parameters goal = Implies(bst(x), Implies(And(x != nil, And(IsMember(y, hbst(x)), And(k == minr(x), And(k == minr(y), y != nil)))), k == minr(lft(y)))) # parameters representing the grammar for synth-fun and # terms on which finite model is extracted # TODO: extract this automatically from grammar_string v = Var('v', fgsort) lemma_grammar_args = [v, y, k, nil] lemma_grammar_terms = {v, lft(v), rght(v), nil, y}
nil = Const('nil', fgsort) cons = Function('cons', intsort, fgsort, fgsort) # projections for cons head = Function('head', fgsort, intsort) tail = Function('tail', fgsort, fgsort) # rec defs append = RecFunction('append', fgsort, fgsort, fgsort) length = RecFunction('length', fgsort, intsort) AddRecDefinition(append, (x, y), If(x == nil, y, cons(head(x), append(tail(x), y)))) AddRecDefinition(length, x, If(x == nil, 0, length(tail(x)) + 1)) # axioms AddAxiom(x, head(cons(hx, x)) == hx) AddAxiom(x, tail(cons(hx, x)) == x) AddAxiom(x, cons(hx, x) != nil) # len(append(x, y)) = len(x) + len(y) goal = length(append(x, y)) == length(x) + length(y) # adt pfp of goal base_case = length(append(nil, y)) == length(nil) + length(y) induction_hypothesis = length(append(tx, y)) == length(tx) + length(y) induction_step = length(append(cons(hx, tx), y)) == length(cons(hx, tx)) + length(y) pfp_goal = And(base_case, Implies(induction_hypothesis, induction_step)) np_solver = NPSolver()
from lemsynth.lemsynth_engine import solveProblem # Declarations x, y = Vars('x y', fgsort) nil, c = Consts('nil c', fgsort) nxt = Function('nxt', fgsort, fgsort) prv = Function('prv', fgsort, fgsort) lst = RecFunction('lst', fgsort, boolsort) dlst = RecFunction('dlst', fgsort, boolsort) lseg = RecFunction('lseg', fgsort, fgsort, boolsort) AddRecDefinition(lst, x, If(x == nil, True, lst(nxt(x)))) AddRecDefinition(dlst, x, If(x == nil, True, If(nxt(x) == nil, True, And(prv(nxt(x)) == x, dlst(nxt(x)))))) AddRecDefinition(lseg, (x, y) , If(x == y, True, lseg(nxt(x), y))) AddAxiom((), nxt(nil) == nil) # Problem parameters goal = Implies(lseg(x, y), Implies(x != c, Implies(dlst(y), lst(x)))) # parameters representing the grammar for synth-fun and # terms on which finite model is extracted # TODO: extract this automatically from grammar_string v1, v2 = Vars('v1 v2', fgsort) lemma_grammar_args = [v1, v2, nil] lemma_grammar_terms = {v1, nil, prv(nxt(v1)), v2, nxt(v2), prv(nxt(nxt(v1))), prv(nxt(v2)), prv(nxt(nil)), prv(nxt(prv(nxt(v1)))), nxt(prv(nxt(v1))), nxt(nil), nxt(v1), nxt(nxt(v1))} name = 'lseg-dlist' grammar_string = importlib_resources.read_text('experiments', 'grammar_{}.sy'.format(name)) solveProblem(lemma_grammar_args, lemma_grammar_terms, goal, name, grammar_string)
black = Function('black', fgsort, boolsort) red_height = RecFunction('red_height', fgsort, intsort) black_height = RecFunction('black_height', fgsort, intsort) AddRecDefinition(rlst, x, If(x == nil, True, And(Or(And(red(x), And(Not(black(x)), And(black(nxt(x)), Not(red(nxt(x)))))), And(black(x), And(Not(red(x)), And(red(nxt(x)), Not(black(nxt(x))))))), rlst(nxt(x))))) AddRecDefinition(red_height, x, If(x == nil, 1, If(red(x), 1 + red_height(nxt(x)), red_height(nxt(x))))) AddRecDefinition(black_height, x, If(x == nil, 0, If(black(x), 1 + black_height(nxt(x)), black_height(nxt(x))))) AddAxiom((), nxt(nil) == nil) AddAxiom((), red(nil)) AddAxiom((), Not(black(nil))) # vc goal = Implies(rlst(x), Implies(red(x), red_height(x) == 1 + black_height(x))) # check validity with natural proof solver and no hardcoded lemmas np_solver = NPSolver() solution = np_solver.solve(make_pfp_formula(goal)) if not solution.if_sat: print('goal (no lemmas) is valid') else: print('goal (no lemmas) is invalid') # hardcoded lemma
from lemsynth.lemsynth_engine import solveProblem # declarations x = Var('x', fgsort) nil, ret = Consts('nil ret', fgsort) nxt = Function('nxt', fgsort, fgsort) prv = Function('prv', fgsort, fgsort) lst = RecFunction('lst', fgsort, boolsort) dlst = RecFunction('dlst', fgsort, boolsort) AddRecDefinition(lst, x, If(x == nil, True, lst(nxt(x)))) AddRecDefinition( dlst, x, If(x == nil, True, If(nxt(x) == nil, True, And(prv(nxt(x)) == x, dlst(nxt(x)))))) AddAxiom((), nxt(nil) == nil) AddAxiom((), prv(nil) == nil) # vc pgm = If(x == nil, ret == nil, ret == nxt(x)) goal = Implies(dlst(x), Implies(pgm, lst(ret))) # check validity with natural proof solver and no hardcoded lemmas np_solver = NPSolver() solution = np_solver.solve(make_pfp_formula(goal)) if not solution.if_sat: print('goal (no lemmas) is valid') else: print('goal (no lemmas) is invalid') # hardcoded lemma
from naturalproofs.pfp import make_pfp_formula from lemsynth.lemsynth_engine import solveProblem # declarations x = Var('x', fgsort) c, s, nil = Consts('c s nil', fgsort) v1 = Function('v1', fgsort, fgsort) v2 = Function('v2', fgsort, fgsort) p = Function('p', fgsort, fgsort) n = Function('n', fgsort, fgsort) reach_pgm = RecFunction('reach_pgm', fgsort, boolsort) # precondition AddAxiom((), v1(s) == n(v2(s))) cond = v1(p(x)) != nil assign1 = v1(x) == n(v1(p(x))) assign2 = v2(x) == n(v2(p(x))) assign = And(assign1, assign2) AddRecDefinition(reach_pgm, x, If(x == s, True, And(reach_pgm(p(x)), And(cond, assign)))) # vc lhs = v1(x) == nil rhs = n(v2(x)) == nil goal = Implies(reach_pgm(x), Implies(lhs, rhs)) # check validity with natural proof solver and no hardcoded lemmas np_solver = NPSolver()
import unittest from z3 import And, Or, Not, Implies, If from z3 import IsSubset, Union, SetIntersect, SetComplement, EmptySet from naturalproofs.uct import fgsort, fgsetsort, intsort, intsetsort, boolsort from naturalproofs.decl_api import Const, Consts, Function, RecFunction, AddRecDefinition, AddAxiom from naturalproofs.pfp import make_pfp_formula from naturalproofs.prover import NPSolver import naturalproofs.proveroptions as proveroptions # Declarations a, zero = Consts('a zero', fgsort) suc = Function('suc', fgsort, fgsort) pred = Function('pred', fgsort, fgsort) AddAxiom(a, pred(suc(a)) == a) nat = RecFunction('nat', fgsort, boolsort) even = RecFunction('even', fgsort, boolsort) odd = RecFunction('odd', fgsort, boolsort) AddRecDefinition(nat, a, If(a == zero, True, nat(pred(a)))) AddRecDefinition(even, a, If(a == zero, True, odd(pred(a)))) AddRecDefinition(odd, a, If(a == zero, False, If(a == suc(zero), True, even(pred(a))))) # Problem parameters goal = Implies(nat(a), Or(even(a), odd(a))) pfp_of_goal = make_pfp_formula(goal) # Call a natural proofs solver npsolver = NPSolver() # Ask for proof npsolution = npsolver.solve(pfp_of_goal)
from naturalproofs.pfp import make_pfp_formula from lemsynth.lemsynth_engine import solveProblem # declarations x = Var('x', fgsort) c, s, nil = Consts('c s nil', fgsort) v1 = Function('v1', fgsort, fgsort) v2 = Function('v2', fgsort, fgsort) p = Function('p', fgsort, fgsort) n = Function('n', fgsort, fgsort) reach_pgm = RecFunction('reach_pgm', fgsort, boolsort) # precondition AddAxiom((), v1(s) == v2(s)) cond = v1(p(x)) != nil assign1 = v1(x) == n(v1(p(x))) assign2 = If(v2(p(x)) != c, v2(x) == n(v2(p(x))), v2(x) == v2(p(x))) assign = And(assign1, assign2) AddRecDefinition(reach_pgm, x, If(x == s, True, And(reach_pgm(p(x)), And(cond, assign)))) # vc lhs = v1(x) == nil rhs = Or(v2(x) == nil, v2(x) == c) goal = Implies(reach_pgm(x), Implies(lhs, rhs)) # check validity with natural proof solver and no hardcoded lemmas np_solver = NPSolver()
elems = RecFunction('elems', fgsort, fgsetsort) member = RecFunction('member', fgsort, boolsort) AddRecDefinition( slst, l, If(l == nil, True, If(tail(l) == nil, True, And(head(l) <= head(tail(l)), slst(tail(l)))))) AddRecDefinition( elems, l, If(l == nil, fgsetsort.lattice_bottom, SetAdd(elems(tail(l)), head(l)))) AddRecDefinition( member, l, If(l == nil, False, If(k == head(l), True, If(k < head(l), False, member(tail(l)))))) # axioms AddAxiom(l, head(cons(h, l)) == h) AddAxiom(l, tail(cons(h, l)) == l) AddAxiom(l, cons(h, l) != nil) goal = Implies(And(slst(l), IsMember(k, elems(l))), member(l)) # adt pfp of goal base_case = Implies(And(slst(nil), IsMember(k, elems(nil))), member(nil)) induction_hypothesis = Implies(And(slst(tl), IsMember(k, elems(tl))), member(tl)) induction_step = Implies( And(slst(cons(h, tl)), IsMember(k, elems(cons(h, tl)))), member(cons(h, tl))) pfp_goal = And(base_case, Implies(induction_hypothesis, induction_step))
rlst = RecFunction('rlst', fgsort, boolsort) red = Function('red', fgsort, boolsort) black = Function('black', fgsort, boolsort) AddRecDefinition(lst, x, If(x == nil, True, lst(nxt(x)))) AddRecDefinition( rlst, x, If( x == nil, True, And( Or( And(red(x), And(Not(black(x)), And(black(nxt(x)), Not(red(nxt(x)))))), And(black(x), And(Not(red(x)), And(red(nxt(x)), Not(black(nxt(x))))))), rlst(nxt(x))))) AddAxiom((), nxt(nil) == nil) AddAxiom((), red(nil)) # vc pgm = If(x == nil, ret == nil, ret == nxt(x)) goal = Implies(rlst(x), Implies(pgm, lst(ret))) # check validity with natural proof solver and no hardcoded lemmas np_solver = NPSolver() solution = np_solver.solve(make_pfp_formula(goal)) if not solution.if_sat: print('goal (no lemmas) is valid') else: print('goal (no lemmas) is invalid') # hardcoded lemma
x, y, nx, ny = Vars('x y nx ny', fgsort) # ADT definition of nats zero = Const('zero', fgsort) succ = Function('succ', fgsort, fgsort) # projection function - analogous to tail of list pred = Function('pred', fgsort, fgsort) # rec defs plus = RecFunction('plus', fgsort, fgsort, fgsort) AddRecDefinition(plus, (x, y), If(x == zero, y, succ(plus(pred(x), y)))) # axioms AddAxiom(x, pred(succ(x)) == x) AddAxiom(x, succ(x) != zero) goal = plus(x, y) == plus(y, x) # adt pfp of goal base_case = plus(zero, y) == plus(y, zero) induction_hypothesis = plus(nx, y) == plus(y, nx) induction_step = plus(succ(nx), y) == plus(y, succ(nx)) pfp_goal = Implies(induction_hypothesis, induction_step) orig_np_solver = NPSolver() orig_solution = orig_np_solver.solve(pfp_goal) print('Commutativity of addition: no lemma') if not orig_solution.if_sat: print(' -- goal is valid')