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
Exemplo n.º 2
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
Exemplo n.º 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)
    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
    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
Exemplo n.º 5
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) and not checked_action.get():
        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()
            clauses1 = lut.true_clauses(annot=act.EmptyAnnotation())
            pre = itp.State(value=clauses1)
            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)

    apply_conj_proofs(mod)

    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 and not checked_action.get():
        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 = act.env_action(actname)
            print "        {}{}".format(pretty_lineno(action), actname)
            if check:
                ag = ivy_art.AnalysisGraph()
                pre = itp.State()
                pre.clauses = get_conjs(mod)
                with itp.EvalContext(check=False):  # don't check safety
                    #                    post = ag.execute(action, pre, None, actname)
                    post = ag.execute(action, pre)
                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 any(r in roots and (r, sub.lineno) not in tried
                                 for r in checked_actions):
                    print_dots()
                    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:
                            tried.add((root, sub.lineno))
                            action = act.env_action(root)
                            ag = ivy_art.AnalysisGraph()
                            pre = itp.State()
                            pre.clauses = get_conjs(mod)
                            with itp.EvalContext(check=False):
                                post = ag.execute(action, 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 ""
Exemplo n.º 6
0
def get_conjs(mod):
    fmlas = [lf.formula for lf in mod.labeled_conjs if not lf.explicit]
    return lut.Clauses(fmlas, annot=act.EmptyAnnotation())
Exemplo n.º 7
0
def module_new_state(self, clauses):
    if isinstance(clauses, Clauses) and clauses.annot is None:
        clauses = Clauses(clauses.fmlas, clauses.defs,
                          ivy_actions.EmptyAnnotation())
    return State(self, clauses)