示例#1
0
    def process_conj(self):
        fmlas = []
        helpers = []
        for lf in self.mod.labeled_conjs:
            label = str(lf.label)
            if label.startswith("help_"):
                helpers.append(lf)
            else:
                fmlas.append(lf.formula)
        cl = lut.Clauses(fmlas)
        f = self.get_formula(cl)
        pref = lgu.substitute(f, self.nex2pre)
        self.add_new_constants(pref)
        res = (pref, "prop", "invar-property", "0")
        self.vmt["$prop"] = res

        for lf in helpers:
            label = str(lf.label)
            self.helpers[label] = lf.formula
            cl = lut.Clauses([lf.formula])
            f = self.get_formula(cl)
            pref = lgu.substitute(f, self.nex2pre)
            self.add_new_constants(pref)
            res = (pref, label, "help", label)
            self.vmt[label] = res
示例#2
0
 def process_axiom(self):
     fmlas = [lf.formula for lf in self.mod.labeled_axioms]
     cl = lut.Clauses(fmlas)
     f = self.get_formula(cl)
     self.add_new_constants(f)
     res = (f, "axiom", "axiom", "true")
     self.vmt["$axiom"] = res
示例#3
0
 def update_theory(self):
     theory = list(self.get_axioms())
     # axioms of the derived relations TODO: used only the
     # referenced ones, but we need to know abstract domain for
     # this
     for ldf in self.definitions:
         cnst = ldf.formula.to_constraint()
         if all(
                 isinstance(p, il.Variable)
                 for p in ldf.formula.args[0].args):
             if not isinstance(ldf.formula, il.DefinitionSchema):
                 #                    theory.append(ldf.formula) # TODO: make this a def?
                 ax = ldf.formula
                 ax = ax.to_constraint() if isinstance(ax.rhs(),
                                                       il.Some) else ax
                 if ldf.formula.args[0].args:
                     ax = il.ForAll(ldf.formula.args[0].args, ax)
                 theory.append(ax)  # TODO: make this a def?
     # extensionality axioms for structs
     for sort in sorted(self.sort_destructors):
         destrs = self.sort_destructors[sort]
         if any(d.name in self.sig.symbols for d in destrs):
             ea = il.extensionality(destrs)
             if il.is_epr(ea):
                 theory.append(ea)
     # exclusivity axioms for variants
     for sort in sorted(self.variants):
         sort_variants = self.variants[sort]
         if any(v.name in self.sig.sorts for v in sort_variants):
             ea = il.exclusivity(self.sig.sorts[sort], sort_variants)
             theory.append(ea)  # these are always in EPR
     self.theory = lu.Clauses(theory)
示例#4
0
文件: ivy_to_cpp.py 项目: xornand/ivy
def emit_action_gen(header, impl, name, action, classname):
    global indent_level
    caname = varname(name)
    upd = action.update(im.module, None)
    pre = tr.reverse_image(ilu.true_clauses(), ilu.true_clauses(), upd)
    pre_clauses = ilu.trim_clauses(pre)
    pre_clauses = ilu.and_clauses(
        pre_clauses,
        ilu.Clauses([df.to_constraint() for df in im.module.concepts]))
    pre = pre_clauses.to_formula()
    syms = [
        x for x in ilu.used_symbols_ast(pre) if x.name not in il.sig.symbols
    ]
    header.append("class " + caname + "_gen : public gen {\n  public:\n")
    for sym in syms:
        if not sym.name.startswith('__ts') and sym not in pre_clauses.defidx:
            declare_symbol(header, sym)
    header.append("    {}_gen();\n".format(caname))
    impl.append(caname + "_gen::" + caname + "_gen(){\n")
    indent_level += 1
    emit_sig(impl)
    for sym in syms:
        emit_decl(impl, sym)

    indent(impl)
    impl.append('add("(assert {})");\n'.format(
        slv.formula_to_z3(pre).sexpr().replace('\n', '\\\n')))
    indent_level -= 1
    impl.append("}\n")
    header.append("    bool generate(" + classname + "&);\n};\n")
    impl.append("bool " + caname + "_gen::generate(" + classname +
                "& obj) {\n    push();\n")
    indent_level += 1
    pre_used = ilu.used_symbols_ast(pre)
    for sym in all_state_symbols():
        if sym in pre_used and sym not in pre_clauses.defidx:  # skip symbols not used in constraint
            if slv.solver_name(sym) != None:  # skip interpreted symbols
                global is_derived
                if sym not in is_derived:
                    emit_set(impl, sym)
    for sym in syms:
        if not sym.name.startswith('__ts') and sym not in pre_clauses.defidx:
            emit_randomize(impl, sym)
    impl.append("""
    bool res = solve();
    if (res) {
""")
    indent_level += 1
    for sym in syms:
        if not sym.name.startswith('__ts') and sym not in pre_clauses.defidx:
            emit_eval(impl, sym)
    indent_level -= 2
    impl.append("""
    }
    pop();
    obj.___ivy_gen = this;
    return res;
}
""")
示例#5
0
 def process_axiom(self):
     fmlas = [lf.formula for lf in self.mod.labeled_axioms]
     cl = lut.Clauses(fmlas)
     self.axioms.append(self.get_formula(cl))
     f = lut.and_clauses(*self.axioms)
     self.add_new_constants(f, 'axiom')
     res = (f, "axiom", "axiom", "true")
     self.vmt["$axiom"] = res
