コード例 #1
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;
}
""")
コード例 #2
0
ファイル: ivy_to_cpp.py プロジェクト: jamella/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;
}
""")
コード例 #3
0
ファイル: ivy_proof.py プロジェクト: hannesm/ivy
    def __init__(self, axioms, definitions, schemata=None):
        """ A proof checker starts with sets of axioms, definitions and schemata
    
        - axioms is a list of ivy_ast.LabeledFormula
        - definitions is a list of ivy_ast.LabeledFormula
        - schemata is a map from string names to ivy_ast.LabeledFormula

        The schemata argument is optional and is included for backward compatibility
        with ivy_mc.
        """

        self.axioms = [normalize_goal(ax) for ax in axioms]
        self.definitions = dict(
            (d.formula.defines().name, normalize_goal(d)) for d in definitions)
        self.schemata = dict(
            (x, normalize_goal(y)) for x, y in
            schemata.iteritems()) if schemata is not None else dict()
        for ax in axioms:
            if ax.label is not None:
                self.schemata[ax.name] = ax
        self.stale = set()  # set of symbols that are not fresh
        for lf in axioms + definitions:
            self.stale.update(lu.used_symbols_ast(lf.formula))
        for goal in schemata.values():
            vocab = goal_vocab(goal)
            self.stale.update(vocab.symbols)
コード例 #4
0
def mine_constants(mod,trans,invariant):
    res = defaultdict(list)
    for c in ilu.used_symbols_ast(invariant):
        if not il.is_function_sort(c.sort) and tr.is_skolem(c):
            res[c.sort].append(c)
#    iu.dbg('res')
    return res
コード例 #5
0
 def show_sym(v,decd,val):
     if all(x in inv_env or not my_is_skolem(x) and
            not tr.is_new(x) and x not in env for x in ilu.used_symbols_ast(decd)):
         expr = ilu.rename_ast(decd,inv_env)
         if not (expr in self.current and self.current[expr] == val):
             print '        {} = {}'.format(expr,val)
             self.current[expr] = val
コード例 #6
0
ファイル: ivy_proof.py プロジェクト: hannesm/ivy
def fmla_vocab(fmla):
    """ Get the free vocabulary of a formula, including sorts, symbols and variables """

    things = lu.used_sorts_ast(fmla)
    things.update(lu.used_symbols_ast(fmla))
    things.update(lu.used_variables_ast(fmla))
    return things
コード例 #7
0
def prev_expr(stvarset,expr,sort_constants):
    if any(sym in stvarset or tr.is_skolem(sym) and not sym in sort_constants[sym.sort]
           for sym in ilu.symbols_ast(expr)):
        return None
    news = [sym for sym in ilu.used_symbols_ast(expr) if tr.is_new(sym)]
    if news:
        rn = dict((sym,tr.new_of(sym)) for sym in news)
        return ilu.rename_ast(expr,rn)
    return None        
コード例 #8
0
ファイル: ivy_solver.py プロジェクト: juanmaneo/ivy
def clauses_model_to_diagram(clauses1,ignore = None, implied = None,model = None,axioms=None,weaken=True,numerals=True):
    """ Return a diagram of a model of clauses1 or None.  The function "ignore", if
    provided, returns true for symbols that should be ignored in the
    diagram.
    """
#    print "clauses_model_to_diagram clauses1 = {}".format(clauses1)
    if axioms == None:
        axioms = true_clauses()
    h = model_if_none(and_clauses(clauses1,axioms),implied,model)
    ignore = ignore if ignore != None else lambda x: False
    res = model_facts(h,(lambda x: False),clauses1,upclose=True) # why not pass axioms?
#    print "clauses_model_to_diagram res = {}".format(res)
    # find representative elements
    # find representatives of universe elements
    if numerals:
        reps = numeral_assign(res,h)
    else:
        reps = dict()
        for c in used_constants_clauses(clauses1):
    #        print "constant: {}".format(c)
            mc = get_model_constant(h.model,ivy_logic.Constant(c))
    #        print "value: {}".format(mc)
            if mc.rep not in reps or reps[mc.rep].rep.is_skolem() and not c.is_skolem():
                reps[mc.rep] = ivy_logic.Constant(c)
        for s in h.sorts():
            for e in h.sort_universe(s):
                if e.rep not in reps:
                    reps[e.rep] = e.rep.skolem()()
