Пример #1
0
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
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
def make_check_art(act_name=None, precond=[]):
    action = act.env_action(act_name)

    ag = art.AnalysisGraph()

    pre = itp.State()
    pre.clauses = lut.and_clauses(*precond) if precond else lut.true_clauses()
    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))

    return ag, post, fail
Пример #4
0
def learnWeekestInv(mod, clf, actname):
    '''
	candInv and coincide will be of type ivy_logic_utils.Clauses.
	coincide is a Clause object representing samples which cannot be distinguish by feature set
	'''
    global candInv, coincide
    candInv, coincide = true_clauses(), false_clauses()
    while True:
        spos = samplePos(mod, candInv, coincide,
                         actname)  # Generating positve sample
        sneg = sampleNeg(mod, candInv, actname)
        if spos is None and sneg is None:
            break
        spos, sneg = Sample(spos, '1'), Sample(sneg, '0')
        print "Pos Sample", spos.unv.unvsize() if hasattr(spos,
                                                          'interp') else None
        print "Neg Sample", sneg.unv.unvsize() if hasattr(sneg,
                                                          'interp') else None
        # if hasattr(spos, 'interp'): # spos is not None
        # 	print "<plearn> + sample interpretation : ",spos.interp, "\n" # for detailed information
        # 	spos.displaySample() # for displaying the sample
        # if hasattr(sneg, 'interp'): # sneg is not None
        # print "<plearn> - sample interpretation : ",sneg.interp, "\n" # for detailed information
        # sneg.displaySample()
        clf.addSample(spos)  # adding Positive sample
        clf.addSample(sneg)
        print "<plearn> done adding samples"
        import sys
        sys.stdout.flush()
        candInv, coincide = clf.learn()
        print "<plearn> candidate Invariant", candInv
        sys.stdout.flush()
        # print "coincide Clause", coincide
        # a = raw_input('One iteration of loop completed, press enter:')
    return candInv
Пример #5
0
def learnInv(mod):
    print "\n" * 2
    print "<plearn> Directed to learning Algorithm"
    global silent, module, numVarFS, featureset
    silent = True
    updatenvi(mod)
    module = mod
    while True:
        print "Checking Inductiveness of the Invariant"
        maxunv, isInvInd = icheck.isInvInductive(mod)
        print "Invariant is{} Inductive\n".format('' if isInvInd else ' NOT')
        if isInvInd:  # its Inductive so nothing to do
            silent = False
            checkInitialCond(mod)
            break
        # testfunc(mod)
        for actname in sorted(mod.public_actions):
            print "learning Invariant for action {}".format(actname)
            clf = Classifier()  # new classifier
            newInv = learnWeekestInv(mod, clf, actname)
            print "\n" * 2
            print "<plearn> new Invariant:", newInv
            a = raw_input('new Invariant learned, press enter to continue')
            print "\n" * 2
            numVarFS = {}  # resetting numVarFS
            featureset = []  # resetting featuerset
            if newInv != true_clauses():
                lf = ivy_ast.LabeledFormula(*[
                    ivy_ast.Atom('learnedInv' + actname),
                    logic.And(*newInv.fmlas)
                ])
                mod.labeled_conjs.append(
                    lf)  # modifying mod and module, obj are copied by refr.
                updatenvi(mod)  # takes care of numVarInv
Пример #6
0
    def process_actions(self):
        for name, action in self.mod.actions.iteritems():
            #             print(type(action))
            #             print ("action2: ", ia.action_def_to_str(name, action))
            ag = ivy_art.AnalysisGraph()
            pre = itp.State()
            pre.clauses = lut.true_clauses()
            #             print(pre.to_formula())
            post = ag.execute(action, pre)
            history = ag.get_history(post)
            clauses = lut.and_clauses(history.post)
            f = self.get_formula(clauses)
            conjuncts = clauses.fmlas
            defn = lut.close_epr(lg.And(*conjuncts))
            #             print(defn)
            #             assert(0)

            update = action.update(pre.domain, pre.in_scope)
            sf = self.standardize_action(f, update[0], name)
            self.add_new_constants(sf)

            actname = "action_" + name
            self.actions.add(actname)
            res = (sf, actname, "action", name)
            self.vmt[actname] = res