示例#6
0
 def background_theory(self, symbols=None):
     """ Return a set of clauses which represent the background theory
     restricted to the given symbols (should be like the result of used_symbols).
     """
     theory = list(self.get_axioms())
     # axioms of the derived relations TODO: used only the
     # referenced ones, but we need to know abstract domain for
     # this
     for df in self.concepts:
         theory.append(df.to_constraint())  # TODO: make this a def?
     return lu.Clauses(theory)
示例#7
0
 def __call__(self,trans,invariant,indhyps):
     # apply to the transition relation
     new_defs = [self.qe(defn,self.sort_constants) for defn in trans.defs]
     new_fmlas = [self.qe(il.close_formula(fmla),self.sort_constants) for fmla in trans.fmlas]
     # apply to the invariant
     invariant = self.qe(invariant,self.sort_constants)
     # apply to inductive hyps
     indhyps = [self.qe(fmla,self.sort_constants2) for fmla in indhyps]
     # add the transition constraints to the new trans
     trans = ilu.Clauses(new_fmlas+indhyps+self.fmlas,new_defs)
     return trans,invariant
示例#8
0
文件: ivy_trace.py 项目: odedp/ivy
def make_vc(action, precond=[], postcond=[], check_asserts=True):

    ag = art.AnalysisGraph()

    pre = itp.State()
    pre.clauses = lut.Clauses([lf.formula for lf in precond])
    pre.clauses.annot = act.EmptyAnnotation()

    with itp.EvalContext(check=False):  # don't check safety
        post = ag.execute(action, pre)
        post.clauses = lut.true_clauses()

    fail = itp.State(expr=itp.fail_expr(post.expr))

    history = ag.get_history(post)
    axioms = im.module.background_theory()
    clauses = history.post

    #Tricky: fix the annotation so it matches the original action
    stack = []
    while isinstance(clauses.annot, act.RenameAnnotation):
        stack.append(clauses.annot.map)
        clauses.annot = clauses.annot.arg
    clauses.annot = clauses.annot.args[1]
    while stack:
        clauses.annot = act.RenameAnnotation(clauses.annot, stack.pop())

    clauses = lut.and_clauses(clauses, axioms)
    fc = lut.Clauses([lf.formula for lf in postcond])
    fc.annot = act.EmptyAnnotation()
    used_names = frozenset(x.name for x in lg.sig.symbols.values())

    def witness(v):
        c = lg.Symbol('@' + v.name, v.sort)
        assert c.name not in used_names
        return c

    fcc = lut.dual_clauses(fc, witness)
    clauses = lut.and_clauses(clauses, fcc)

    return clauses
示例#9
0
def instantiate_non_epr(non_epr,ground_terms):
    theory = []
    if ground_terms != None:
        matched = set()
        for term in ground_terms:
            if term.rep in non_epr and term not in matched:
                ldf,cnst = non_epr[term.rep]
                subst = dict((v,t) for v,t in zip(ldf.formula.args[0].args,term.args)
                             if not isinstance(v,il.Variable))
                inst = lu.substitute_constants_ast(cnst,subst)
                theory.append(inst)
#                iu.dbg('inst')
                matched.add(term)
    return lu.Clauses(theory)
 def add_state(self, eqns):
     clauses = lut.Clauses(eqns)
     state = self.domain.new_state(clauses)
     univs = self.get_universes()
     if univs is not None:
         state.universe = univs
     if self.last_action is not None:
         expr = itp.action_app(self.last_action, self.states[-1])
         if self.returned is not None:
             expr.subgraph = self.returned
             self.returned = None
         self.last_action = None
         self.add(state, expr)
     else:
         self.add(state)
