def check_node(self, n): x = var_to_skolem('__', Variable('X', n.sort)).suffix(str(n.sort)) y = var_to_skolem('__', Variable('Y', n.sort)).suffix(str(n.sort)) # print "x.sort: {}",format(x.sort) self.solver.push() s = self.solver # if we have a witness we can show node is definite (present in all models) wit = get_witness(n) # print "checking: {}".format(n.fmla) cube = substitute_clause(n.fmla, {'X': x}) # print "cube: {!r}".format(cube) # print wit # if wit != None: ## print "wit: {}, wit.sort: {}, x.sort: {}".format(wit,wit.sort,x.sort) res = s_check_cube(s, cube, (Atom(equals, [x, wit]) if wit != None else None)) ## print"check cube: %s = %s" % (cube,res) # res = s_check_cube(s,substitute_clause(n.fmla,{'X':x})) # print "status: {}".format(res) n.status = res s_add(s, cube_to_z3(substitute_clause(n.fmla, {'X': x}))) s_add(s, cube_to_z3(substitute_clause(n.fmla, {'X': y}))) s_add(s, cube_to_z3([Literal(0, Atom(equals, [x, y]))])) n.summary = s.check() != z3.unsat self.solver.pop()
def mk_variant_assign_clauses(lhs, rhs): n = lhs.rep new_n = new(n) args = lhs.args dlhs = new_n(*sym_placeholders(n)) vs = dlhs.args eqs = [ eq_atom(v, a) for (v, a) in zip(vs, args) if not isinstance(a, Variable) ] rn = dict((a.rep, v) for v, a in zip(vs, args) if isinstance(a, Variable)) drhs = substitute_ast(rhs, rn) nondet = n.suffix("_nd").skolem() if eqs: nondet = Ite(And(*eqs), nondet, n(*dlhs.args)) lsort, rsort = lhs.sort, rhs.sort fmlas = [ Iff( pto(lsort, rsort)(dlhs, Variable('X', rsort)), Equals(Variable('X', rsort), drhs)) ] for s in ivy_module.module.variants[lsort.name]: if s != rsort: fmlas.append(Not(pto(lsort, s)(dlhs, Variable('X', s)))) new_clauses = Clauses(fmlas, [Definition(dlhs, nondet)]) return new_clauses
def rela_fact(polarity, relname, n1, n2): return ([~lit for lit in fmla1] + [ ~lit for lit in substitute_clause(n2.fmla, {'X': Variable('Y', n2.sort)}) ] + [ Literal( polarity, Atom(relname, [Variable('X', n1.sort), Variable('Y', n2.sort)])) ])
def empty_edge(self, rel_lit, head, tail): g = self fmla = [~lit for lit in head.fmla] + [ ~substitute_lit(lit, {'X': Variable('Y')}) for lit in tail.fmla ] + [~rel_lit] # print "adding clause: %s" % fmla self.add_constraints([fmla])
def interp_from_unsat_core(clauses1, clauses2, core, interpreted): used_syms = used_symbols_clauses(core) vars = used_variables_clauses(core) if vars: # print "interpolant would require skolem constants" return None core_consts = used_constants_clauses(core) clauses2_consts = used_constants_clauses(clauses2) # print "interp_from_unsat_core core_consts = {}".format(map(str,core_consts)) # print "interp_from_unsat_core clauses2_consts = {}".format(map(str,clauses2_consts)) renaming = dict() i = 0 for v in core_consts: if v not in clauses2_consts or v.is_skolem( ): # and v not in interpreted: renaming[v] = Variable('V' + str(i), Constant(v).get_sort()) i += 1 # print "interp_from_unsat_core core = {}".format(core) # print "interp_from_unsat_core renaming = {}".format(renaming) renamed_core = substitute_constants_clauses(core, renaming) # print "interp_from_unsat_core renamed_core = {}".format(renamed_core) res = simplify_clauses( Clauses([Or(*[negate(c) for c in renamed_core.fmlas])])) # print "interp_from_unsat_core res = {}".format(res) return res
def subactions(self) : if isinstance(self.args[0],ivy_ast.Some): ps = list(self.args[0].params()) fmla = self.args[0].fmla() vs = [Variable('V{}'.format(idx),x.sort) for idx,x in enumerate(ps)] subst = dict((c,v) for c,v in zip(ps,vs)) sfmla = substitute_constants_ast(fmla,subst) if isinstance(self.args[0],ivy_ast.SomeMinMax): idx = self.args[0].index() if idx not in ps: ltsym = Symbol('<',RelationSort([idx.sort,idx.sort])) operator = lambda x,y: Not(ltsym(x,y)) ivar = substitute_constants_ast(idx,subst) comp = operator(ivar,idx) if isinstance(self.args[0],ivy_ast.SomeMin) else operator(idx,ivar) fmla = And(fmla,Implies(sfmla,comp)) else : leqsym = Symbol('<=',RelationSort([idx.sort,idx.sort])) operator = lambda x,y: And(leqsym(x,y),Not(Equals(x,y))) ivar = next(v for p,v in zip(ps,vs) if p == idx) comp = operator(ivar,idx) if isinstance(self.args[0],ivy_ast.SomeMin) else operator(idx,ivar) fmla = And(fmla,Not(And(sfmla,comp))) if_part = LocalAction(*(ps+[Sequence(AssumeAction(fmla),self.args[1])])) else_action = self.args[2] if len(self.args) >= 3 else Sequence() else_part = Sequence(AssumeAction(Not(sfmla)),else_action) # iu.dbg('if_part') # iu.dbg('else_part') else: if not is_boolean(self.args[0]): raise IvyError(self,'condition must be boolean') if_part = Sequence(AssumeAction(self.args[0]),self.args[1]) else_action = self.args[2] if len(self.args) >= 3 else Sequence() else_part = Sequence(AssumeAction(dual_formula(self.args[0])),else_action) return if_part,else_part
def compile_concepts(self, concepts): clauses = self.post.post_step(concepts) # print "compile_concepts clauses={}".format(clauses) vs = used_variables_in_order_clauses(clauses) sksubs = dict( (v.rep, var_to_skolem('__', Variable(v.rep, v.sort))) for v in vs) clauses = substitute_clauses(clauses, sksubs) # print "clauses: {}".format(clauses) return clauses
def concept_label(self, concept): fmla = concept.formula if len(concept.variables) == 1: v = concept.variables[0] if can_abbreviate_formula(v, fmla): res = il.fmla_to_str_ambiguous( ilu.substitute_ast(fmla, {v.rep: Variable('', v.sort)})) return res.replace(' ', '').replace('()', '') return str(fmla)
def check_edge(self, f1, f2, solver): x = var_to_skolem('__', Variable('X', self.sorts[0])).suffix(str(self.sorts[0])) y = var_to_skolem('__', Variable('Y', self.sorts[1])).suffix(str(self.sorts[1])) solver.push() s_add(solver, cube_to_z3(substitute_clause(f1, {'X': x}))) s_add(solver, cube_to_z3(substitute_clause(f2, {'X': y}))) # print "xsort: {}, ysort: {}".format(x.get_sort(),y.get_sort()) # print "rel_lit: {}, subs: {}".format(self.rel_lit,substitute_lit(self.rel_lit,{'X':x,'Y':y})) res = s_check_cube(solver, [substitute_lit(self.rel_lit, { 'X': x, 'Y': y })]) solver.pop() return res
def initial_concept_domain(sorts): concepts = empty_concepts() # add one node for each sort for sort in sorts: X = Variable('X', sort) add_domain_concept_fmla(concepts, Equals(X, X), kind='nodes') return make_concept_domain(concepts)
def create_unit_sort(concepts): sort = il.UninterpretedSort('unit') if 'unit' not in il.sig.sorts: il.sig.sorts['unit'] = sort if 'has_unit' not in concepts: # HACK: will this damage anything? X = Variable('X', sort) add_domain_concept_fmla(concepts, Equals(X, X), kind='nodes') concepts['has_unit'] = [] return il.sig.sorts['unit']
def get_cond(self): if isinstance(self.args[0],ivy_ast.Some): ps = list(self.args[0].params()) fmla = self.args[0].fmla() vs = [Variable('V{}'.format(idx),x.sort) for idx,x in enumerate(ps)] subst = dict((c,v) for c,v in zip(ps,vs)) sfmla = substitute_constants_ast(fmla,subst) return Exists(vs,sfmla) else: return self.args[0]
def splatter(self, node, constants=None): if constants == None: constants = ilu.used_constants_clauses(self.constraints) concepts = self.concept_session.domain.concepts name = node.name + '.splatter' concepts[name] = enum_concepts(name, None, None) for cons in constants: c1 = concept_from_formula(Equals(Variable('X', node.sort), cons)) concepts[c1.name] = c1 concepts[name].append(c1.name) self.concept_session.domain.split(node.name, name) self.recompute()
def get_projections_of_ternaries(wit): # print "witness: {}".format(wit) for sym in ivy_logic.all_symbols(): # print "rel: {}. sort = {}".format(sym,sym.sort) if sym.is_relation() and len(sym.sort.dom) == 3: # print "ternary: {}, sort = {}".format(sym,sym.sort) for i in range(3): if sym.sort.dom[i] == wit.sort: yield sym(*[ t if t is wit else Variable(t, s) for t, s in zip(lins(['X', 'Y'], i, wit), sym.sort.dom) ])
def make_lit_label(lit): # pred = lit.atom.relname # if pred != "=": # label = pred # else: # terms = lit.atom.args # arg = 1 if isinstance(terms[0],Variable) else 0 # label = "=" + lit.atom.args[arg].rep for v in used_variables_ast(lit): return repr(substitute_lit(lit, {v.rep: Variable('', v.sort)})).replace( ' ', '').replace('()', '') label = str(lit.atom) return label if lit.polarity == 1 else "~" + label
def update_frame_constraint(update, relations): """ Return a clause list constraining all updated symbols to keep their previous values """ clauses = [] for sym in update[0]: if sym in relations: arity = relations[sym] vs = [Variable("V{}".format(i)) for i in range(0, arity)] lit1 = Literal(1, Atom(sym, vs)) lit2 = Literal(1, Atom(new(sym), vs)) clauses += [[~lit1, lit2], [lit1, ~lit2]] else: clauses.append([eq_lit(Constant(sym), Constant(new(sym)))]) return Clauses(clauses)
def set_state(self, clauses, recomp=True): self.state = clauses self.solver_clauses = true_clauses() self.predicates = self.get_predicates(clauses) sig = self.parent_state.domain.sig ufs = [ x for x, arity in self.parent_state.domain.functions.iteritems() if arity == 1 and not has_enumerated_sort(sig, x) ] if not hasattr(self, 'brels'): self.brels = ([ self.make_rel_lit(r, ['X', 'Y']) for r, arity in self.parent_state.domain.all_relations if arity == 2 ] + [ Literal( 1, Atom(equals, [ App(f, Variable('X', f.sort.dom[0])), Variable('Y', f.sort.rng) ])) for f in ufs ]) # brels = list(used_binary_relations_clauses(clauses)) # brels = [r for r in brels if ((r != equals) and not r.startswith('__'))] ## print "brels: %s" % brels self.relations = [GraphRelation(self, rel) for rel in self.brels] self.relations += [ GraphRelationUnary(self, rel) for rel in self.predicates if not isinstance(rel, tuple) and used_variables_ast(rel) ] self.relations += [ GraphFunctionUnary(self, Literal(1, rel[0])) for rel in self.predicates if isinstance(rel, tuple) ] self.needs_recompute = True if recomp: self.recompute()
def get_predicates(self, clauses): # print "get_predicates: {}".format(clauses) d = self.parent_state.domain sig = d.sig urs = [ x for x in used_unary_relations_clauses(clauses) if not is_skolem(x) ] cs = [ x for x in used_constants_clauses(clauses) if not is_skolem(x) and not has_enumerated_sort(sig, x) and not x.is_numeral() ] ufs = [ x for x in used_unary_functions_clauses(clauses) if not is_skolem(x) and has_enumerated_sort(sig, x) ] nrs = [x for x, arity in d.relations.iteritems() if arity == 0] union_to_list( urs, [x for x, arity in d.relations.iteritems() if arity == 1]) union_to_list(cs, [ x for x, arity in d.functions.iteritems() if arity == 0 and not has_enumerated_sort(sig, x) ]) union_to_list(ufs, [ x for x, arity in d.functions.iteritems() if arity == 1 and has_enumerated_sort(sig, x) ]) # print "ufs: {}".format(ufs) ccs = [Constant(c) for c in cs] # print "sorts: {}".format([(c,c.get_sort()) for c in ccs]) return ([Literal(1, Atom(c, [])) for c in nrs] + [ Literal(1, Atom(equals, [Variable("X", c.get_sort()), c])) for c in ccs ] + [Literal(1, Atom(r, [Variable("X", r.sort.dom[0])])) for r in urs] + [(App(f, Variable('X', f.sort.dom[0])), [ Constant(Symbol(x, f.sort.rng)) for x in f.sort.rng.defines() ]) for f in ufs])
def concepts_from_sig(symbols, concepts): for c in sorted(symbols, key=str): dom, rng = c.sort.dom, c.sort.rng if il.is_enumerated_sort(rng): # TODO: we have no way to display enumerated constants if len(dom) in [1, 2]: vs = [Variable(n, s) for n, s in zip(['X', 'Y'], dom)] ec = concept_from_formula(c(*vs)) concepts['enum'].append(ec.name) concepts[ec.name] = enum_concepts(ec.name, vs, c(*vs)) for cons in rng.constructors: c1 = add_domain_concept_fmla(concepts, Equals(c(*vs), cons), kind='enum_case') concepts[ec.name].append(c1.name) elif il.is_boolean_sort(rng): # TODO: we have no way to display boolean constants if len(dom) in [1, 2, 3]: vs = [Variable(n, s) for n, s in zip(['X', 'Y', 'Z'], dom)] add_domain_concept_fmla(concepts, c(*vs)) elif il.is_first_order_sort(rng): if len(dom) == 0: add_domain_concept_fmla(concepts, Equals(Variable('X', rng), c)) elif len(dom) in [1, 2]: vs = [ Variable(n, s) for n, s in zip(['X', 'Y', 'Z'], dom + (rng, )) ] fmla = Equals(c(*vs[0:-1]), vs[-1]) add_domain_concept_fmla(concepts, fmla)
def action_update(self,domain,pvars): lhs = self.args[0] n = lhs.rep new_n = new(n) args = lhs.args vs = [Variable("X%d" % i,s) for i,s in enumerate(n.sort.dom)] eqs = [eq_atom(v,a) for (v,a) in zip(vs,args) if not isinstance(a,Variable)] if is_atom(lhs): clauses = And(*([Or(Not(Atom(new_n,vs)),Atom(n,vs),eq) for eq in eqs] + [Or(Atom(new_n,vs),Not(Atom(n,vs)),eq) for eq in eqs])) elif is_individual_ast(lhs.rep): clauses = And(*[Or(eq_atom(type(lhs)(new_n,vs),type(lhs)(n,vs)),eq) for eq in eqs]) else: # TODO: ??? clauses = And() clauses = formula_to_clauses(clauses) return ([n], clauses, false_clauses())
def witness(self, node): g = self for lit in node.fmla: # print lit if is_equality_lit(lit) and isinstance(lit.atom.args[0], Variable): self.add_witness_constraint(node, lit.atom.args[1]) return lit.atom.args[1] uc = used_symbols_clauses(g.state) fmlas = [n.fmla for n in g.all_nodes] for f in fmlas: uc.update(used_symbols_clause(f)) nc = unused_constant(uc, node.sort) # print "type(nc) = {}".format(type(nc)) self.add_witness_constraint(node, nc) self.split(node, eq_lit(Variable('X', node.sort), nc)) return nc
def check_edge(self, f1, solver): x = var_to_skolem('__', Variable('X', self.sorts[0])).suffix(str(self.sorts[0])) solver.push() s_add(solver, cube_to_z3(substitute_clause(f1, {'X': x}))) # print "xsort: {}, ysort: {}".format(x.get_sort(),y.get_sort()) # print "rel_lit: {}, subs: {}".format(self.rel_lit,substitute_lit(self.rel_lit,{'X':x,'Y':y})) f = self.fmla vals = [Constant(Symbol(y, f.sort.rng)) for y in f.sort.rng.defines()] status = 'undef' for v in vals: if s_check_fmla(solver, self.test_lit(x, v).atom) == z3.unsat: status = v break solver.pop() return status
def concepts_from_sig(symbols, concepts): for c in sorted(symbols, key=str): dom, rng = c.sort.dom, c.sort.rng if il.is_enumerated_sort(rng): if len(dom) in [0, 1, 2]: if len(dom) == 0: if c in il.sig.constructors: continue # Hack: we treat enumerated constants as labels on the bogus sort "unit" vs, xvs = [], [Variable('X', create_unit_sort(concepts))] else: vs, xvs = [ Variable(n, s) for n, s in zip(['X', 'Y'], dom) ], None ec = concept_from_formula(c(*vs), vs=xvs) concepts['enum'].append(ec.name) concepts[ec.name] = enum_concepts(ec.name, vs, c(*vs)) for cons in rng.constructors: c1 = add_domain_concept_fmla(concepts, Equals(c(*vs), cons), kind='enum_case', vs=xvs) concepts[ec.name].append(c1.name) elif il.is_boolean_sort(rng): # TODO: we have no way to display boolean constants if len(dom) in [0, 1, 2, 3]: if len(dom) == 0: if c in il.sig.constructors: continue # Hack: we treat boolean constants as labels on the bogus sort "unit" vs, xvs = [], [Variable('X', create_unit_sort(concepts))] else: vs, xvs = [ Variable(n, s) for n, s in zip(['X', 'Y', 'Z'], dom) ], None add_domain_concept_fmla(concepts, c(*vs), vs=xvs) elif il.is_first_order_sort(rng): if len(dom) == 0: add_domain_concept_fmla(concepts, Equals(Variable('X', rng), c)) elif len(dom) in [1, 2]: vs = [ Variable(n, s) for n, s in zip(['X', 'Y', 'Z'], dom + (rng, )) ] fmla = Equals(c(*vs[0:-1]), vs[-1]) add_domain_concept_fmla(concepts, fmla)
def xtra_concept(sort, vn1, vn2): return Literal( 1, Atom('__xtra:' + sort, [Variable(vn1, sort), Variable(vn2, sort)]))
def witness_concept(c): return concept_from_formula(Equals(Variable('X', c.sort), c))
def make_field_update(self,l,f,r,domain,pvars): if not f.is_relation() or len(f.sort.dom) != 2: raise IvyError(self, "field " + str(f) + " must be a binary relation") v = Variable('X',f.sort.dom[1]) aa = AssignAction(f(l,v),r(v)) return aa.action_update(domain,pvars)
def node_concept(sort, varname): return Literal(1, Atom('__node:' + sort, [Variable(varname, sort)]))
def variable(self, name): return Variable(name, self.sort)
def make_rel_lit(self, rel, varnames): args = [Variable(v, t) for v, t in zip(varnames, rel.sort.dom)] return Literal(1, Atom(rel, args))