Пример #7
0
    def clear(self):

        # these fields represent all the module declarations

        self.all_relations = [
        ]  # this includes both base and derived relations in declaration order
        self.concepts = []  # TODO: these are actually "derived" relations
        self.labeled_axioms = []
        self.labeled_inits = []
        self.init_cond = lu.true_clauses()
        self.relations = dict()  # TODO: this is redundant, remove
        self.functions = dict()  # TODO: this is redundant, remove
        self.updates = []
        self.schemata = dict()
        self.instantiations = []
        self.concept_spaces = []
        self.labeled_conjs = []  # conjectures
        self.hierarchy = defaultdict(set)
        self.actions = {}
        self.predicates = {}
        self.assertions = []
        self.mixins = defaultdict(list)
        self.public_actions = set()
        self.isolates = {}
        self.exports = []
        self.delegates = []
        self.public_actions = set()  # hash of the exported actions
        self.progress = []  # list of progress properties
        self.rely = []  # list of rely relations
        self.mixord = []  # list of mixin order relations
        self.destructor_sorts = {}
        self.sort_destructors = defaultdict(list)

        self.sig = il.sig.copy()  # capture the current signature
Пример #8
0
    def clear(self):

        # these fields represent all the module declarations

        self.all_relations = [
        ]  # this includes both base and derived relations in declaration order
        self.definitions = []  # TODO: these are actually "derived" relations
        self.labeled_axioms = []
        self.labeled_props = []
        self.labeled_inits = []
        self.init_cond = lu.true_clauses()
        self.relations = dict()  # TODO: this is redundant, remove
        self.functions = dict()  # TODO: this is redundant, remove
        self.updates = []
        self.schemata = dict()
        self.theorems = dict()
        self.instantiations = []
        self.concept_spaces = []
        self.labeled_conjs = []  # conjectures
        self.labeled_templates = []  # conjectures
        self.hierarchy = defaultdict(set)
        self.actions = {}
        self.predicates = {}
        self.assertions = []
        self.mixins = defaultdict(list)
        self.public_actions = set()
        self.isolates = {}
        self.exports = []
        self.imports = []
        self.delegates = []
        self.public_actions = set()  # hash of the exported actions
        self.progress = []  # list of progress properties
        self.rely = []  # list of rely relations
        self.mixord = []  # list of mixin order relations
        self.destructor_sorts = {}
        self.sort_destructors = defaultdict(list)
        self.privates = set()  # set of string (names of private actions)
        self.interps = defaultdict(
            list)  # maps type names to lists of labeled interpretions
        self.natives = []  # list of NativeDef
        self.native_definitions = [
        ]  # list of definitions whose rhs is NativeExpr
        self.initializers = []  # list of name,action pairs
        self.params = []
        self.ghost_sorts = set()  # set of sort names
        self.native_types = {}  # map from sort names to ivy_ast.NativeType
        self.sort_order = []  # list of sorts names in order declared
        self.symbol_order = []  # list of symbols in order declared
        self.aliases = {}  # map from name to name
        self.before_export = {}  # map from string to action
        self.attributes = {}  # map from name to atom
        self.variants = defaultdict(list)  # map from sort name to list of sort
        self.ext_preconds = {}  # map from action name to formula
        self.proofs = []  # list of pair (labeled formula, proof)
        self.named = []  # list of pair (labeled formula, atom)
        self.subgoals = []  # (labeled formula * labeled formula list) list
        self.isolate_info = None  # IsolateInfo or None
        self.conj_actions = dict()  # map from conj names to action name list

        self.sig = il.sig.copy()  # capture the current signature
Пример #9
0
    def clear(self):

        # these fields represent all the module declarations

        self.all_relations = [] # this includes both base and derived relations in declaration order
        self.concepts = []  # TODO: these are actually "derived" relations
        self.labeled_axioms = []
        self.labeled_inits = []
        self.init_cond = lu.true_clauses()
        self.relations = dict()  # TODO: this is redundant, remove
        self.functions = dict()  # TODO: this is redundant, remove
        self.updates = []
        self.schemata = dict()
        self.instantiations = []
        self.concept_spaces = []
        self.labeled_conjs = []  # conjectures
        self.hierarchy = defaultdict(set)
        self.actions = {}
        self.predicates = {}
        self.assertions = []
        self.mixins = defaultdict(list)
        self.public_actions = set()
        self.isolates = {}
        self.exports = []
        self.delegates = []
        self.public_actions = set() # hash of the exported actions
        self.progress = []  # list of progress properties
        self.rely = [] # list of rely relations
        self.mixord = [] # list of mixin order relations
        self.destructor_sorts = {}
        self.sort_destructors = defaultdict(list)
        self.privates = set() # set of string (names of private actions)

        self.sig = il.sig.copy() # capture the current signature