示例#11
0
 def update_theory(self):
     theory = list(self.get_axioms())
     # axioms of the derived relations TODO: used only the
     # referenced ones, but we need to know abstract domain for
     # this
     for ldf in self.definitions:
         cnst = ldf.formula.to_constraint()
         if all(isinstance(p,il.Variable) for p in ldf.formula.args[0].args):
             theory.append(cnst) # TODO: make this a def?
     # extensionality axioms for structs
     for sort in sorted(self.sort_destructors):
         destrs = self.sort_destructors[sort]
         if any(d.name in self.sig.symbols for d in destrs):
             ea = il.extensionality(destrs)
             if il.is_epr(ea):
                 theory.append(ea)
     self.theory = lu.Clauses(theory)
示例#12
0
文件: ivy_trace.py 项目: hannesm/ivy
 def new_state_pairs(self, sym_pairs, env):
     eqns = []
     for sym, renamed_sym in sym_pairs:
         rmap = {renamed_sym: sym}
         # TODO: what if the renamed symbol is not in the model?
         for fmla in self.eqs[renamed_sym]:
             rfmla = lut.rename_ast(fmla, rmap)
             eqns.append(rfmla)
     clauses = lut.Clauses(eqns)
     state = self.domain.new_state(clauses)
     state.universe = self.model.universes(numerals=True)
     if self.last_action is not None:
         expr = itp.action_app(self.last_action, self.states[-1])
         if self.returned is not None:
             expr.subgraph = self.returned
             self.returned = None
         self.last_action = None
         self.add(state, expr)
     else:
         self.add(state)
示例#13
0
def to_aiger(mod,ext_act):

    erf = il.Symbol('err_flag',il.find_sort('bool'))
    errconds = []
    add_err_flag_mod(mod,erf,errconds)

    # we use a special state variable __init to indicate the initial state

    ext_acts = [mod.actions[x] for x in sorted(mod.public_actions)]
    ext_act = ia.EnvAction(*ext_acts)

    init_var = il.Symbol('__init',il.find_sort('bool')) 
    init = add_err_flag(ia.Sequence(*([a for n,a in mod.initializers]+[ia.AssignAction(init_var,il.And())])),erf,errconds)
    action = ia.Sequence(ia.AssignAction(erf,il.Or()),ia.IfAction(init_var,ext_act,init))
    
    # get the invariant to be proved, replacing free variables with
    # skolems. First, we apply any proof tactics.

    pc = ivy_proof.ProofChecker(mod.axioms,mod.definitions,mod.schemata)
    pmap = dict((lf.id,p) for lf,p in mod.proofs)
    conjs = []
    for lf in mod.labeled_conjs:
        if lf.id in pmap:
            proof = pmap[lf.id]
            subgoals = pc.admit_proposition(lf,proof)
            conjs.extend(subgoals)
        else:
            conjs.append(lf)

    invariant = il.And(*[il.drop_universals(lf.formula) for lf in conjs])
#    iu.dbg('invariant')
    skolemizer = lambda v: ilu.var_to_skolem('__',il.Variable(v.rep,v.sort))
    vs = ilu.used_variables_in_order_ast(invariant)
    sksubs = dict((v.rep,skolemizer(v)) for v in vs)
    invariant = ilu.substitute_ast(invariant,sksubs)
    invar_syms = ilu.used_symbols_ast(invariant)
    
    # compute the transition relation

    stvars,trans,error = action.update(mod,None)
    

#    print 'action : {}'.format(action)
#    print 'annotation: {}'.format(trans.annot)
    annot = trans.annot
#    match_annotation(action,annot,MatchHandler())
    
    indhyps = [il.close_formula(il.Implies(init_var,lf.formula)) for lf in mod.labeled_conjs]
#    trans = ilu.and_clauses(trans,indhyps)

    # save the original symbols for trace
    orig_syms = ilu.used_symbols_clauses(trans)
    orig_syms.update(ilu.used_symbols_ast(invariant))
                     
    # TODO: get the axioms (or maybe only the ground ones?)

    # axioms = mod.background_theory()

    # rn = dict((sym,tr.new(sym)) for sym in stvars)
    # next_axioms = ilu.rename_clauses(axioms,rn)
    # return ilu.and_clauses(axioms,next_axioms)

    funs = set()
    for df in trans.defs:
        funs.update(ilu.used_symbols_ast(df.args[1]))
    for fmla in trans.fmlas:
        funs.update(ilu.used_symbols_ast(fmla))
