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 match(self,action): """ if action matches pattern, return the axioms, else None """ ## print "match: %s %s" % (self,action) subst = dict() if self.pattern.match(action,self.placeholders.args,subst): # print "match: {}".format(subst) axioms_as_clause_sets = (formula_to_clauses(x) for x in (Not(self.precond),self.transrel)) return (subst_both_clauses(x,subst) for x in axioms_as_clause_sets) return None
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 int_update(self, domain, pvars): if determinize and len(self.args) == 2: cond = bool_const('___branch:' + str(self.unique_id)) ite = IfAction(Not(cond), self.args[0], self.args[1]) return ite.int_update(domain, pvars) result = [], false_clauses(), false_clauses() for a in self.args: foo = a.int_update(domain, pvars) result = join_action(result, foo, domain.relations) return result
def condition_update_on_fmla(update, fmla, relations): """Given an update, return an update conditioned on fmla. Maybe an "else" would be useful too :-). """ updated, if_clauses, if_pre = update else_clauses = update_frame_constraint(update, relations) if_clauses = condition_clauses(if_clauses, fmla) else_clauses = condition_clauses(else_clauses, Not(fmla)) ## print "if_clauses: %s" % if_clauses ## print "else_clauses: %s" % else_clauses return updated, (and_clauses(if_clauses, else_clauses)), if_pre
def expand(self,domain,pvars): modset,pre,post = self.args[1].int_update(domain,pvars) # TODO:cheaper way to get modset asserts = self.args[2:] assumes = [a.assert_to_assume() for a in asserts] havocs = [HavocAction(sym) for sym in modset] res = Sequence(*( asserts + havocs + assumes + [ChoiceAction(Sequence(),Sequence(*([AssumeAction(self.args[0]), self.args[1]]+asserts+[AssumeAction(And())]))), AssumeAction(Not(self.args[0]))])) return res
def condition_update_on_fmla(update, fmla): """Given an update, return an update conditioned on fmla. Maybe an "else" would be useful too :-). """ assert isinstance(update, SemValue) updated, if_clauses, if_pre = update.comps else_clauses = update_frame_constraint(update) if_clauses = condition_clauses(if_clauses, fmla) else_clauses = condition_clauses(else_clauses, Not(fmla)) ## print "if_clauses: %s" % if_clauses ## print "else_clauses: %s" % else_clauses return type(update)(updated, (and_clauses(if_clauses, else_clauses)), if_pre)
def action_update(self, domain, pvars): lhs = type_ast(domain, 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 unroll(self, card, body=None): cond = self.args[0] while isinstance(cond, And) and len(cond.args) > 0: cond = cond.args[0] if is_app(cond) and cond.rep.name in ['<', '>', '<=', '>=']: idx_sort = cond.args[0].sort elif isinstance(cond, Not) and is_eq(cond.args[0]): idx_sort = cond.args[0].args[0].sort else: raise IvyError(self, 'cannot determine an index sort for loop') cardsort = card(idx_sort) if cardsort is None: raise IvyError( self, 'cannot determine an iteration bound for loop over {}'.format( idx_sort)) res = AssumeAction(Not(self.args[0])) for idx in range(cardsort): res = IfAction(self.args[0], Sequence(body or self.args[1], res)) if hasattr(self, 'formal_params'): res.formal_params = self.formal_params if hasattr(self, 'formal_returns'): res.formal_returns = self.formal_returns return res
def sign(polarity,atom): return atom if polarity else Not(atom)
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)))]))
def check_can_assert(fmla, ast): check_can_assume(fmla, ast) logic = ivy_module.logic() if not is_in_logic(Not(fmla), logic): raise IvyError( ast, "This formula is not in logic {} when negated.".format(logic))