Пример #10
0
    def process_actions(self):
        if ivy_compiler.isolate.get():
            st = ivy_compiler.isolate.get().split('.')[0]
        else:
            st = ''
        st = [st, 'timeout', 'handle', 'recv']
        for name in self.mod.public_actions:
            print >> sys.stderr, "action:\t", name
            if not (ivy_compiler.isolate.get() == None or any(s in name
                                                              for s in st)):
                continue
            action = ia.env_action(name)
            #             print ("action2: ", ia.action_def_to_str(name, action))
            ag = ivy_art.AnalysisGraph()
            pre = itp.State()
            pre.clauses = lut.true_clauses()
            #             print(pre.to_formula())
            with itp.EvalContext(check=False):
                post = ag.execute(action, pre)
            history = ag.get_history(post)
            clauses = lut.and_clauses(history.post)
            f = self.get_formula(clauses)
            conjuncts = clauses.fmlas
            defn = lut.close_epr(lg.And(*conjuncts))
            #             print(defn)
            #             assert(0)

            update = action.update(pre.domain, pre.in_scope)
            sf = self.standardize_action(f, update[0], name)
            self.add_new_constants(sf, 'action')

            actname = "action_" + name
            self.actions.add(actname)
            res = (sf, actname, "action", name)
            self.vmt[actname] = res
Пример #11
0
    def int_update(self,domain,pvars):
        update = ([],true_clauses(),false_clauses())
        axioms = domain.background_theory(pvars)
        for op in self.args:
            thing = op.int_update(domain,pvars);
#            print "op: {}, thing: {}".format(op,thing)
            update = compose_updates(update,axioms,thing)
        return update
Пример #12
0
 def int_update(self, domain, pvars):
     update = ([], true_clauses(), false_clauses())
     axioms = domain.background_theory(pvars)
     for op in self.args:
         thing = op.int_update(domain, pvars)
         #            print "op: {}, thing: {}".format(op,thing)
         update = compose_updates(update, axioms, thing)
     return update
Пример #13
0
 def action_update(self, domain, pvars):
     type_check(domain, self.args[0])
     check_can_assert(self.args[0], self)
     #        print type(self.args[0])
     if iu.new_assert_impl.get():
         return assert_action(self.args[0])
     else:
         cl = formula_to_clauses(dual_formula(self.args[0]))
         return SemActionValue([], true_clauses(), cl)
Пример #14
0
    def action_update(self,domain,pvars):
        type_check(domain,self.args[0])
        check_can_assert(self.args[0],self)
#        print type(self.args[0])
        if iu.new_assert_impl.get():
            return assert_action(self.args[0])
        else:
            cl = formula_to_clauses(dual_formula(self.args[0]))
            return SemActionValue([],true_clauses(),cl)
Пример #15
0
    def clear(self):

        # these fields represent all the module declarations

        self.all_relations = [] # this includes both base and derived relations in declaration order
        self.definitions = []  # TODO: these are actually "derived" relations
        self.labeled_axioms = []
        self.labeled_props = []
        self.labeled_inits = []
        self.init_cond = lu.true_clauses()
        self.relations = dict()  # TODO: this is redundant, remove
        self.functions = dict()  # TODO: this is redundant, remove
        self.updates = []
        self.schemata = dict()
        self.instantiations = []
        self.concept_spaces = []
        self.labeled_conjs = []  # conjectures
        self.hierarchy = defaultdict(set)
        self.actions = {}
        self.predicates = {}
        self.assertions = []
        self.mixins = defaultdict(list)
        self.public_actions = set()
        self.isolates = {}
        self.exports = []
        self.imports = []
        self.delegates = []
        self.public_actions = set() # hash of the exported actions
        self.progress = []  # list of progress properties
        self.rely = [] # list of rely relations
        self.mixord = [] # list of mixin order relations
        self.destructor_sorts = {}
        self.sort_destructors = defaultdict(list)
        self.privates = set() # set of string (names of private actions)
        self.interps = defaultdict(list) # maps type names to lists of labeled interpretions
        self.natives = [] # list of NativeDef
        self.native_definitions = [] # list of definitions whose rhs is NativeExpr
        self.initializers = [] # list of name,action pairs
        self.params = []
        self.ghost_sorts = set() # set of sort names
        self.native_types = {} # map from sort names to ivy_ast.NativeType
        self.sort_order = [] # list of sorts names in order declared
        self.symbol_order = [] # list of symbols in order declared
        self.aliases = {} # map from name to name
        self.before_export = {} # map from string to action
        self.attributes = {} # map from name to atom
        self.variants = defaultdict(list) # map from sort name to list of sort
        self.ext_preconds = {} # map from action name to formula
        self.proofs = [] # list of pair (labeled formula, proof)
        self.named = [] # list of pair (labeled formula, atom)
        self.subgoals = [] # (labeled formula * labeled formula list) list
        self.isolate_info = None # IsolateInfo or None
        self.conj_actions = dict() # map from conj names to action name list

        
        self.sig = il.sig.copy() # capture the current signature