#    print "clauses_model_to_diagram reps = {}".format(reps)
    # filter out clauses using universe elements without reps
#    res = [cls for cls in res if all(c in reps for c in used_constants_clause(cls))]
    # replace universe elements with their reps
#    print "clauses_model_to_diagram res = {}".format(res)
    res = substitute_constants_clauses(res,reps)
    # filter defined skolems
    # this caused a bug in the leader example. the generated diagram did not satisfy clauses1
    res.fmlas = [f for f in res.fmlas if not any((x.is_skolem() and x in clauses1.defidx) for x in used_symbols_ast(f))]
#    print "clauses_model_to_diagram res = {}".format(res)
    uc = Clauses([[ivy_logic._eq_lit(ivy_logic.Variable('X',c.get_sort()),reps[c.rep])
                   for c in h.sort_universe(s)] for s in h.sorts()])
#    print "clauses_model_to_diagram uc = {}".format(uc)

    #    uc = true_clauses()
    if weaken:
        res = unsat_core(res,and_clauses(uc,axioms),clauses1) # implied not used here
#    print "clauses_model_to_diagram res = {}".format(res)

#    print "foo = {}".format(unsat_core(and_clauses(uc,axioms),true_clauses(),clauses1))

    # filter out non-rep skolems
    repset = set(c.rep for e,c in reps.iteritems())
#    print "clauses_model_to_diagram repset = {}".format(repset)
    ign = lambda x,ignore=ignore: (ignore(x) and not x in repset)
    res = Clauses([cl for cl in res.fmlas if not any(ign(c) for c in used_symbols_ast(cl))])
#    print "clauses_model_to_diagram res = {}".format(res)
    return res
コード例 #9
0
def mine_constants2(mod,trans,invariant):
    defnd = set(dfn.defines() for dfn in trans.defs)
    res = defaultdict(list)
    syms = ilu.used_symbols_ast(invariant)
    syms.update(ilu.used_symbols_clauses(trans))
    for c in syms:
        if not il.is_function_sort(c.sort):
            res[c.sort].append(c)
#    iu.dbg('res')
    return res
コード例 #10
0
ファイル: ivy_graph.py プロジェクト: jamella/ivy
 def state_changed(self,recomp=True):
     cs = self.concept_session
     cs.cache.clear()
     vocab = list(ilu.used_symbols_asts([c.formula for c in self.nodes]))
     fsyms = list(s for s in ilu.used_symbols_ast(cs._to_formula()) if not s.is_skolem())
     vocab += list(all_symbols()) + fsyms
     cs.domain = replace_concept_domain_vocabulary(cs.domain,set(vocab))
     for concept in self.new_relations:
         add_domain_concept(self.concept_domain.concepts,concept)
     if recomp:
         self.recompute()
コード例 #11
0
ファイル: ivy_graph.py プロジェクト: xornand/ivy
 def state_changed(self, recomp=True):
     cs = self.concept_session
     cs.cache.clear()
     vocab = list(ilu.used_symbols_asts([c.formula for c in self.nodes]))
     fsyms = list(s for s in ilu.used_symbols_ast(cs._to_formula())
                  if not s.is_skolem())
     vocab += list(all_symbols()) + fsyms
     cs.domain = replace_concept_domain_vocabulary(cs.domain, set(vocab))
     for concept in self.new_relations:
         add_domain_concept(self.concept_domain.concepts, concept)
     if recomp:
         self.recompute()
コード例 #12
0
ファイル: ivy_proof.py プロジェクト: hannesm/ivy
def match_get(match, sym, env, default=None):
    """ get the value of a symbol in a match, checking that no symbols
    are captured in env """
    val = match.get(sym, None)
    if val is not None:
        vocab = lu.used_symbols_ast(val)
        vocab.update(lu.variables_ast(val))
        for v in vocab:
            if v in env:
                raise_capture(v)
        return val
    return default
コード例 #13
0
 def __init__(self,defn):
     self.defn = defn
     self.dependencies = used_symbols_ast(defn.args[1])
コード例 #14
0
ファイル: ivy_actions.py プロジェクト: JJTRX/ivy
 def __init__(self, defn):
     self.defn = defn
     self.dependencies = used_symbols_ast(defn.args[1])
コード例 #15
0
 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