#   funs = ilu.used_symbols_clauses(trans)
    funs.update(ilu.used_symbols_ast(invariant))
    funs = set(sym for sym in funs if  il.is_function_sort(sym.sort))
    iu.dbg('[str(fun) for fun in funs]')

    # Propositionally abstract

    # step 1: get rid of definitions of non-finite symbols by turning
    # them into constraints

    new_defs = []
    new_fmlas = []
    for df in trans.defs:
        if len(df.args[0].args) == 0 and is_finite_sort(df.args[0].sort):
            new_defs.append(df)
        else:
            fmla = df.to_constraint()
            new_fmlas.append(fmla)
    trans = ilu.Clauses(new_fmlas+trans.fmlas,new_defs)

    # step 2: get rid of ite's over non-finite sorts, by introducing constraints

    cnsts = []
    new_defs = [elim_ite(df,cnsts) for df in trans.defs]
    new_fmlas = [elim_ite(fmla,cnsts) for fmla in trans.fmlas]
    trans = ilu.Clauses(new_fmlas+cnsts,new_defs)
    
    # step 3: eliminate quantfiers using finite instantiations

    from_asserts = il.And(*[il.Equals(x,x) for x in ilu.used_symbols_ast(il.And(*errconds)) if
                            tr.is_skolem(x) and not il.is_function_sort(x.sort)])
    iu.dbg('from_asserts')
    invar_syms.update(ilu.used_symbols_ast(from_asserts))
    sort_constants = mine_constants(mod,trans,il.And(invariant,from_asserts))
    sort_constants2 = mine_constants2(mod,trans,invariant)
    print '\ninstantiations:'
    trans,invariant = Qelim(sort_constants,sort_constants2)(trans,invariant,indhyps)
    
    
#    print 'after qe:'
#    print 'trans: {}'.format(trans)
#    print 'invariant: {}'.format(invariant)

    # step 4: instantiate the axioms using patterns

    # We have to condition both the transition relation and the
    # invariant on the axioms, so we define a boolean symbol '__axioms'
    # to represent the axioms.

    axs = instantiate_axioms(mod,stvars,trans,invariant,sort_constants,funs)
    ax_conj = il.And(*axs)
    ax_var = il.Symbol('__axioms',ax_conj.sort)
    ax_def = il.Definition(ax_var,ax_conj)
    invariant = il.Implies(ax_var,invariant)
    trans = ilu.Clauses(trans.fmlas+[ax_var],trans.defs+[ax_def])
    
    # step 5: eliminate all non-propositional atoms by replacing with fresh booleans
    # An atom with next-state symbols is converted to a next-state symbol if possible

    stvarset = set(stvars)
    prop_abs = dict()  # map from atoms to proposition variables
    global prop_abs_ctr  # sigh -- python lameness
    prop_abs_ctr = 0   # counter for fresh symbols
    new_stvars = []    # list of fresh symbols

    # get the propositional abstraction of an atom
    def new_prop(expr):
        res = prop_abs.get(expr,None)
        if res is None:
            prev = prev_expr(stvarset,expr,sort_constants)
            if prev is not None:
#                print 'stvar: old: {} new: {}'.format(prev,expr)
                pva = new_prop(prev)
                res = tr.new(pva)
                new_stvars.append(pva)
                prop_abs[expr] = res  # prevent adding this again to new_stvars
            else:
                global prop_abs_ctr
                res = il.Symbol('__abs[{}]'.format(prop_abs_ctr),expr.sort)
#                print '{} = {}'.format(res,expr)
                prop_abs[expr] = res
                prop_abs_ctr += 1
        return res

    # propositionally abstract an expression
    global mk_prop_fmlas
    mk_prop_fmlas = []
    def mk_prop_abs(expr):
        if il.is_quantifier(expr) or len(expr.args) > 0 and any(not is_finite_sort(a.sort) for a in expr.args):
            return new_prop(expr)
        return expr.clone(map(mk_prop_abs,expr.args))

    
    # apply propositional abstraction to the transition relation
    new_defs = map(mk_prop_abs,trans.defs)
    new_fmlas = [mk_prop_abs(il.close_formula(fmla)) for fmla in trans.fmlas]

    # find any immutable abstract variables, and give them a next definition

    def my_is_skolem(x):
        res = tr.is_skolem(x) and x not in invar_syms
        return res    
    def is_immutable_expr(expr):
        res = not any(my_is_skolem(sym) or tr.is_new(sym) or sym in stvarset for sym in ilu.used_symbols_ast(expr))
        return res
    for expr,v in prop_abs.iteritems():
        if is_immutable_expr(expr):
            new_stvars.append(v)
            print 'new state: {}'.format(expr)
            new_defs.append(il.Definition(tr.new(v),v))

    trans = ilu.Clauses(new_fmlas+mk_prop_fmlas,new_defs)

    # apply propositional abstraction to the invariant
    invariant = mk_prop_abs(invariant)

    # create next-state symbols for atoms in the invariant (is this needed?)
    rn = dict((sym,tr.new(sym)) for sym in stvars)
    mk_prop_abs(ilu.rename_ast(invariant,rn))  # this is to pick up state variables from invariant

    # update the state variables by removing the non-finite ones and adding the fresh state booleans
    stvars = [sym for sym in stvars if is_finite_sort(sym.sort)] + new_stvars