Пример #16
0
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
Пример #17
0
    def action_update(self,domain,pvars):
        type_check(domain,self.args[0])
#        print type(self.args[0])
        ca = checked_assert.get()
        if ca:
            if ca != self.lineno:
                return ([],formula_to_clauses(self.args[0]),false_clauses())
        cl = formula_to_clauses(dual_formula(self.args[0]))
#        return ([],formula_to_clauses_tseitin(self.args[0]),cl)
        return ([],true_clauses(),cl)
Пример #18
0
    def is_sufficient(self, button=None):
        """
        Check if the active conjecture is sufficient to imply the current
        CTI conjecture at the next step

        TODO: this has a lot in common with check_inductiveness,
        should refactor common parts out
        """
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses
        from random import randrange

        with self.ui_parent.run_context():

            conj = self.get_selected_conjecture()
            target_conj = self.parent.current_conjecture

            ag = self.parent.new_ag()

            pre = State()
            pre.clauses = and_clauses(conj, *self.parent.conjectures)
            pre.clauses.annot = ia.EmptyAnnotation()

            action = ia.env_action(None)
            post = ag.execute(action, pre)
            post.clauses = ilu.true_clauses(annot=ia.EmptyAnnotation())

            assert target_conj.is_universal_first_order()
            used_names = frozenset(x.name for x in il.sig.symbols.values())

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

            clauses = dual_clauses(target_conj, witness)
            clauses.annot = ia.EmptyAnnotation()
            res = ivy_trace.check_final_cond(ag, post, clauses, [], True)

            text = '(1) ' + str(conj.to_formula()) + '\n(2) ' + str(
                target_conj.to_formula())
            if res is not None:
                self.ui_parent.text_dialog(
                    '(1) does not imply (2) at the next time. View counterexample?',
                    text,
                    command_label='View',
                    command=lambda: self.ui_parent.add(res))
                return False
            else:
                self.ui_parent.text_dialog('(1) implies (2) at the next time:',
                                           text,
                                           on_cancel=None)
                return True
Пример #19
0
 def top_bottom(node):
     # TODO: change this to use the concrete post already there
     preds, action = arg_get_preds_action(node)
     assert action != "join"
     assert len(preds) == 1
     pred = preds[0]
     implied = implied_facts(forward_image(arg_get_fact(pred), action), [false_clauses()])
     if len(implied) == 1:
         node.clauses = false_clauses()
     else:
         node.clauses = true_clauses()
Пример #20
0
 def __init__(self,nodes):
     self.all_nodes = [GraphNode(n,f,s) for (n,f,s) in nodes]
     self.relations = []
     self.pred = None
     self.status = dict()
     self.solver = z3.Solver()
     self.solver.push()
     self.constraints = true_clauses()
     self.needs_recompute = False
     self.nodes = []
     self.edges = []
     self.enabled_relations = set()
Пример #21
0
 def propagate_and_conjectures(node):
     """
     Propagate clauses from predecessor
     """
     preds, action = arg_get_preds_action(node)
     assert action != "join"
     assert len(preds) == 1
     pred = preds[0]
     implied = implied_facts(forward_image(arg_get_fact(pred), action), list(_ivy_interp.conjs))
     node.clauses = true_clauses()
     for fact in implied:
         arg_add_facts(node, fact)
Пример #22
0
def arg_add_action_node(pre, action, abstractor=None):
    """
    Add a new node with an action edge from pre, and return it.
    """
    try:
        label = [k for k, v in _ivy_ag.actions.iteritems() if v == action][0]
    except IndexError:
        label = None
    node = _ivy_ag.execute(action, pre, abstractor, label)
    if abstractor is None:
        node.clauses = true_clauses()
    return node
Пример #23
0
 def __init__(self, nodes):
     self.all_nodes = [GraphNode(n, f, s) for (n, f, s) in nodes]
     self.relations = []
     self.pred = None
     self.status = dict()
     self.solver = z3.Solver()
     self.solver.push()
     self.constraints = true_clauses()
     self.needs_recompute = False
     self.nodes = []
     self.edges = []
     self.enabled_relations = set()
Пример #24
0
def arg_add_action_node(pre, action, abstractor=None):
    """
    Add a new node with an action edge from pre, and return it.
    """
    try:
        label = [k for k, v in _ivy_ag.actions.iteritems() if v == action][0]
    except IndexError:
        label = None
    node = _ivy_ag.execute(action, pre, abstractor, label)
    if abstractor is None:
        node.clauses = true_clauses()
    return node
Пример #25
0
    def get_update_axioms(self,updated,action):
