Ejemplo n.º 1
0
def compose_state_action(state,axioms,action, check=True):
    """ Compose a state and an action, returning a state """
#    print "state: {}".format(state)
#    print "action: {}".format(action)
    su,sc,sp = state
    au,ac,ap = action
    sc,sp = clausify(sc),clausify(sp)
    if check:
        pre_test = and_clauses(and_clauses(sc,ap),axioms)
        model = small_model_clauses(pre_test)
        if model != None:
            trans = extract_pre_post_model(pre_test,model,au)
            post_updated = [new(s) for s in au]
            pre_test = exist_quant(post_updated,pre_test)
            raise ActionFailed(pre_test,trans)
    if su != None:      # none means all moded
        ssu = set(su) # symbols already modified in state
        rn = dict((x,old(x)) for x in au if x not in ssu)
        sc = rename_clauses(sc,rn)
        ac = rename_clauses(ac,rn)
        su = list(su)
        union_to_list(su,au)
    img = forward_image(sc,axioms,action)
##    print "compose: {}".format((su,img,sp))
    return (su,img,sp)
Ejemplo n.º 2
0
    def add_constraints(self,cnstrs,recompute=True):
        g = self
        fc = [c for c in cnstrs if not g.state_implies_fmla(clause_to_formula(c))]
#        print "fc: %s" % fc
        if fc:
            g.set_state(and_clauses(g.state,Clauses(fc)),recompute)
            g.constraints = and_clauses(g.constraints,Clauses(cnstrs))
Ejemplo n.º 3
0
def join(s1,s2,relations,op):
    u1,c1,p1 = s1
    u2,c2,p2 = s2
    c1 = and_clauses(c1,diff_frame(u1,u2,relations,op))
    c2 = and_clauses(c2,diff_frame(u2,u1,relations,op))
    u = updated_join(u1,u2)
    c = or_clauses(c1,c2)
    p = or_clauses(p1,p2)
    return (u,c,p)
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    def satisfy(self, axioms, _get_model_clauses=None, final_cond=None):
        """ Produce a state sequence if the symbolic history contains
        one. Returns the sort universes and a sequence of states, or
        None if the history is vacuous. """

        if _get_model_clauses is None:
            _get_model_clauses = small_model_clauses

#        print "axioms: {}".format(axioms)

        # A model of the post-state embeds a valuation for each time
        # in the history.
#        print "concrete state: {}".format(self.post)
#        print "background: {}".format(axioms)
        post = and_clauses(self.post,axioms)
#        print "bounded check {"
        model = _get_model_clauses(post,final_cond=final_cond)
#        print "} bounded check"
        if model == None:
#            print "core = {}".format(unsat_core(post,true_clauses()))
            return None

        # we reconstruct the sub-model for each state composing the
        # recorded renamings in reverse order. Here "renaming" maps
        # symbols representing a past time onto current time skolems
        renaming,states,maps = {},[],reversed(self.maps)
        while True:
            # ignore all symbols except those representing the given past time
            img = set(renaming[s] for s in renaming if not s.is_skolem())
            ignore = lambda s: self.ignore(s,img,renaming)
            # get the sub-mode for the given past time as a formula
            
            if isinstance(final_cond,list):
                final_cond = or_clauses(*[fc.cond() for fc in final_cond])
            all_clauses = and_clauses(post,final_cond) if final_cond != None else post
            clauses = clauses_model_to_clauses(all_clauses,ignore = ignore, model = model, numerals=use_numerals())
            # map this formula into the past using inverse map
            clauses = rename_clauses(clauses,inverse_map(renaming))
            # remove tautology equalities, TODO: not sure if this is correct here
            clauses = Clauses(
                [f for f in clauses.fmlas if not is_tautology_equality(f)],
                clauses.defs
            )
            states.append(clauses)
            try:
                # update the inverse map by composing it with inverse
                # of the next renaming (in reverse order)
                renaming = compose_maps(next(maps),renaming)
            except StopIteration:
                break
        uvs = model.universes(numerals=use_numerals())
#        print "uvs: {}".format(uvs)
        return uvs, [pure_state(clauses) for clauses in reversed(states)]
Ejemplo n.º 6
0
def ite(cond,s1,s2,relations,op):
    u1,c1,p1 = s1
    u2,c2,p2 = s2
    df12 = diff_frame(u1,u2,relations,op)
    df21 = diff_frame(u2,u1,relations,op)
    c1 = and_clauses(c1,df12)
    c2 = and_clauses(c2,df21)
    p1 = and_clauses(p1,df12)
    p2 = and_clauses(p2,df21)
    u = updated_join(u1,u2)
    c = ite_clauses(cond,[c1,c2])
    p = ite_clauses(cond,[p1,p2])
    return (u,c,p)
Ejemplo n.º 7
0
def join(s1,s2):
    assert isinstance(s1,SemValue) and type(s1) is type(s2)
    op = s1.op
    u1,c1,p1 = s1.comps
    u2,c2,p2 = s2.comps
    df12 = diff_frame(u1,u2,op)
    df21 = diff_frame(u2,u1,op)
    c1 = and_clauses(c1,df12)
    c2 = and_clauses(c2,df21)
    p1 = and_clauses(p1,df12)
    p2 = and_clauses(p2,df21)
    u = updated_join(u1,u2)
    c = or_clauses(c1,c2)
    p = or_clauses(p1,p2)
    return type(s1)(u,c,p)
Ejemplo n.º 8
0
    def assume(self,clauses):
        """ Returns a new history in which the final state is constrainted to
        satisfy "clauses"."""
#        print "assume post: {}".format(self.post)
#        print "assume: {}".format(clauses)
        clauses = rename_distinct(clauses,self.post) # TODO: shouldn't be needed
        return History(pure_state(and_clauses(self.post,clauses)),self.maps)
Ejemplo n.º 9
0
def refuted_goal(goal):
    from z3_utils import z3_implies

    axioms = _ivy_interp.background_theory()
    premise = (and_clauses(axioms, goal.node.clauses)).to_formula()
    f = Not(goal.formula.to_formula())
    return z3_implies(premise, f)
Ejemplo n.º 10
0
def try_conjectures(s):
    axioms = _analysis_session.analysis_state.ivy_interp.background_theory()
    premise = (and_clauses(axioms, s.clauses)).to_formula()
    return [
        ('conj: {}'.format(conj), try_conjecture, conj)
        for conj in _analysis_session.analysis_state.ivy_interp.conjs
        if not z3_implies(premise, conj.to_formula())
    ]
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
def implies(s1,s2,axioms,relations,op):
    u1,c1,p1 = s1
    u2,c2,p2 = s2
    if u1 == None and u2 != None:
        return False