コード例 #16
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
コード例 #17
0
ファイル: ivy_solver.py プロジェクト: simudream/ivy
def clauses_model_to_diagram(clauses1,
                             ignore=None,
                             implied=None,
                             model=None,
                             axioms=None,
                             weaken=True):
    """ Return a diagram of a model of clauses1 or None.  The function "ignore", if
    provided, returns true for symbols that should be ignored in the
    diagram.
    """
    print "clauses_model_to_diagram clauses1 = {}".format(clauses1)
    if axioms == None:
        axioms = true_clauses
    h = model_if_none(and_clauses(clauses1, axioms), implied, model)
    ignore = ignore if ignore != None else lambda x: False
    res = model_facts(h, (lambda x: False), clauses1,
                      upclose=True)  # why not pass axioms?
    print "clauses_model_to_diagram res = {}".format(res)
    # find representative elements
    # find representatives of universe elements
    reps = dict()
    for c in used_constants_clauses(clauses1):
        #        print "constant: {}".format(c)
        mc = get_model_constant(h.model, ivy_logic.Constant(c))
        #        print "value: {}".format(mc)
        if mc.rep not in reps or reps[
                mc.rep].rep.is_skolem() and not c.is_skolem():
            reps[mc.rep] = ivy_logic.Constant(c)
    for s in h.sorts():
        for e in h.sort_universe(s):
            if e.rep not in reps:
                reps[e.rep] = e.rep.skolem()()
    print "clauses_model_to_diagram reps = {}".format(reps)
    # filter out clauses using universe elements without reps
    #    res = [cls for cls in res if all(c in reps for c in used_constants_clause(cls))]
    # replace universe elements with their reps
    print "clauses_model_to_diagram res = {}".format(res)
    res = substitute_constants_clauses(res, reps)
    # filter defined skolems
    # this caused a bug in the leader example. the generated diagram did not satisfy clauses1
    res.fmlas = [
        f for f in res.fmlas
        if not any((x.is_skolem() and x in clauses1.defidx)
                   for x in used_symbols_ast(f))
    ]
    print "clauses_model_to_diagram res = {}".format(res)
    uc = Clauses([[
        ivy_logic._eq_lit(ivy_logic.Variable('X', c.get_sort()), reps[c.rep])
        for c in h.sort_universe(s)
    ] for s in h.sorts()])
    print "clauses_model_to_diagram uc = {}".format(uc)

    #    uc = true_clauses()
    if weaken:
        res = unsat_core(res, and_clauses(uc, axioms),
                         clauses1)  # implied not used here
    print "clauses_model_to_diagram res = {}".format(res)

    #    print "foo = {}".format(unsat_core(and_clauses(uc,axioms),true_clauses(),clauses1))

    # filter out non-rep skolems
    repset = set(c.rep for e, c in reps.iteritems())
    print "clauses_model_to_diagram repset = {}".format(repset)
    ign = lambda x, ignore=ignore: (ignore(x) and not x in repset)
    res = Clauses([
        cl for cl in res.fmlas
        if not any(ign(c) for c in used_symbols_ast(cl))
    ])
    print "clauses_model_to_diagram res = {}".format(res)
    return res