#        print "get_update_axioms: {}, {}".format(map(str,updated),action)
        for x in updated:
            if x in self.dependencies.symbols:
                updated = updated + [y for y in self.defines.symbols if y not in updated]
                try:
                    precond,postcond = next(y for y in (p.match(action) for p in self.patterns.args) if y != None)
                except StopIteration:
                    raise IvyError(action,'No matching update axiom for ' + str(x))
                postcond = state_to_action((updated,postcond,precond))
#                print "update axioms: {}, {}, {}".format(map(str,postcond[0]),postcond[1],postcond[2])
                return (updated,postcond[1],precond)
        return (updated,true_clauses(),false_clauses())
Пример #26
0
 def get_update_axioms(self, updated, action):
     #        print "get_update_axioms: {}, {}".format(map(str,updated),action)
     for x in updated:
         if x in self.dependencies.symbols:
             updated = updated + [y for y in self.defines.symbols if y not in updated]
             try:
                 precond, postcond = next(y for y in (p.match(action) for p in self.patterns.args) if y != None)
             except StopIteration:
                 raise IvyError(action, "No matching update axiom for " + str(x))
             postcond = state_to_action((updated, postcond, precond))
             #                print "update axioms: {}, {}, {}".format(map(str,postcond[0]),postcond[1],postcond[2])
             return (updated, postcond[1], precond)
     return (updated, true_clauses(), false_clauses())
Пример #27
0
 def top_bottom(node):
     # TODO: change this to use the concrete post already there
     preds, action = arg_get_preds_action(node)
     assert action != 'join'
     assert len(preds) == 1
     pred = preds[0]
     implied = implied_facts(
         forward_image(arg_get_fact(pred), action),
         [false_clauses()],
     )
     if len(implied) == 1:
         node.clauses = false_clauses()
     else:
         node.clauses = true_clauses()
Пример #28
0
    def is_inductive(self, button=None):
        """
        Check if the active conjecture implies itself at the next step

        TODO: this has a lot in common with check_inductiveness and is_sufficient,
        should refactor common parts out
        """
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses
        from random import randrange

        with self.ui_parent.run_context():
            conj = self.get_selected_conjecture()
            target_conj = conj

            ag = self.parent.new_ag()

            pre = State()
            pre.clauses = and_clauses(conj, *self.parent.conjectures)

            action = im.module.actions['ext']
            post = ag.execute(action, pre, None, 'ext')
            post.clauses = ilu.true_clauses()

            assert target_conj.is_universal_first_order()
            used_names = frozenset(x.name for x in il.sig.symbols.values())

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

            clauses = dual_clauses(target_conj, witness)
            res = ag.bmc(post, clauses)

            text = '(1) ' + str(conj.to_formula())
            if res is not None:
                self.ui_parent.text_dialog(
                    '(1) is not relatively inductive. View counterexample?',
                    text,
                    command_label='View',
                    command=lambda: self.ui_parent.add(res))
                return False
            else:
                self.ui_parent.text_dialog('(1) is relatively inductive:',
                                           text,
                                           on_cancel=None)
                return True
Пример #29
0
    def recompute(self):
        if not self.needs_recompute:
##            print "skipped recompute"
            return
        self.needs_recompute = False
##        print "did recompute"
        self.solver.pop()
        self.solver.push()
        self.solver_clauses = true_clauses()
        self.get_solver_clauses()
        for n in self.all_nodes:
            self.check_node(n)
        self.nodes = [GraphNode(n.name,n.fmla,n.sort) for n in self.all_nodes if n.status != "false"]
        for r in self.relations:
            r.compute_edges(self.solver)
Пример #30
0
 def propagate(node):
     """
     Propagate clauses from predecessor
     """
     preds, action = arg_get_preds_action(node)
     assert action != 'join'
     assert len(preds) == 1
     pred = preds[0]
     implied = implied_facts(
         forward_image(arg_get_fact(pred), action),
         list(arg_get_conjuncts(pred)),
     )
     node.clauses = true_clauses()
     for fact in implied:
         arg_add_facts(node, fact)
Пример #31
0
 def propagate_and_conjectures(node):
     """
     Propagate clauses from predecessor
     """
     preds, action = arg_get_preds_action(node)
     assert action != 'join'
     assert len(preds) == 1
     pred = preds[0]
     implied = implied_facts(
         forward_image(arg_get_fact(pred), action),
         list(_ivy_interp.conjs),
     )
     node.clauses = true_clauses()
     for fact in implied:
         arg_add_facts(node, fact)
