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 extra_concepts(self): tn = self.text_name() X, Y = self.variable('X'), self.variable('Y') c = [ Literal(1, Atom(tn, [X])), ~eq_lit(X, Y), Literal(1, Atom(tn, [Y])) ] cs = [ProductSpace([NamedSpace(x) for x in c])] w = get_witness(self) if w: cls = [[~lit, eq_lit(X, w)] for lit in self.fmla] cs += [ProductSpace([NamedSpace(x) for x in c]) for c in cls] return cs
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 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 action_update(self, domain, pvars): lhs, rhs = self.args n = lhs.rep # Handle the hierarchical case if n in domain.hierarchy: asgns = [ postfix_atoms_ast(self, Atom(x, [])) for x in domain.hierarchy[n] ] res = unzip_append( [asgn.action_update(domain, pvars) for asgn in asgns]) return res # If the lhs application is partial, make it total by adding parameters xtra = len(lhs.rep.sort.dom) - len(lhs.args) if xtra < 0: raise IvyError(self, "too many parameters in assignment to " + lhs.rep) if xtra > 0: extend = sym_placeholders(lhs.rep)[-xtra:] extend = variables_distinct_list_ast(extend, self) # get unused variables lhs = add_parameters_ast(lhs, extend) # Assignment of individual to a boolean is a special case if is_individual_ast(rhs) and not is_individual_ast(lhs): rhs = eq_atom(extend[-1], add_parameters_ast(rhs, extend[0:-1])) else: rhs = add_parameters_ast(rhs, extend) type_check(domain, rhs) if is_individual_ast(lhs) != is_individual_ast(rhs): # print type(lhs.rep) # print str(lhs.rep) # print type(lhs.rep.sort) # print "lhs: %s: %s" % (lhs,type(lhs)) # print "rhs: %s: %s" % (rhs,type(rhs)) raise IvyError(self, "sort mismatch in assignment to {}".format(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) if eqs: drhs = Ite(And(*eqs), drhs, n(*dlhs.args)) new_clauses = Clauses([], [Definition(dlhs, drhs)]) # print "assign new_clauses = {}".format(new_clauses) return ([n], new_clauses, false_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 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 action_update(self,domain,pvars): lit = self.args[0] n = lit.atom.relname new_n = new(n) args = lit.atom.args vs = sym_placeholders(n) eqs = [Atom(equals,[v,a]) for (v,a) in zip(vs,args) if not isinstance(a,Variable)] new_clauses = And(*([Or(sign(lit.polarity,Atom(new_n,vs)),sign(1-lit.polarity,Atom(n,vs))), sign(lit.polarity,Atom(new_n,args))] + [Or(*([sign(0,Atom(new_n,vs)),sign(1,Atom(n,vs))] + [eq])) for eq in eqs] + [Or(*([sign(1,Atom(new_n,vs)),sign(0,Atom(n,vs))] + [eq])) for eq in eqs])) new_clauses = formula_to_clauses(new_clauses) return ([n], new_clauses, false_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 to_concept_space(self): return Atom(self.text_name(), [self.variable('X')]), ProductSpace( [NamedSpace(x) for x in self.fmla])
def action_update(self,domain,pvars): lhs,rhs = self.args n = lhs.rep # Handle the hierarchical case if n in domain.hierarchy: asgns = [postfix_atoms_ast(self,Atom(x,[])) for x in domain.hierarchy[n]] res = unzip_append([asgn.action_update(domain,pvars) for asgn in asgns]) return res # If the lhs application is partial, make it total by adding parameters xtra = len(lhs.rep.sort.dom) - len(lhs.args) if xtra < 0: raise IvyError(self,"too many parameters in assignment to " + lhs.rep) if xtra > 0: extend = sym_placeholders(lhs.rep)[-xtra:] extend = variables_distinct_list_ast(extend,self) # get unused variables lhs = add_parameters_ast(lhs,extend) # Assignment of individual to a boolean is a special case if is_individual_ast(rhs) and not is_individual_ast(lhs): rhs = eq_atom(extend[-1],add_parameters_ast(rhs,extend[0:-1])) else: rhs = add_parameters_ast(rhs,extend) lhs_vars = used_variables_ast(lhs) if any(v not in lhs_vars for v in used_variables_ast(rhs)): print self raise IvyError(self,"multiply assigned: {}".format(lhs.rep)) type_check(domain,rhs) if is_individual_ast(lhs) != is_individual_ast(rhs): # print type(lhs.rep) # print str(lhs.rep) # print type(lhs.rep.sort) # print "lhs: %s: %s" % (lhs,type(lhs)) # print "rhs: %s: %s" % (rhs,type(rhs)) raise IvyError(self,"sort mismatch in assignment to {}".format(lhs.rep)) # For a destructor assignment, we actually mutate the first argument if n.name in ivy_module.module.destructor_sorts: mut = lhs.args[0] rest = list(lhs.args[1:]) mut_n = mut.rep nondet = mut_n.suffix("_nd").skolem() new_clauses = mk_assign_clauses(mut_n,nondet(*sym_placeholders(mut_n))) fmlas = [] nondet_lhs = lhs.rep(*([nondet(*mut.args)]+rest)) fmlas.append(equiv_ast(nondet_lhs,rhs)) vs = sym_placeholders(n) dlhs = n(*([nondet(*mut.args)] + vs[1:])) drhs = n(*([mut] + vs[1:])) eqs = [eq_atom(v,a) for (v,a) in zip(vs,lhs.args)[1:] if not isinstance(a,Variable)] if eqs: fmlas.append(Or(And(*eqs),equiv_ast(dlhs,drhs))) for destr in ivy_module.module.sort_destructors[mut.sort.name]: if destr != n: phs = sym_placeholders(destr) a1 = [nondet(*mut.args)] + phs[1:] a2 = [mut] + phs[1:] fmlas.append(eq_atom(destr(*a1),destr(*a2))) new_clauses = and_clauses(new_clauses,Clauses(fmlas)) return ([mut_n], new_clauses, false_clauses()) new_clauses = mk_assign_clauses(lhs,rhs) # print "assign new_clauses = {}".format(new_clauses) return ([n], new_clauses, false_clauses())
def type_ast(domain,ast): if is_atom(ast) and ast.rep not in domain.relations and ast.rep != '=': return App(ast.rep,ast.args) if isinstance(ast,App) and ast.rep in domain.relations: return Atom(ast.rep,ast.args) return ast
def to_concept_space(self): rel_lit = self.rel_lit return Atom('__' + rel_lit.atom.rep, rel_lit.atom.args), SumSpace( [NamedSpace(rel_lit), NamedSpace(~rel_lit)])
def status_lit(self, status): return Literal(1, Atom(equals, [self.fmla, status]))
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))
def node_concept(sort, varname): return Literal(1, Atom('__node:' + sort, [Variable(varname, sort)]))
def xtra_concept(sort, vn1, vn2): return Literal( 1, Atom('__xtra:' + sort, [Variable(vn1, sort), Variable(vn2, sort)]))