コード例 #18
0
ファイル: ivy_isolate.py プロジェクト: kleopatra999/ivy
def isolate_component(mod, isolate_name, extra_with=[], extra_strip=None):
    if isolate_name not in mod.isolates:
        raise iu.IvyError(None, "undefined isolate: {}".format(isolate_name))
    isolate = mod.isolates[isolate_name]
    verified = set(a.relname for a in (isolate.verified() + tuple(extra_with)))
    present = set(a.relname for a in isolate.present())
    present.update(verified)
    if not interpret_all_sorts:
        for type_name in list(ivy_logic.sig.interp):
            if not (type_name in present or any(
                    startswith_eq_some(itp.label.rep, present, mod)
                    for itp in mod.interps[type_name] if itp.label)):
                del ivy_logic.sig.interp[type_name]
    delegates = set(s.delegated() for s in mod.delegates if not s.delegee())
    delegated_to = dict(
        (s.delegated(), s.delegee()) for s in mod.delegates if s.delegee())
    derived = set(df.args[0].func.name for df in mod.concepts)
    for name in present:
        if (name not in mod.hierarchy and name not in ivy_logic.sig.sorts
                and name not in derived and name not in ivy_logic.sig.interp
                and name not in mod.actions
                and name not in ivy_logic.sig.symbols):
            raise iu.IvyError(
                None,
                "{} is not an object, action, sort, definition, or interpreted function"
                .format(name))

    impl_mixins = defaultdict(list)
    # delegate all the stub actions to their implementations
    global implementation_map
    implementation_map = {}
    for actname, ms in mod.mixins.iteritems():
        implements = [
            m for m in ms if isinstance(m, ivy_ast.MixinImplementDef)
        ]
        impl_mixins[actname].extend(implements)
        before_after = [
            m for m in ms if not isinstance(m, ivy_ast.MixinImplementDef)
        ]
        del ms[:]
        ms.extend(before_after)
        for m in implements:
            for foo in (m.mixee(), m.mixer()):
                if foo not in mod.actions:
                    raise IvyError(m, 'action {} not defined'.format(foo))
            action = mod.actions[m.mixee()]
            if not (isinstance(action, ia.Sequence) and len(action.args) == 0):
                raise IvyError(
                    m,
                    'multiple implementations of action {}'.format(m.mixee()))
            action = ia.apply_mixin(m, mod.actions[m.mixer()], action)
            mod.actions[m.mixee()] = action
            implementation_map[m.mixee()] = m.mixer()

    new_actions = {}
    use_mixin = lambda name: startswith_some(name, present, mod)
    mod_mixin = lambda m: m if startswith_some(name, verified, mod
                                               ) else m.prefix_calls('ext:')
    all_mixins = lambda m: True
    no_mixins = lambda m: False
    after_mixins = lambda m: isinstance(m, ivy_ast.MixinAfterDef)
    before_mixins = lambda m: isinstance(m, ivy_ast.MixinBeforeDef)
    delegated_to_verified = lambda n: n in delegated_to and startswith_eq_some(
        delegated_to[n], verified, mod)
    ext_assumes = lambda m: before_mixins(m) and not delegated_to_verified(
        m.mixer())
    int_assumes = lambda m: after_mixins(m) and not delegated_to_verified(
        m.mixer())
    ext_assumes_no_ver = lambda m: not delegated_to_verified(m.mixer())
    summarized_actions = set()
    for actname, action in mod.actions.iteritems():
        ver = startswith_eq_some(actname, verified, mod)
        pre = startswith_eq_some(actname, present, mod)
        if pre:
            if not ver:
                assert hasattr(action, 'lineno')
                assert hasattr(action, 'formal_params'), action
                ext_action = action.assert_to_assume().prefix_calls('ext:')
                assert hasattr(ext_action, 'lineno')
                assert hasattr(ext_action, 'formal_params'), ext_action
                if actname in delegates:
                    int_action = action.prefix_calls('ext:')
                    assert hasattr(int_action, 'lineno')
                    assert hasattr(int_action, 'formal_params'), int_action
                else:
                    int_action = ext_action
                    assert hasattr(int_action, 'lineno')
                    assert hasattr(int_action, 'formal_params'), int_action
            else:
                int_action = ext_action = action
                assert hasattr(int_action, 'lineno')
                assert hasattr(int_action, 'formal_params'), int_action
            # internal version of the action has mixins checked
            ea = no_mixins if ver else int_assumes
            new_actions[actname] = add_mixins(mod, actname, int_action, ea,
                                              use_mixin, lambda m: m)
            # external version of the action assumes mixins are ok, unless they
            # are delegated to a currently verified object
            ea = ext_assumes if ver else ext_assumes_no_ver
            new_action = add_mixins(mod, actname, ext_action, ea, use_mixin,
                                    mod_mixin)
            new_actions['ext:' + actname] = new_action
            # TODO: external version is public if action public *or* called from opaque
            # public_actions.add('ext:'+actname)
        else:
            # TODO: here must check that summarized action does not
            # have a call dependency on the isolated module
            summarized_actions.add(actname)
            action = summarize_action(action)
            new_actions[actname] = add_mixins(mod, actname, action,
                                              after_mixins, use_mixin,
                                              mod_mixin)
            new_actions['ext:' + actname] = add_mixins(mod, actname, action,
                                                       all_mixins, use_mixin,
                                                       mod_mixin)

    # figure out what is exported:
    exported = set()
    for e in mod.exports:
        if not e.scope() and startswith_eq_some(e.exported(), present,
                                                mod):  # global scope
            exported.add('ext:' + e.exported())
    for actname, action in mod.actions.iteritems():
        if not startswith_some(actname, present, mod):
            for c in action.iter_calls():
                if (startswith_some(c, present, mod) or any(
                        startswith_some(m.mixer(), present, mod)
                        for m in mod.mixins[c])):
                    exported.add('ext:' + c)