Пример #32
0
 def __init__(self,nodes,parent_state=None):
     self.parent_state = parent_state
     self.all_nodes = [GraphNode(n,f,s) for (n,f,s) in nodes]
     self.relations = []
     self.pred = None
     self.status = dict()
     self.solver = z3.Solver()
     self.solver.push()
     self.constraints = true_clauses()
     self.needs_recompute = False
     self.nodes = []
     self.edges = []
     self.enabled_relations = set()
     self.concept_domain = initial_concept_domain([s for n,f,s in nodes])
     self.widget = ConceptStateViewWidget()
     self.session = cis.ConceptInteractiveSession(self.concept_domain,And(),And(),widget=self.widget)
Пример #33
0
    def is_sufficient(self, button=None):
        """
        Check if the active conjecture is sufficient to imply the current
        CTI conjecture at the next step

        TODO: this has a lot in common with check_inductiveness,
        should refactor common parts out
        """
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses
        from random import randrange

        with self.ui_parent.run_context():

            conj = self.get_selected_conjecture()
            target_conj = self.parent.current_conjecture

            ag = self.parent.new_ag()

            pre = State()
            pre.clauses = and_clauses(conj, *self.parent.conjectures)

            action = im.module.actions['ext']
            post = ag.execute(action, pre, None, 'ext')
            post.clauses = ilu.true_clauses()

            assert target_conj.is_universal_first_order()
            used_names = frozenset(x.name for x in il.sig.symbols.values())
            def witness(v):
                c = lg.Const('@' + v.name, v.sort)
                assert c.name not in used_names
                return c
            clauses = dual_clauses(target_conj, witness)
            res = ag.bmc(post, clauses)

            text = '(1) ' + str(conj.to_formula()) + '\n(2) ' + str(target_conj.to_formula())
            if res is not None:
                self.ui_parent.text_dialog('(1) does not imply (2) at the next time. View counterexample?',
                                           text,command_label='View',command = lambda: self.ui_parent.add(res))
                return False
            else:
                self.ui_parent.text_dialog('(1) implies (2) at the next time:',text,on_cancel=None)
                return True
Пример #34
0
    def clear(self):

        # these fields represent all the module declarations

        self.all_relations = [] # this includes both base and derived relations in declaration order
        self.definitions = []  # TODO: these are actually "derived" relations
        self.labeled_axioms = []
        self.labeled_props = []
        self.labeled_inits = []
        self.init_cond = lu.true_clauses()
        self.relations = dict()  # TODO: this is redundant, remove
        self.functions = dict()  # TODO: this is redundant, remove
        self.updates = []
        self.schemata = dict()
        self.instantiations = []
        self.concept_spaces = []
        self.labeled_conjs = []  # conjectures
        self.hierarchy = defaultdict(set)
        self.actions = {}
        self.predicates = {}
        self.assertions = []
        self.mixins = defaultdict(list)
        self.public_actions = set()
        self.isolates = {}
        self.exports = []
        self.imports = []
        self.delegates = []
        self.public_actions = set() # hash of the exported actions
        self.progress = []  # list of progress properties
        self.rely = [] # list of rely relations
        self.mixord = [] # list of mixin order relations
        self.destructor_sorts = {}
        self.sort_destructors = defaultdict(list)
        self.privates = set() # set of string (names of private actions)
        self.interps = defaultdict(list) # maps type names to lists of labeled interpretions
        self.natives = [] # list of NativeDef
        self.initializers = [] # list of name,action pairs
        self.params = []
        self.ghost_sorts = set() # set of sort names
        self.native_types = {} # map from sort names to ivy_ast.NativeType
        self.sort_order = [] # list of sorts names in order declared
        self.symbol_order = [] # list of symbols in order declared
        self.aliases = {} # map from name to name

        self.sig = il.sig.copy() # capture the current signature
Пример #35
0
 def diagram(self):
     from ivy_solver import clauses_model_to_diagram, get_model_clauses
     from ivy_transrel import is_skolem, reverse_image
     if not self.have_cti:
         if self.check_inductiveness() or len(self.g.states) != 2:
             return
     conj = self.current_conjecture
     post = ilu.dual_clauses(conj) if conj != None else ilu.true_clauses()
     pre = self.g.states[0].clauses
     axioms = im.module.background_theory()
     rev = ilu.and_clauses(reverse_image(post,axioms,self.g.states[1].update), axioms)
     clauses = ilu.and_clauses(pre,rev)
     mod = get_model_clauses(clauses)
     assert mod != None
     diag = clauses_model_to_diagram(rev,is_skolem,model=mod)
     self.g.states[0].clauses = diag
     self.view_state(self.g.states[0], reset=True)
     self.show_used_relations(diag,both=True)