#    print "c1: {}".format(c1)
#    print "axioms: {}".format(axioms)
#    print "df: {}".format(diff_frame(u1,u2,relations,op))
    c1 = and_clauses(c1,axioms,diff_frame(u1,u2,relations,op))
    if isinstance(c2,Clauses):
        if not c2.is_universal_first_order() or not p2.is_universal_first_order():
            return False
        c2 = and_clauses(c2,diff_frame(u2,u1,relations,op))
        return clauses_imply(p1,p2) and clauses_imply(c1,c2)
    else:
        if not is_prenex_universal(c2) or not is_prenex_universal(p2):
            return False
        c2 = And(c2,clauses_to_formula(diff_frame(u2,u1,relations,op)))
        return clauses_imply_formula_cex(p1,p2) and clauses_imply_formula_cex(c1,c2)
Ejemplo n.º 13
0
def interpolant(clauses1,clauses2,axioms,interpreted):
#    print "interpolant clauses1={} clauses2={}".format(clauses1,clauses2)
#    print "axioms = {}".format(axioms)
    foo = and_clauses(clauses1,axioms)
    clauses2 = simplify_clauses(clauses2)
    core = unsat_core(clauses2,foo)
    if core == None:
        return None
#    print "core: %s" % core
    return core, interp_from_unsat_core(clauses2,foo,core,interpreted)
Ejemplo n.º 14
0
def implied_facts(premise, facts_to_check):
    """
    Return a list of facts from facts_to_check that are implied by
    theory
    """
    from z3_utils import z3_implies_batch
    axioms = _ivy_interp.background_theory()
    premise = normalize_quantifiers((and_clauses(axioms, premise)).to_formula())
    facts_to_check = [f.to_formula() if type(f) is Clauses else f for f in facts_to_check]
    result = z3_implies_batch(premise, facts_to_check, False)
    return [f for f, x in zip(facts_to_check, result) if x]
Ejemplo n.º 15
0
def condition_update_on_fmla(update,fmla,relations):
    """Given an update, return an update conditioned on fmla. Maybe an "else" would
    be useful too :-).
    """
    updated,if_clauses,if_pre = update
    else_clauses = update_frame_constraint(update,relations)
    if_clauses = condition_clauses(if_clauses,fmla)
    else_clauses = condition_clauses(else_clauses,Not(fmla))
##    print "if_clauses: %s" % if_clauses
##    print "else_clauses: %s" % else_clauses
    return updated,(and_clauses(if_clauses,else_clauses)),if_pre
Ejemplo n.º 16
0
def get_diagram(goal, weaken=False):
    axioms = _ivy_interp.background_theory()
    d = ivy_solver.clauses_model_to_diagram(
        and_clauses(goal.node.clauses, goal.formula),
        is_skolem,
        # None,
        false_clauses(),
        axioms=axioms,
        weaken=weaken,
    )
    return goal_at_arg_node(d, goal.node)
Ejemplo n.º 17
0
def condition_update_on_fmla(update,fmla):
    """Given an update, return an update conditioned on fmla. Maybe an "else" would
    be useful too :-).
    """
    assert isinstance(update,SemValue)
    updated,if_clauses,if_pre = update.comps
    else_clauses = update_frame_constraint(update)
    if_clauses = condition_clauses(if_clauses,fmla)
    else_clauses = condition_clauses(else_clauses,Not(fmla))
##    print "if_clauses: %s" % if_clauses
##    print "else_clauses: %s" % else_clauses
    return type(update)(updated,(and_clauses(if_clauses,else_clauses)),if_pre)
Ejemplo n.º 18
0
def compose_state_action(state,axioms,action, check=True):
    """ Compose a state and an action, returning a state """
#    print "state: {}".format(state)
#    print "action: {}".format(action)
    su,sc,sp = state
    au,ac,ap = action
    sc,sp = clausify(sc),clausify(sp)
    if check:
        pre_test = and_clauses(and_clauses(sc,ap),axioms)
        if clauses_sat(pre_test):
            raise ActionFailed(pre_test)
    if su != None:      # none means all moded
        ssu = set(su) # symbols already modified in state
        rn = dict((x,old(x)) for x in au if x not in ssu)
        sc = rename_clauses(sc,rn)
        ac = rename_clauses(ac,rn)
        su = list(su)
        union_to_list(su,au)
    img = forward_image(sc,axioms,action)
##    print "compose: {}".format((su,img,sp))
    return (su,img,sp)