#    print "exported: {}".format(exported)

# We allow objects to reference any symbols in global scope, and
# we keep axioms declared in global scope. Because of the way
# thigs are named, this gives a different condition for keeping
# symbols and axioms (in particular, axioms in global scope have
# label None). Maybe this needs to be cleaned up.

    keep_sym = lambda name: (iu.ivy_compose_character not in name or
                             startswith_eq_some(name, present))

    keep_ax = lambda name: (name is None or startswith_eq_some(
        name.rep, present, mod))
    check_pr = lambda name: (name is None or startswith_eq_some(
        name.rep, verified, mod))

    prop_deps = get_prop_dependencies(mod)

    # filter the conjectures

    new_conjs = [c for c in mod.labeled_conjs if keep_ax(c.label)]
    del mod.labeled_conjs[:]
    mod.labeled_conjs.extend(new_conjs)

    # filter the inits

    new_inits = [c for c in mod.labeled_inits if keep_ax(c.label)]
    del mod.labeled_inits[:]
    mod.labeled_inits.extend(new_inits)

    # filter the axioms
    dropped_axioms = [a for a in mod.labeled_axioms if not keep_ax(a.label)]
    mod.labeled_axioms = [a for a in mod.labeled_axioms if keep_ax(a.label)]
    mod.labeled_props = [a for a in mod.labeled_props if keep_ax(a.label)]

    # convert the properties not being verified to axioms
    mod.labeled_axioms.extend(
        [a for a in mod.labeled_props if not check_pr(a.label)])
    mod.labeled_props = [a for a in mod.labeled_props if check_pr(a.label)]

    # filter definitions
    mod.concepts = [
        c for c in mod.concepts
        if startswith_eq_some(c.args[0].func.name, present, mod)
    ]

    # filter the signature
    # keep only the symbols referenced in the remaining
    # formulas

    asts = []
    for x in [
            mod.labeled_axioms, mod.labeled_props, mod.labeled_inits,
            mod.labeled_conjs
    ]:
        asts += [y.formula for y in x]
    asts += mod.concepts
    asts += [action for action in new_actions.values()]
    sym_names = set(x.name for x in lu.used_symbols_asts(asts))

    if filter_symbols.get() or cone_of_influence.get():
        old_syms = list(mod.sig.symbols)
        for sym in old_syms:
            if sym not in sym_names:
                del mod.sig.symbols[sym]

    # check that any dropped axioms do not refer to the isolate's signature
    # and any properties have dependencies present

    def pname(s):
        return s.label if s.label else ""

    if enforce_axioms.get():
        for a in dropped_axioms:
            for x in lu.used_symbols_ast(a.formula):
                if x.name in sym_names:
                    raise iu.IvyError(
                        a, "relevant axiom {} not enforced".format(pname(a)))
        for actname, action in mod.actions.iteritems():
            if startswith_eq_some(actname, present, mod):
                for c in action.iter_calls():
                    called = mod.actions[c]
                    if not startswith_eq_some(c, present, mod):
                        if not (type(called) == ia.Sequence
                                and not called.args):
                            raise iu.IvyError(
                                None,
                                "No implementation for action {}".format(c))
        for p, ds in prop_deps:
            for d in ds:
                if not startswith_eq_some(d, present, mod):
                    raise iu.IvyError(
                        p,
                        "property {} depends on abstracted object {}".format(
                            pname(p), d))


#    for x,y in new_actions.iteritems():
#        print iu.pretty(ia.action_def_to_str(x,y))

# check for interference

#    iu.dbg('list(summarized_actions)')
    check_interference(mod, new_actions, summarized_actions)

    # After checking, we can put in place the new action definitions

    mod.public_actions.clear()
    mod.public_actions.update(exported)
    mod.actions.clear()
    mod.actions.update(new_actions)

    # TODO: need a better way to filter signature
    # new_syms = set(s for s in mod.sig.symbols if keep_sym(s))
    # for s in list(mod.sig.symbols):
    #     if s not in new_syms:
    #         del mod.sig.symbols[s]

    # strip the isolate parameters

    strip_isolate(mod, isolate, impl_mixins, extra_strip)

    # collect the initial condition

    init_cond = ivy_logic.And(*(lf.formula for lf in mod.labeled_inits))
    mod.init_cond = lu.formula_to_clauses(init_cond)