Пример #36
0
 def recompute(self):
     if not self.needs_recompute:
         ##            print "skipped recompute"
         return
     self.needs_recompute = False
     ##        print "did recompute"
     self.solver.pop()
     self.solver.push()
     self.solver_clauses = true_clauses()
     self.get_solver_clauses()
     for n in self.all_nodes:
         self.check_node(n)
     self.nodes = [
         GraphNode(n.name, n.fmla, n.sort) for n in self.all_nodes
         if n.status != "false"
     ]
     for r in self.relations:
         r.compute_edges(self.solver)
Пример #37
0
 def diagram(self):
     from ivy_solver import clauses_model_to_diagram, get_model_clauses
     from ivy_transrel import is_skolem, reverse_image
     if not self.have_cti:
         if self.check_inductiveness() or len(self.g.states) != 2:
             return
     conj = self.current_conjecture
     post = ilu.dual_clauses(conj) if conj != None else ilu.true_clauses()
     pre = self.g.states[0].clauses
     axioms = im.module.background_theory()
     rev = ilu.and_clauses(
         reverse_image(post, axioms, self.g.states[1].update), axioms)
     clauses = ilu.and_clauses(pre, rev)
     mod = get_model_clauses(clauses)
     assert mod != None
     diag = clauses_model_to_diagram(rev, is_skolem, model=mod)
     self.g.states[0].clauses = diag
     self.view_state(self.g.states[0], reset=True)
     self.show_used_relations(diag, both=True)
Пример #38
0
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
Пример #39
0
    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()
Пример #40
0
    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()
Пример #41
0
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)))]))
Пример #42
0
 def int_update(self,domain,pvars):
     return ([], true_clauses(), false_clauses())
Пример #43
0
def action_failure(action):
    assert isinstance(action,SemActionValue)
    upd,tr,pre = action.comps
    print "action_failure upd: {}".format([str(x) for x in upd])
    return type(action)(upd,pre,true_clauses())
Пример #44
0
def null_update():
    return SemActionValue([],true_clauses(),false_clauses())
Пример #45
0
 def get_update_axioms(self,updated,action):
     defines = self.defn.args[0].rep
     if defines not in updated and any(x in self.dependencies for x in updated):
         updated.append(defines)
     return (updated,true_clauses(),false_clauses())
Пример #46
0
def action_failure(action):
    upd,tr,pre = action
    return upd,pre,true_clauses()
Пример #47
0
 def get_update_axioms(self, updated, action):
     defines = self.defn.args[0].rep
     if defines not in updated and any(x in self.dependencies for x in updated):
         updated.append(defines)
     return (updated, true_clauses(), false_clauses())
def null_update():
    return ([], true_clauses(), false_clauses())
def action_failure(action):
    upd, tr, pre = action
    return upd, pre, true_clauses()
def top_state():
    return pure_state(true_clauses())
Пример #51
0
def null_update():
    return ([],true_clauses(),false_clauses())
Пример #52
0
def top_state():
    return pure_state(true_clauses())
Пример #53
0
    def check_inductiveness(self, button=None):
        import ivy_transrel
        from ivy_solver import get_small_model
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses
        from random import randrange
        
        with self.ui_parent.run_context():

            ag = self.new_ag()

            pre = State()
            pre.clauses = and_clauses(*self.conjectures)

            action = im.module.actions['ext']
            with EvalContext(check=False): # don't check safety
                post = ag.execute(action, pre, None, 'ext')
            post.clauses = ilu.true_clauses()

            to_test = list(self.conjectures) + [None]  # None = check safety

            while len(to_test) > 0:
                # choose randomly, so the user can get another result by
                # clicking again
                conj = to_test.pop(randrange(len(to_test)))
                assert conj == None or conj.is_universal_first_order()
                used_names = frozenset(x.name for x in il.sig.symbols.values())
                def witness(v):
                    c = lg.Const('@' + v.name, v.sort)
                    assert c.name not in used_names
                    return c

                # TODO: this is still a bit hacky, and without nice error reporting
                if self.relations_to_minimize.value == 'relations to minimize':
                    self.relations_to_minimize.value = ' '.join(sorted(
                        k for k, v in il.sig.symbols.iteritems()
                        if (type(v.sort) is lg.FunctionSort and
                            v.sort.range == lg.Boolean and
                            v.name not in self.transitive_relations and
                            '.' not in v.name
                        )
                    ))

                if conj == None: # check safety
                    clauses = ilu.true_clauses()
                    rels_to_min = [il.sig.symbols[x] for x in self.relations_to_minimize.value.split()]
                else:
                    clauses = dual_clauses(conj, witness)
                    history = ag.get_history(post)
                    rels_to_min = [
                        # TODO: this is still a bit hacky, and without nice error reporting
                        history.maps[0].get(relation, relation)
                        for x in self.relations_to_minimize.value.split()
                        for relation in [il.sig.symbols[x]]
                    ],

                _get_model_clauses = lambda clauses, final_cond=False: get_small_model(
                    clauses,
                    sorted(il.sig.sorts.values()),
                    rels_to_min,
                    final_cond = final_cond
                )

                if conj == None:
                    print "check safety"
                    res = ag.check_bounded_safety(post, _get_model_clauses)
                else:
                    res = ag.bmc(post, clauses, None, None, _get_model_clauses)

                if res is not None:
                    self.current_conjecture = conj
                    assert len(res.states) == 2
    #                self.set_states(res.states[0], res.states[1])
    #                self.cti = self.ui_parent.add(res)
                    self.g = res
                    self.rebuild()
                    self.view_state(self.g.states[0], reset=True)
                    self.show_used_relations(clauses)
                    #self.post_graph.selected = self.get_relevant_elements(self.post_state[2], clauses)
                    if conj == None:
                        self.ui_parent.ok_dialog('An assertion failed. A failing state is displayed. You can decompose\nthe failing action observe the failing execution. ')
                    else:
                        self.ui_parent.text_dialog('The following conjecture is not relatively inductive:',
                                                   str(conj.to_formula()),on_cancel=None)
                    self.have_cti = True
                    return False

    #        self.set_states(False, False)
            self.ui_parent.text_dialog('Inductive invariant found:',
                                       '\n'.join(str(conj) for conj in self.conjectures))
            self.have_cti = False
            return True