Ejemplo n.º 19
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;
}
""")
Ejemplo n.º 20
0
def frame_update(update,in_scope,sig):
    """ Modify an update so all symbols in "in_scope" are on the
    update list, preserving semantics.
    """
    updated,clauses,pre = update
    moded = set(updated)
    dfns = []
    for sym in in_scope:
        if sym not in moded:
            updated.append(sym)
            dfns.append(frame_def(sym,new))
    return (updated,and_clauses(clauses,Clauses([],dfns)),pre)
Ejemplo n.º 21
0
    def enable_relation(self,relation):
        if relation.name() in self.enabled_relations:
            return
        self.enabled_relations.add(relation.name())
        if use_ivy_alpha:
            concepts = self.relation_concepts([relation])
#    #        print concepts
            self.post.concept_spaces += concepts
            clauses = self.compile_concepts(concepts)
#    #        print clauses
            s_add(self.solver,clauses_to_z3(clauses))
            self.solver_clauses = and_clauses(self.solver.clauses,clauses)
Ejemplo n.º 22
0
def compose_updates(update1,axioms,update2):
    updated1, clauses1, pre1 = update1
    updated2, clauses2, pre2 = update2
    clauses2 = rename_distinct(clauses2,clauses1)
    pre2 = rename_distinct(pre2,clauses1)
#    print "clauses2 = {}".format(clauses2)
    us1 = set(updated1)
    us2 = set(updated2)
    mid = us1.intersection(us2)
    mid_ax = clauses_using_symbols(mid,axioms)
    used = used_symbols_clauses(and_clauses(clauses1,clauses2))
    rn = UniqueRenamer('__m_',used)
    map1 = dict()
    map2 = dict()
    for v in updated1:
        map2[v] = new(v)
    for mv in mid:
        mvf = rename(mv,rn)
        map1[new(mv)] = mvf
        map2[mv] = mvf
    clauses1 = rename_clauses(clauses1,map1)
    new_clauses = and_clauses(clauses1, rename_clauses(and_clauses(clauses2,mid_ax),map2))
    new_updated = list(us1.union(us2))
#    print "pre1 before = {}".format(pre1)
    pre1 = and_clauses(pre1,diff_frame(updated1,updated2,None,new))  # keep track of post-state of assertion failure
#    print "pre1 = {}".format(pre1)
    new_pre = or_clauses(pre1,and_clauses(clauses1,rename_clauses(and_clauses(pre2,mid_ax),map2)))
#    print "new_pre = {}".format(new_pre)
    return (new_updated,new_clauses,new_pre)
Ejemplo n.º 23
0
def implies(s1,s2):
    assert isinstance(s1,SemValue) and type(s1) is type(s2)
    op = s1.op
    axioms = im.background_theory()
    u1,c1,p1 = s1.comps
    u2,c2,p2 = s2.comps
    if u1 == None and u2 != None:
        return False
#    print "c1: {}".format(c1)
#    print "axioms: {}".format(axioms)
#    print "df: {}".format(diff_frame(u1,u2,relations,op))
    c1 = and_clauses(c1,axioms,diff_frame(u1,u2,op))
    if isinstance(c2,Clauses):
        if not c2.is_universal_first_order() or not p2.is_universal_first_order():
            return False
        c2 = and_clauses(c2,diff_frame(u2,u1,op))
        return clauses_imply(p1,p2) and clauses_imply(c1,c2)
    else:
        if not is_prenex_universal(c2) or not is_prenex_universal(p2):
            return False
        c2 = And(c2,clauses_to_formula(diff_frame(u2,u1,op)))
        return clauses_imply_formula_cex(p1,p2) and clauses_imply_formula_cex(c1,c2)
Ejemplo n.º 24
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
Ejemplo n.º 25
0
 def int_update(self, domain, in_scope):
     (updated, clauses, pre) = self.action_update(domain, in_scope)
     # instantiate the update axioms
     for u in domain.updates:
         updated, transrel, precond = u.get_update_axioms(updated, self)
         # TODO: do something with the precondition
         #            if transrel:
         ##                print "updated: {}".format(updated)
         ##                print "update from axiom: %s" % transrel
         clauses = and_clauses(clauses, transrel)
         pre = or_clauses(pre, precond)
     ##        print "update clauses: %s" % clauses
     res = (updated, clauses, pre)
     return res
Ejemplo n.º 26
0
    def satisfy(self, axioms, _get_model_clauses=None):
        """ Produce a state sequence if the symbolic history contains
        one. Returns the sort universes and a sequence of states, or
        None if the history is vacuous. """

        if _get_model_clauses is None:
            _get_model_clauses = lambda cls: get_small_model(
                cls, ivy_logic.sig.sorts.values(), [])

        # A model of the post-state embeds a valuation for each time
        # in the history.
        post = and_clauses(self.post, axioms)
        #        print "post: {}".format(post)
        print "bounded check {"
        model = _get_model_clauses(post)
        print "} bounded check"
        if model == None:
            #            print "core = {}".format(unsat_core(post,true_clauses()))
            return None

        # we reconstruct the sub-model for each state composing the
        # recorded renamings in reverse order. Here "renaming" maps
        # symbols representing a past time onto current time skolems
        renaming, states, maps = {}, [], reversed(self.maps)
        while True:
            # ignore all symbols except those representing the given past time
            img = set(renaming[s] for s in renaming if not s.is_skolem())
            ignore = lambda s: self.ignore(s, img, renaming)
            # get the sub-mode for the given past time as a formula
            clauses = clauses_model_to_clauses(post,
                                               ignore=ignore,
                                               model=model,
                                               numerals=True)
            # map this formula into the past using inverse map
            clauses = rename_clauses(clauses, inverse_map(renaming))
            # remove tautology equalities, TODO: not sure if this is correct here
            clauses = Clauses(
                [f for f in clauses.fmlas if not is_tautology_equality(f)],
                clauses.defs)
            states.append(clauses)
            try:
                # update the inverse map by composing it with inverse
                # of the next renaming (in reverse order)
                renaming = compose_maps(next(maps), renaming)
            except StopIteration:
                break
        return model.universes(numerals=True), [
            pure_state(clauses) for clauses in reversed(states)
        ]
Ejemplo n.º 27
0
def samplePos(mod, candInv, coincide, actname):
    lcs = mod.labeled_conjs
    conjs = [Clauses([lc.formula]) for lc in lcs]
    fcs = [icheck.ConjChecker(c, invert=False) for c in lcs]
    negateci, negateCoincide = negate_clauses(candInv), negate_clauses(
        coincide)
    assert isinstance(negateci, Clauses) and isinstance(
        negateCoincide, Clauses), "negation causes type change"
    preclause = and_clauses(negateci, negateCoincide, *conjs)
    print "preclause: ", preclause
    print "not coincide: ", negateCoincide
    # print "<plearn> checking for action+ ", actname
    res = sampleUtil(mod, preclause, fcs, actname)
    a = raw_input('tried for pos sample')
    return res
Ejemplo n.º 28
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()
     uc = universe_constraint(self.g.states[0])
     axioms_uc = ilu.and_clauses(axioms, uc)
     #        rev = ilu.and_clauses(reverse_image(post,axioms,self.g.states[1].update), axioms)
     rev = reverse_image(post, axioms, self.g.states[1].update)
     clauses = ilu.and_clauses(ilu.and_clauses(pre, rev), axioms_uc)
     mod = get_model_clauses(clauses)
     assert mod != None
     diag = clauses_model_to_diagram(rev,
                                     is_skolem,
                                     model=mod,
                                     axioms=axioms)
     self.view_state(self.g.states[0], clauses=diag, reset=True)
     self.show_used_relations(diag, both=True)
     self.current_concept_graph.gather_facts()
Ejemplo n.º 29
0
    def int_update(self, domain, in_scope):
        (updated, clauses, pre) = self.action_update(domain, in_scope)
        # instantiate the update axioms
        for u in domain.updates:
            updated, transrel, precond = u.get_update_axioms(updated, self)
            # TODO: do something with the precondition
            #            if transrel:
            ##                print "updated: {}".format(updated)
            ##                print "update from axiom: %s" % transrel
            clauses = and_clauses(clauses, transrel)
            pre = or_clauses(pre, precond)


##        print "update clauses: %s" % clauses
        res = (updated, clauses, pre)
        return res
Ejemplo n.º 30
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)
    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
Ejemplo n.º 31
0
    def minimize_conjecture(self, button=None, bound=None):
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses, used_symbols_clauses, negate
        from ivy_solver import unsat_core
        from logic_util import free_variables, substitute

        if self.bmc_conjecture(bound=bound):
            # found a BMC counter-example
            return

        with self.ui_parent.run_context():
            step_action = im.module.actions['ext']

            n_steps = self.current_bound

            ag = self.parent.new_ag()
            with ag.context as ac:
                post = ac.new_state(ag.init_cond)
            if 'initialize' in im.module.actions:
                init_action = im.module.actions['initialize']
                post = ag.execute(init_action, None, None, 'initialize')
            for n in range(n_steps):
                post = ag.execute(step_action, None, None, 'ext')
            axioms = im.module.background_theory()
            post_clauses = and_clauses(post.clauses, axioms)

            used_names = (frozenset(x.name for x in il.sig.symbols.values())
                          | frozenset(
                              x.name
                              for x in used_symbols_clauses(post_clauses)))
            facts = self.get_active_facts()
            assert not any(c.is_skolem() and c.name in used_names
                           for c in lu.used_constants(*facts))
            core = unsat_core(Clauses(facts), post_clauses)
            if core is None:
                core = Clauses([])  ## can happen if we are proving true
#            assert core is not None, "bmc_conjecture returned False but unsat core is None"
            core_formulas = frozenset(core.fmlas)
            self.set_facts([fact for fact in facts if fact in core_formulas])
            self.highlight_selected_facts()
            self.ui_parent.text_dialog(
                "BMC found the following possible conjecture:",
                str(self.get_selected_conjecture()))
Ejemplo n.º 32
0
    def minimize_conjecture(self, button=None, bound=None):
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses, used_symbols_clauses, negate
        from ivy_solver import unsat_core
        from logic_util import free_variables, substitute

        if self.bmc_conjecture(bound=bound):
            # found a BMC counter-example
            return

        with self.ui_parent.run_context():
            step_action = im.module.actions['ext']

            n_steps = self.current_bound

            ag = self.parent.new_ag()
            with ag.context as ac:
                post = ac.new_state(ag.init_cond)
            if 'initialize' in im.module.actions:
                init_action = im.module.actions['initialize']
                post = ag.execute(init_action, None, None, 'initialize')
            for n in range(n_steps):
                post = ag.execute(step_action, None, None, 'ext')
            axioms = im.module.background_theory()
            post_clauses = and_clauses(post.clauses, axioms)

            used_names = (
                frozenset(x.name for x in il.sig.symbols.values()) |
                frozenset(x.name for x in used_symbols_clauses(post_clauses))
            )
            facts = self.get_active_facts()
            assert not any(
                c.is_skolem() and c.name in used_names for c in lu.used_constants(*facts)
            )
            core = unsat_core(Clauses(facts), post_clauses)
            if core is None:
                core = Clauses([]) ## can happen if we are proving true
#            assert core is not None, "bmc_conjecture returned False but unsat core is None"
            core_formulas = frozenset(core.fmlas)
            self.set_facts([fact for fact in facts if fact in core_formulas])
            self.highlight_selected_facts()
            self.ui_parent.text_dialog("BMC found the following possible conjecture:",
                                       str(self.get_selected_conjecture()))
Ejemplo n.º 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
Ejemplo n.º 34
0
def compose_updates(update1, axioms, update2):
    updated1, clauses1, pre1 = update1
    updated2, clauses2, pre2 = update2
    clauses2 = rename_distinct(clauses2, clauses1)
    pre2 = rename_distinct(pre2, clauses1)
    #    print "clauses2 = {}".format(clauses2)
    us1 = set(updated1)
    us2 = set(updated2)
    mid = us1.intersection(us2)
    mid_ax = clauses_using_symbols(mid, axioms)
    used = used_symbols_clauses(and_clauses(clauses1, clauses2))
    used.update(symbols_clauses(pre1))
    used.update(symbols_clauses(pre2))
    rn = UniqueRenamer('__m_', used)
    map1 = dict()
    map2 = dict()
    for v in updated1:
        map2[v] = new(v)
    for mv in mid:
        mvf = rename(mv, rn)
        map1[new(mv)] = mvf
        map2[mv] = mvf


#    iu.dbg('clauses1')
#    iu.dbg('clauses1.annot')
    clauses1 = rename_clauses(clauses1, map1)
    annot_op = lambda x, y: x.compose(
        y) if x is not None and y is not None else None
    new_clauses = and_clauses(clauses1,
                              rename_clauses(and_clauses(clauses2, mid_ax),
                                             map2),
                              annot_op=annot_op)
    new_updated = list(us1.union(us2))
    #    print "pre1 before = {}".format(pre1)
    #    iu.dbg('pre1.annot')
    #    iu.dbg('pre1')
    pre1 = and_clauses(pre1, diff_frame(
        updated1, updated2, new,
        axioms))  # keep track of post-state of assertion failure
    #    print "pre1 = {}".format(pre1)
    temp = and_clauses(clauses1,
                       rename_clauses(and_clauses(pre2, mid_ax), map2),
                       annot_op=my_annot_op)
    #    iu.dbg('temp.annot')
    new_pre = or_clauses(pre1, temp)
    #    iu.dbg('new_pre.annot')
    #    print "new_pre = {}".format(new_pre)
    #    iu.dbg('new_clauses')
    #    iu.dbg('new_clauses.annot')
    return (new_updated, new_clauses, new_pre)
Ejemplo n.º 35
0
def check_final_cond(ag,
                     post,
                     final_cond,
                     rels_to_min=[],
                     shrink=False,
                     handler_class=None):
    history = ag.get_history(post)
    axioms = im.module.background_theory()
    clauses = history.post
    clauses = lut.and_clauses(clauses, axioms)
    assert all(x is not None for x in history.actions)
    # work around a bug in ivy_interp
    actions = [
        im.module.actions[a] if isinstance(a, str) else a
        for a in history.actions
    ]
    action = act.Sequence(*actions)
    return check_vc(clauses, action, final_cond, rels_to_min, shrink,
                    handler_class)
Ejemplo n.º 36
0
    def get_solver_clauses(self):
#        expr = self.state_as_z3_expr
        if use_ivy_alpha:
            d = ProgressiveDomain(verbose=True)
            self.post = d
            sorts = sorted(set(n.sort for n in self.all_nodes))
            concepts = []
            for s in sorts:
                nconcepts = [n.to_concept_space() for n in self.all_nodes]
                nconcepts.append((node_concept(s,'X').atom, SumSpace([NamedSpace(Literal(1,x)) for x,y in nconcepts])))
                nconcepts.append((xtra_concept(s,'X','Y').atom,SumSpace([x for n in self.all_nodes for x in n.extra_concepts()])))
                concepts += nconcepts
            concepts = concepts + self.relation_concepts([r for r in self.relations if r.name() in self.enabled_relations])
            d.concept_spaces = concepts
#    #        print "concepts: %s" % concepts
            d.post_init(self.state,[],{},[])
            clauses = self.compile_concepts(concepts)
#    #        print "clauses: %s" % clauses
        else:
            clauses = self.state
#        print "graph solver clauses = {}".format(clauses)
        s_add(self.solver,clauses_to_z3(clauses))
        self.solver_clauses = and_clauses(self.solver_clauses,clauses)
Ejemplo n.º 37
0
def check_vc(clauses,
             action,
             final_cond=None,
             rels_to_min=[],
             shrink=False,
             handler_class=None):
    model = slv.get_small_model(clauses,
                                lg.uninterpreted_sorts(),
                                rels_to_min,
                                final_cond=final_cond,
                                shrink=shrink)
    if model is not None:
        failed = ([] if final_cond is None else
                  [final_cond] if not isinstance(final_cond, list) else
                  [c.cond() for c in ffcs if c.failed])
        mclauses = lut.and_clauses(*([clauses] + failed))
        vocab = lut.used_symbols_clauses(mclauses)
        handler = (handler_class(mclauses, model, vocab) if handler_class
                   is not None else Trace(mclauses, model, vocab))
        act.match_annotation(action, clauses.annot, handler)
        handler.end()
        return handler
    return None
Ejemplo n.º 38
0
    def isValid(self):
        ''' Checks if the current instance is a valid samplePoint. 
			i.e. for negative sample it checks if the samplePoint satisfies negation of current invariant (fcs) in post state
			Assumptions : safety Condition and Candidate Inv and Coincide clause is Universally Quantified.
		'''
        global module, candInv, coincide
        if self.label == '0':  # nagative sample
            fcs = [icheck.ConjChecker(c)
                   for c in module.labeled_conjs]  # inverts the fmla
            fmlas = [
                fc.cond().fmlas for fc in fcs
            ]  # fc.cond().fmlas gives a list of ivy predicate logic object.
        else:  # positive sample
            # return True # It will cause repeatation of some positive samples, but it will not affect the correctness of algorithm
            # comment the above return stmt to check validity of positive samples
            negateci, negateCoincide = negate_clauses(candInv), negate_clauses(
                coincide)
            condition = and_clauses(negateci, negateCoincide)
            fmlas = [condition.fmlas]
            # assert len(fmlas) == 1, ""
        for fmla in fmlas:  # requires satisfying atleast one fmla, as they are in disjunction
            isfmlatrue = True
            for pred in fmla:
                ret = self.solveIvyfmla(pred)
                assert isinstance(
                    ret, logic.Const), "return value is not a Const object"
                assert isinstance(
                    ret.sort, BooleanSort), "return is not a boolean formla"
                assert ret.name in ["0", "1"
                                    ], "return value is not in correct format"
                # print "<plearn> pred: {} \t\t result: {}".format(pred, ret.name)
                if ret.name == "0":
                    isfmlatrue = False
                    break
            if isfmlatrue:
                return True
        return False
Ejemplo n.º 39
0
def compose_updates(update1,axioms,update2):
    updated1, clauses1, pre1 = update1
    updated2, clauses2, pre2 = update2
    clauses2 = rename_distinct(clauses2,clauses1)
    pre2 = rename_distinct(pre2,clauses1)
#    print "clauses2 = {}".format(clauses2)
    us1 = set(updated1)
    us2 = set(updated2)
    mid = us1.intersection(us2)
    mid_ax = clauses_using_symbols(mid,axioms)
    used = used_symbols_clauses(and_clauses(clauses1,clauses2))
    rn = UniqueRenamer('__m_',used)
    map1 = dict()
    map2 = dict()
    for v in updated1:
        map2[v] = new(v)
    for mv in mid:
        mvf = rename(mv,rn)
        map1[new(mv)] = mvf
        map2[mv] = mvf
#    iu.dbg('clauses1')
#    iu.dbg('clauses1.annot')
    clauses1 = rename_clauses(clauses1,map1)
    annot_op = lambda x,y: x.compose(y) if x is not None and y is not None else None
    new_clauses = and_clauses(clauses1, rename_clauses(and_clauses(clauses2,mid_ax),map2),annot_op=annot_op)
    new_updated = list(us1.union(us2))
#    print "pre1 before = {}".format(pre1)
#    iu.dbg('pre1.annot')
#    iu.dbg('pre1')
    pre1 = and_clauses(pre1,diff_frame(updated1,updated2,None,new))  # keep track of post-state of assertion failure
#    print "pre1 = {}".format(pre1)
    temp = and_clauses(clauses1,rename_clauses(and_clauses(pre2,mid_ax),map2),annot_op=my_annot_op)
#    iu.dbg('temp.annot')
    new_pre = or_clauses(pre1,temp)
#    iu.dbg('new_pre.annot')
#    print "new_pre = {}".format(new_pre)
#    iu.dbg('new_clauses')
#    iu.dbg('new_clauses.annot')
    return (new_updated,new_clauses,new_pre)
Ejemplo n.º 40
0
def compose_updates(update1, update2):
    assert isinstance(update1,
                      SemActionValue) and type(update1) is type(update2)
    axioms = im.background_theory()
    updated1, clauses1, pre1 = update1.comps
    updated2, clauses2, pre2 = update2.comps
    clauses2 = rename_distinct(clauses2, clauses1)
    pre2 = rename_distinct(pre2, clauses1)
    #    print "clauses2 = {}".format(clauses2)
    us1 = set(updated1)
    us2 = set(updated2)
    mid = us1.intersection(us2)
    mid_ax = clauses_using_symbols(mid, axioms)
    used = used_symbols_clauses(and_clauses(clauses1, clauses2))
    rn = UniqueRenamer('__m_', used)
    map1 = dict()
    map2 = dict()
    for v in updated1:
        map2[v] = new(v)
    for mv in mid:
        mvf = rename(mv, rn)
        map1[new(mv)] = mvf
        map2[mv] = mvf
    clauses1 = rename_clauses(clauses1, map1)
    new_clauses = and_clauses(
        clauses1, rename_clauses(and_clauses(clauses2, mid_ax), map2))
    new_updated = list(us1.union(us2))
    #    print "pre1 before = {}".format(pre1)
    pre1 = and_clauses(
        pre1, diff_frame(updated1, updated2,
                         new))  # keep track of post-state of assertion failure
    #    print "pre1 = {}".format(pre1)
    new_pre = or_clauses(
        pre1,
        and_clauses(clauses1, rename_clauses(and_clauses(pre2, mid_ax), map2)))
    #    print "new_pre = {}".format(new_pre)
    return SemActionValue(new_updated, new_clauses, new_pre)
Ejemplo n.º 41
0
    def action_update(self,domain,pvars):
        lhs,rhs = self.args
        n = lhs.rep

        # Handle the hierarchical case
        if n in domain.hierarchy:
            asgns = [postfix_atoms_ast(self,Atom(x,[])) for x in domain.hierarchy[n]]
            res = unzip_append([asgn.action_update(domain,pvars) for asgn in asgns])
            return res

        # If the lhs application is partial, make it total by adding parameters
        xtra = len(lhs.rep.sort.dom) - len(lhs.args)
        if xtra < 0:
            raise IvyError(self,"too many parameters in assignment to " + lhs.rep)
        if xtra > 0:
            extend = sym_placeholders(lhs.rep)[-xtra:]
            extend = variables_distinct_list_ast(extend,self)  # get unused variables
            lhs = add_parameters_ast(lhs,extend)
            # Assignment of individual to a boolean is a special case
            if is_individual_ast(rhs) and not is_individual_ast(lhs):
                rhs = eq_atom(extend[-1],add_parameters_ast(rhs,extend[0:-1]))
            else:
                rhs = add_parameters_ast(rhs,extend)

        lhs_vars = used_variables_ast(lhs)
        if any(v not in lhs_vars for v in used_variables_ast(rhs)):
            print self
            raise IvyError(self,"multiply assigned: {}".format(lhs.rep))

        type_check(domain,rhs)
        if is_individual_ast(lhs) != is_individual_ast(rhs):
#            print type(lhs.rep)
#            print str(lhs.rep)
#            print type(lhs.rep.sort)
#            print "lhs: %s: %s" % (lhs,type(lhs))
#            print "rhs: %s: %s" % (rhs,type(rhs))
            raise IvyError(self,"sort mismatch in assignment to {}".format(lhs.rep))

        # For a destructor assignment, we actually mutate the first argument

        if n.name in ivy_module.module.destructor_sorts:
            mut = lhs.args[0]
            rest = list(lhs.args[1:])
            mut_n = mut.rep
            nondet = mut_n.suffix("_nd").skolem()
            new_clauses = mk_assign_clauses(mut_n,nondet(*sym_placeholders(mut_n)))
            fmlas = []
            nondet_lhs = lhs.rep(*([nondet(*mut.args)]+rest))
            fmlas.append(equiv_ast(nondet_lhs,rhs))
            vs = sym_placeholders(n)
            dlhs = n(*([nondet(*mut.args)] + vs[1:]))
            drhs = n(*([mut] + vs[1:]))
            eqs = [eq_atom(v,a) for (v,a) in zip(vs,lhs.args)[1:] if not isinstance(a,Variable)]
            if eqs:
                fmlas.append(Or(And(*eqs),equiv_ast(dlhs,drhs)))
            for destr in ivy_module.module.sort_destructors[mut.sort.name]:
                if destr != n:
                    phs = sym_placeholders(destr)
                    a1 = [nondet(*mut.args)] + phs[1:]
                    a2 = [mut] + phs[1:]
                    fmlas.append(eq_atom(destr(*a1),destr(*a2)))
            new_clauses = and_clauses(new_clauses,Clauses(fmlas))
            return ([mut_n], new_clauses, false_clauses())

        new_clauses = mk_assign_clauses(lhs,rhs)
#        print "assign new_clauses = {}".format(new_clauses)
        return ([n], new_clauses, false_clauses())
Ejemplo n.º 42
0
def constrain_state(upd, fmla):
    assert isinstance(upd, SemStateValue)
    return SemStateValue(upd.modset,
                         and_clauses(upd.trans, formula_to_clauses(fmla)),
                         upd.fail)
Ejemplo n.º 43
0
def interactive_updr():
    frames = ta._ivy_ag.states
    if len(frames) != 1:
        raise InteractionError(
            "Interactive UPDR can only be started when the ARG " +
            "contains nothing but the initial state.")

    bad_states = negate_clauses(ta.get_safety_property())
    action = ta.get_big_action()
    ta._ivy_ag.actions[repr(action)] = action

    init_frame = last_frame = frames[0]

    # TODO: test conjecture in initial

    while True:

        # the property is true in all frames and all "clauses" are pushed
        # the goal stack is empty

        # check if we found an infuctive invariant
        for i in range(len(frames) - 1):
            if t.check_cover(frames[i + 1], frames[i]):
                ta.step(msg="Inductive invariant found at frame {}".format(i),
                        i=i)
                # return True

        # add new frame

        last_frame = ta.arg_add_action_node(last_frame, action, None)
        ta.push_goal(ta.goal_at_arg_node(bad_states, last_frame))
        ta.step(msg="Added new frame")

        # push facts to last frame
        t.recalculate_facts(last_frame,
                            ta.arg_get_conjuncts(ta.arg_get_pred(last_frame)))

        while True:
            current_goal = ta.top_goal()
            if current_goal is None:
                # goal stack is empty
                break

            if t.remove_if_refuted(current_goal):
                continue

            if current_goal.node == init_frame:
                # no invariant
                print "No Invariant!"
                # return False

            dg = ta.get_diagram(current_goal, False)
            options = OrderedDict()
            for c in simplify_clauses(dg.formula).conjuncts():
                options[str(c)] = c
            user_selection = (yield UserSelectMultiple(
                options=options,
                title="Generalize Diagram",
                prompt="Choose which literals to take as the refutation goal",
                default=options.values()))
            assert user_selection is not None
            ug = ta.goal_at_arg_node(Clauses(list(user_selection)),
                                     current_goal.node)
            ta.push_goal(ug)
            ta.step(msg='Pushed user selected goal', ug=ug)

            goal = ta.top_goal()
            preds, action = ta.arg_get_preds_action(goal.node)
            assert action != 'join'
            assert len(preds) == 1
            pred = preds[0]
            axioms = ta._ivy_interp.background_theory()
            theory = and_clauses(
                ivy_transrel.forward_image(pred.clauses, axioms,
                                           action.update(ta._ivy_interp,
                                                         None)), axioms)
            goal_clauses = simplify_clauses(goal.formula)
            assert len(goal_clauses.defs) == 0

            s = z3.Solver()
            s.add(clauses_to_z3(theory))
            s.add(clauses_to_z3(goal_clauses))
            is_sat = s.check()
            if is_sat == z3.sat:
                bi = ta.backward_image(goal.formula, action)
                x, y = False, ta.goal_at_arg_node(bi, pred)
            elif is_sat == z3.unsat:
                user_selection, user_is_sat = yield UserSelectCore(
                    theory=theory,
                    constrains=goal_clauses.fmlas,
                    title="Refinement",
                    prompt="Choose the literals to use",
                )
                assert user_is_sat is False
                core = Clauses(user_selection)
                x, y = True, ivy_transrel.interp_from_unsat_core(
                    goal_clauses, theory, core, None)
            else:
                assert False, is_sat

            t.custom_refine_or_reverse(goal, x, y, False)

        # propagate phase
        for i in range(1, len(frames)):
            facts_to_check = (set(ta.arg_get_conjuncts(frames[i - 1])) -
                              set(ta.arg_get_conjuncts(frames[i])))
            t.recalculate_facts(frames[i], list(facts_to_check))
def constrain_state(upd, fmla):
    return (upd[0], and_clauses(upd[1], formula_to_clauses(fmla)), upd[2])
def conjoin(clauses1, clauses2, annot_op=None):
    """ Conjoin clause sets, taking into account skolems """
    return and_clauses(clauses1,
                       rename_distinct(clauses2, clauses1),
                       annot_op=annot_op)
Ejemplo n.º 46
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
Ejemplo n.º 47
0
def arg_add_facts(node, *facts):
    """
    Add facts to arg node
    """
    for f in facts:
        node.clauses = and_clauses(node.clauses, f)
Ejemplo n.º 48
0
 def get_formula(self, clauses):
     cl = lut.and_clauses(clauses)
     f = cl.to_formula()
     return f
Ejemplo n.º 49
0
    def bmc_conjecture(self,
                       button=None,
                       bound=None,
                       conjecture=None,
                       verbose=False,
                       tell_unsat=True):
        import ivy_transrel
        import ivy_solver
        from proof import ProofGoal
        from ivy_logic_utils import Clauses, and_clauses, dual_clauses

        # get the bound, if not specified

        if bound is None:
            iv = self.current_bound if hasattr(self, 'current_bound') else None
            c = lambda b: self.bmc_conjecture(button=button,
                                              bound=b,
                                              conjecture=conjecture,
                                              verbose=verbose,
                                              tell_unsat=tell_unsat)
            self.ui_parent.int_dialog('Number of steps to check:',
                                      command=c,
                                      minval=0,
                                      initval=iv)
            return

        with self.ui_parent.run_context():

            step_action = ia.env_action(None)

            n_steps = bound
            self.current_bound = bound

            conj = conjecture
            if conj is None:
                conj = and_clauses(*self.conjectures)

            assert 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(conj, witness)

            ag = self.new_ag()
            with ag.context as ac:
                #                post = ac.new_state(ag.init_cond)
                ag.add_initial_state(ag.init_cond)
                post = ag.states[0]
            if 'initialize' in im.module.actions:
                print "got here"
                init_action = im.module.actions['initialize']
                post = ag.execute(init_action, None, None, 'initialize')

            for n in range(n_steps + 1):
                res = ivy_trace.check_final_cond(ag, post, clauses, [], True)
                #                res = ag.bmc(post, clauses)
                if verbose:
                    if res is None:
                        msg = 'BMC with bound {} did not find a counter-example to:\n{}'.format(
                            n,
                            str(conj.to_formula()),
                        )
                    else:
                        msg = 'BMC with bound {} found a counter-example to:\n{}'.format(
                            n,
                            str(conj.to_formula()),
                        )
                    print '\n' + msg + '\n'
                if res is not None:
                    #                ta.step()
                    cmd = lambda: self.ui_parent.add(
                        res, ui_class=ivy_ui.AnalysisGraphUI)
                    self.ui_parent.text_dialog(
                        'BMC with bound {} found a counter-example to:'.format(
                            n),
                        str(conj.to_formula()),
                        command=cmd,
                        command_label='View')
                    return True
                post = ag.execute(step_action)

            if tell_unsat:
                self.ui_parent.text_dialog(
                    'BMC with bound {} did not find a counter-example to:'.
                    format(n_steps),
                    str(conj.to_formula()),
                    on_cancel=None)

            return False
Ejemplo n.º 50
0
def add_post_axioms(update, axioms):
    map = dict((sym, new(sym)) for sym in update[0])
    syms = set(update[0])
    post_ax = clauses_using_symbols(syms, axioms)
    return (update[0], and_clauses(update[1], rename_clauses(post_ax,
                                                             map)), update[2])
Ejemplo n.º 51
0
def constrain_state(upd,fmla):
    return (upd[0],and_clauses(upd[1],formula_to_clauses(fmla)),upd[2])
Ejemplo n.º 52
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
Ejemplo n.º 53
0
def summarize_isolate(mod):

    global check_lineno
    check_lineno = act.checked_assert.get()
    if check_lineno == "":
        check_lineno = None
#    print 'check_lineno: {}'.format(check_lineno)
    check = not opt_summary.get()
    subgoalmap = dict((x.id,y) for x,y in im.module.subgoals)
    axioms = [m for m in mod.labeled_axioms if m.id not in subgoalmap]
    schema_instances = [m for m in mod.labeled_axioms if m.id in subgoalmap]
    if axioms:
        print "\n    The following properties are assumed as axioms:"
        for lf in axioms:
            print pretty_lf(lf)

    if mod.definitions:
        print "\n    The following definitions are used:"
        for lf in mod.definitions:
            print pretty_lf(lf)

    if mod.labeled_props or schema_instances:
        print "\n    The following properties are to be checked:"
        if check:
            for lf in schema_instances:
                print pretty_lf(lf) + " [proved by axiom schema]"
            ag = ivy_art.AnalysisGraph()
            pre = itp.State()
            props = [x for x in im.module.labeled_props if not x.temporal]
            fcs = ([(ConjAssumer if prop.id in subgoalmap else ConjChecker)(prop) for prop in props])
            check_fcs_in_state(mod,ag,pre,fcs)
        else:
            for lf in schema_instances + mod.labeled_props:
                print pretty_lf(lf)

    # after checking properties, make them axioms
    im.module.labeled_axioms.extend(im.module.labeled_props)
    im.module.update_theory()


    if mod.labeled_inits:
        print "\n    The following properties are assumed initially:"
        for lf in mod.labeled_inits:
            print pretty_lf(lf)
    if mod.labeled_conjs:
        print "\n    The inductive invariant consists of the following conjectures:"
        for lf in mod.labeled_conjs:
            print pretty_lf(lf)

    if mod.isolate_info.implementations:
        print "\n    The following action implementations are present:"
        for mixer,mixee,action in sorted(mod.isolate_info.implementations,key=lambda x: x[0]):
            print "        {}implementation of {}".format(pretty_lineno(action),mixee)

    if mod.isolate_info.monitors:
        print "\n    The following action monitors are present:"
        for mixer,mixee,action in sorted(mod.isolate_info.monitors,key=lambda x: x[0]):
            print "        {}monitor of {}".format(pretty_lineno(action),mixee)

    # if mod.actions:
    #     print "\n    The following actions are present:"
    #     for actname,action in sorted(mod.actions.iteritems()):
    #         print "        {}{}".format(pretty_lineno(action),actname)

    if mod.initializers:
        print "\n    The following initializers are present:"
        for actname,action in sorted(mod.initializers, key=lambda x: x[0]):
            print "        {}{}".format(pretty_lineno(action),actname)

    if mod.labeled_conjs:
        print "\n    Initialization must establish the invariant"
        if check:
            with itp.EvalContext(check=False):
                ag = ivy_art.AnalysisGraph(initializer=lambda x:None)
                check_conjs_in_state(mod,ag,ag.states[0])
        else:
            print ''

    if mod.initializers:
        print "\n    Any assertions in initializers must be checked",
        if check:
            ag = ivy_art.AnalysisGraph(initializer=lambda x:None)
            fail = itp.State(expr = itp.fail_expr(ag.states[0].expr))
            check_safety_in_state(mod,ag,fail)


    checked_actions = get_checked_actions()

    if checked_actions and mod.labeled_conjs:
        print "\n    The following set of external actions must preserve the invariant:"
        for actname in sorted(checked_actions):
            action = mod.actions[actname]
            print "        {}{}".format(pretty_lineno(action),actname)
            if check:
                ag = ivy_art.AnalysisGraph()
                pre = itp.State()
                pre.clauses = lut.and_clauses(*mod.conjs)
                with itp.EvalContext(check=False): # don't check safety
                    post = ag.execute(action, pre, None, actname)
                check_conjs_in_state(mod,ag,post,indent=12)
            else:
                print ''
            


    callgraph = defaultdict(list)
    for actname,action in mod.actions.iteritems():
        for called_name in action.iter_calls():
            callgraph[called_name].append(actname)

    some_assumps = False
    for actname,action in mod.actions.iteritems():
        assumptions = [sub for sub in action.iter_subactions()
                           if isinstance(sub,act.AssumeAction)]
        if assumptions:
            if not some_assumps:
                print "\n    The following program assertions are treated as assumptions:"
                some_assumps = True
            callers = callgraph[actname]
            if actname in mod.public_actions:
                callers.append("the environment")
            prettyname = actname[4:] if actname.startswith('ext:') else actname
            prettycallers = [c[4:] if c.startswith('ext:') else c for c in callers]
            print "        in action {} when called from {}:".format(prettyname,','.join(prettycallers))
            for sub in assumptions:
                print "            {}assumption".format(pretty_lineno(sub))

    tried = set()
    some_guarants = False
    for actname,action in mod.actions.iteritems():
        guarantees = [sub for sub in action.iter_subactions()
                          if isinstance(sub,(act.AssertAction,act.Ranking))]
        if check_lineno is not None:
            guarantees = [sub for sub in guarantees if sub.lineno == check_lineno]
        if guarantees:
            if not some_guarants:
                print "\n    The following program assertions are treated as guarantees:"
                some_guarants = True
            callers = callgraph[actname]
            if actname in mod.public_actions:
                callers.append("the environment")
            prettyname = actname[4:] if actname.startswith('ext:') else actname
            prettycallers = [c[4:] if c.startswith('ext:') else c for c in callers]
            print "        in action {} when called from {}:".format(prettyname,','.join(prettycallers))
            roots = set(iu.reachable([actname],lambda x: callgraph[x]))
            for sub in guarantees:
                print "            {}guarantee".format(pretty_lineno(sub)),
                if check and sub.lineno not in tried:
                    print_dots()
                    tried.add(sub.lineno)
                    old_checked_assert = act.checked_assert.get()
                    act.checked_assert.value = sub.lineno
                    some_failed = False
                    for root in checked_actions:
                        if root in roots:
                           ag = ivy_art.AnalysisGraph()
                           pre = itp.State()
                           pre.clauses = lut.and_clauses(*mod.conjs)
                           with itp.EvalContext(check=False):
                               post = ag.execute_action(root,prestate=pre)
                           fail = itp.State(expr = itp.fail_expr(post.expr))
                           if not check_safety_in_state(mod,ag,fail,report_pass=False):
                               some_failed = True
                               break
                    if not some_failed:
                        print 'PASS'
                    act.checked_assert.value = old_checked_assert
                else:
                    print ""
Ejemplo n.º 54
0
def refuted_goal(goal):
    from z3_utils import z3_implies
    axioms = _ivy_interp.background_theory()
    premise = (and_clauses(axioms, goal.node.clauses)).to_formula()
    f = Not(goal.formula.to_formula())
    return z3_implies(premise, f)
def try_conjectures(s):
    axioms = _analysis_session.analysis_state.ivy_interp.background_theory()
    premise = (and_clauses(axioms, s.clauses)).to_formula()
    return [('conj: {}'.format(conj), try_conjecture, conj)
            for conj in _analysis_session.analysis_state.ivy_interp.conjs
            if not z3_implies(premise, conj.to_formula())]
Ejemplo n.º 56
0
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