#    iu.dbg('trans')
#    iu.dbg('stvars')
#    iu.dbg('invariant')
#    exit(0)

    # For each state var, create a variable that corresponds to the input of its latch
    # Also, havoc all the state bits except the init flag at the initial time. This
    # is needed because in aiger, all latches start at 0!

    def fix(v):
        return v.prefix('nondet')
    def curval(v):
        return v.prefix('curval')
    def initchoice(v):
        return v.prefix('initchoice')
    stvars_fix_map = dict((tr.new(v),fix(v)) for v in stvars)
    stvars_fix_map.update((v,curval(v)) for v in stvars if v != init_var)
    trans = ilu.rename_clauses(trans,stvars_fix_map)
#    iu.dbg('trans')
    new_defs = trans.defs + [il.Definition(ilu.sym_inst(tr.new(v)),ilu.sym_inst(fix(v))) for v in stvars]
    new_defs.extend(il.Definition(curval(v),il.Ite(init_var,v,initchoice(v))) for v in stvars if  v != init_var)
    trans = ilu.Clauses(trans.fmlas,new_defs)
    
    # Turn the transition constraint into a definition
    
    cnst_var = il.Symbol('__cnst',il.find_sort('bool'))
    new_defs = list(trans.defs)
    new_defs.append(il.Definition(tr.new(cnst_var),fix(cnst_var)))
    new_defs.append(il.Definition(fix(cnst_var),il.Or(cnst_var,il.Not(il.And(*trans.fmlas)))))
    stvars.append(cnst_var)
    trans = ilu.Clauses([],new_defs)
    
    # Input are all the non-defined symbols. Output indicates invariant is false.

#    iu.dbg('trans')
    def_set = set(df.defines() for df in trans.defs)
    def_set.update(stvars)
#    iu.dbg('def_set')
    used = ilu.used_symbols_clauses(trans)
    used.update(ilu.symbols_ast(invariant))
    inputs = [sym for sym in used if
              sym not in def_set and not il.is_interpreted_symbol(sym)]
    fail = il.Symbol('__fail',il.find_sort('bool'))
    outputs = [fail]
    

#    iu.dbg('trans')
    
    # make an aiger

    aiger = Encoder(inputs,stvars,outputs)
    comb_defs = [df for df in trans.defs if not tr.is_new(df.defines())]

    invar_fail = il.Symbol('invar__fail',il.find_sort('bool'))  # make a name for invariant fail cond
    comb_defs.append(il.Definition(invar_fail,il.Not(invariant)))

    aiger.deflist(comb_defs)
    for df in trans.defs:
        if tr.is_new(df.defines()):
            aiger.set(tr.new_of(df.defines()),aiger.eval(df.args[1]))
    miter = il.And(init_var,il.Not(cnst_var),il.Or(invar_fail,il.And(fix(erf),il.Not(fix(cnst_var)))))
    aiger.set(fail,aiger.eval(miter))

#    aiger.sub.debug()

    # make a decoder for the abstract propositions

    decoder = dict((y,x) for x,y in prop_abs.iteritems())
    for sym in aiger.inputs + aiger.latches:
        if sym not in decoder and sym in orig_syms:
            decoder[sym] = sym

    cnsts = set(sym for syms in sort_constants.values() for sym in syms)
    return aiger,decoder,annot,cnsts,action,stvarset
示例#14
0
 def background_theory(self, symbols=None):
     if hasattr(self, "theory"):
         return self.theory
     return lu.Clauses([])
示例#15
0
文件: ivy_check.py 项目: hannesm/ivy
def get_conjs(mod):
    fmlas = [lf.formula for lf in mod.labeled_conjs if not lf.explicit]
    return lut.Clauses(fmlas, annot=act.EmptyAnnotation())
示例#16
0
 def constraints(self):
     return ilu.Clauses(self.concept_session.suppose_constraints)
示例#17
0
 def abstractor(state):
     state.clauses = ilu.Clauses(stvals)
     state.universes = dict() # indicates this is a singleton state
示例#18
0
    def add_state(self,stvals,action):
#        iu.dbg('stvals')
        self.add(itp.State(value=ilu.Clauses(stvals),expr=itp.action_app(action,self.states[-1]),label='ext'))