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 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 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 destr_asgn_val(lhs, fmlas): mut = lhs.args[0] rest = list(lhs.args[1:]) mut_n = mut.rep if mut_n.name in ivy_module.module.destructor_sorts: lval, new_clauses, mutated = destr_asgn_val(mut, fmlas) else: nondet = mut_n.suffix("_nd").skolem() new_clauses = (mk_assign_clauses(mut_n, nondet(*sym_placeholders(mut_n)))) lval = nondet(*mut.args) mutated = mut_n n = lhs.rep vs = sym_placeholders(n) dlhs = n(*([lval] + 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 = [lval] + phs[1:] a2 = [mut] + phs[1:] fmlas.append(eq_atom(destr(*a1), destr(*a2))) return lhs.rep(*([lval] + rest)), new_clauses, mutated
def action_update(self,domain,pvars): l,f = self.args return make_field_update(self,l,f,lambda v: Or(),domain,pvars)
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 equiv_ast(ast1,ast2): if is_individual_ast(ast1): # ast2 had better be the same! return eq_atom(ast1,ast2) return And(Or(ast1,Not(ast2)),Or(Not(ast1),ast2))
def assert_action(fmla): fail_flag = Symbol("sys:fail", RelationSort([])) return SemActionValue( [fail_flag], true_clauses(), Clauses(defs=[Definition(new(fail_flag), Or(fail_flag, Not(fmla)))]))