Пример #54
0
    def check_inductiveness(self, button=None):
        import ivy_transrel
        from ivy_solver import get_small_model
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses
        from random import randrange
        from ivy_art import AnalysisGraph

        with self.ui_parent.run_context():

            ag, succeed, fail = ivy_trace.make_check_art(
                precond=self.conjectures)

            to_test = [None] + list(self.conjectures)  # None = check safety

            while len(to_test) > 0:
                # choose randomly, so the user can get another result by
                # clicking again
                #                conj = to_test.pop(randrange(len(to_test)))
                conj = to_test.pop(0)
                assert conj == None or conj.is_universal_first_order()
                used_names = frozenset(x.name for x in il.sig.symbols.values())

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

                # TODO: this is still a bit hacky, and without nice error reporting
                if self.relations_to_minimize.value == 'relations to minimize':
                    self.relations_to_minimize.value = ' '.join(
                        sorted(k for k, v in il.sig.symbols.iteritems() if (
                            type(v.sort) is lg.FunctionSort
                            and v.sort.range == lg.Boolean
                            and v.name not in self.transitive_relations
                            #                            and '.' not in v.name
                        )))

                if conj == None:  # check safety
                    clauses = ilu.true_clauses()
                    post = fail
                else:
                    clauses = dual_clauses(conj, witness)
                    post = succeed
                history = ag.get_history(post)
                rels_to_min = []
                for x in self.relations_to_minimize.value.split():
                    relation = il.sig.symbols[x]
                    relation = history.maps[0].get(relation, relation)
                    rels_to_min.append(relation)

                clauses.annot = ia.EmptyAnnotation()
                res = ivy_trace.check_final_cond(ag, post, clauses,
                                                 rels_to_min, True)
                #                    res = ag.bmc(post, clauses, None, None, _get_model_clauses)

                if res is not None:
                    self.current_conjecture = conj
                    assert len(res.states) == 2
                    self.g = res
                    self.rebuild()
                    self.view_state(self.g.states[0], reset=True)
                    self.show_used_relations(clauses)
                    #self.post_graph.selected = self.get_relevant_elements(self.post_state[2], clauses)
                    if conj == None:
                        self.ui_parent.ok_dialog(
                            'An assertion failed. A failing state is displayed. You can step into\nthe failing action to observe the failing execution. '
                        )
                    else:
                        self.ui_parent.text_dialog(
                            'The following conjecture is not relatively inductive:',
                            str(il.drop_universals(conj.to_formula())),
                            on_cancel=None)
                    self.have_cti = True
                    return False

    #        self.set_states(False, False)
            self.ui_parent.text_dialog(
                'Inductive invariant found:',
                '\n'.join(str(conj) for conj in self.conjectures))
            self.have_cti = False
            return True
Пример #55
0
 def action_update(self, domain, pvars):
     type_check(domain, self.args[0])
     #        print type(self.args[0])
     cl = formula_to_clauses(dual_formula(self.args[0]))
     return ([], true_clauses(), cl)
Пример #56
0
 def action_update(self, domain, pvars):
     type_check(domain, self.args[0])
     #        print type(self.args[0])
     cl = formula_to_clauses(dual_formula(self.args[0]))
     return ([], true_clauses(), cl)