コード例 #1
0
ファイル: ivy_actions.py プロジェクト: e42s/ivy
def mk_variant_assign_clauses(lhs, rhs):
    n = lhs.rep
    new_n = new(n)
    args = lhs.args
    dlhs = new_n(*sym_placeholders(n))
    vs = dlhs.args
    eqs = [
        eq_atom(v, a) for (v, a) in zip(vs, args)
        if not isinstance(a, Variable)
    ]
    rn = dict((a.rep, v) for v, a in zip(vs, args) if isinstance(a, Variable))
    drhs = substitute_ast(rhs, rn)
    nondet = n.suffix("_nd").skolem()
    if eqs:
        nondet = Ite(And(*eqs), nondet, n(*dlhs.args))
    lsort, rsort = lhs.sort, rhs.sort
    fmlas = [
        Iff(
            pto(lsort, rsort)(dlhs, Variable('X', rsort)),
            Equals(Variable('X', rsort), drhs))
    ]
    for s in ivy_module.module.variants[lsort.name]:
        if s != rsort:
            fmlas.append(Not(pto(lsort, s)(dlhs, Variable('X', s))))
    new_clauses = Clauses(fmlas, [Definition(dlhs, nondet)])
    return new_clauses
コード例 #2
0
ファイル: ivy_graph.py プロジェクト: yotamfe/ivy
 def concept_label(self,concept):
     fmla = concept.formula
     if len(concept.variables) == 1:
         v = concept.variables[0]
         if can_abbreviate_formula(v,fmla):
             res = il.fmla_to_str_ambiguous(ilu.substitute_ast(fmla,{v.rep:Variable('',v.sort)}))
             return res.replace(' ','').replace('()','')
     return str(fmla)
コード例 #3
0
ファイル: ivy_actions.py プロジェクト: simudream/ivy
    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)

        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))

        new_n = new(n)
        args = lhs.args
        dlhs = new_n(*sym_placeholders(n))
        vs = dlhs.args
        eqs = [
            eq_atom(v, a) for (v, a) in zip(vs, args)
            if not isinstance(a, Variable)
        ]
        rn = dict(
            (a.rep, v) for v, a in zip(vs, args) if isinstance(a, Variable))
        drhs = substitute_ast(rhs, rn)
        if eqs:
            drhs = Ite(And(*eqs), drhs, n(*dlhs.args))
        new_clauses = Clauses([], [Definition(dlhs, drhs)])
        #        print "assign new_clauses = {}".format(new_clauses)
        return ([n], new_clauses, false_clauses())
コード例 #4
0
ファイル: ivy_graph.py プロジェクト: kleopatra999/ivy
 def concept_label(self, concept):
     fmla = concept.formula
     if len(concept.variables) == 1:
         v = concept.variables[0]
         if can_abbreviate_formula(v, fmla):
             res = il.fmla_to_str_ambiguous(
                 ilu.substitute_ast(fmla, {v.rep: Variable('', v.sort)}))
             return res.replace(' ', '').replace('()', '')
     return str(fmla)
コード例 #5
0
ファイル: ivy_to_cpp.py プロジェクト: xornand/ivy
def emit_derived(header, impl, df, classname):
    name = df.defines().name
    sort = df.defines().sort
    retval = il.Symbol("ret:val", sort)
    vs = df.args[0].args
    ps = [ilu.var_to_skolem('p:', v) for v in vs]
    mp = dict(zip(vs, ps))
    rhs = ilu.substitute_ast(df.args[1], mp)
    action = ia.AssignAction(retval, rhs)
    action.formal_params = ps
    action.formal_returns = [retval]
    emit_some_action(header, impl, name, action, classname)
コード例 #6
0
ファイル: ivy_to_cpp.py プロジェクト: jamella/ivy
def emit_derived(header,impl,df,classname):
    name = df.defines().name
    sort = df.defines().sort
    retval = il.Symbol("ret:val",sort)
    vs = df.args[0].args
    ps = [ilu.var_to_skolem('p:',v) for v in vs]
    mp = dict(zip(vs,ps))
    rhs = ilu.substitute_ast(df.args[1],mp)
    action = ia.AssignAction(retval,rhs)
    action.formal_params = ps
    action.formal_returns = [retval]
    emit_some_action(header,impl,name,action,classname)
コード例 #7
0
def mk_assign_clauses(lhs,rhs):
    n = lhs.rep
    new_n = new(n)
    args = lhs.args
    dlhs = new_n(*sym_placeholders(n))
    vs = dlhs.args
    eqs = [eq_atom(v,a) for (v,a) in zip(vs,args) if not isinstance(a,Variable)]
    rn = dict((a.rep,v) for v,a in zip(vs,args) if isinstance(a,Variable))
    drhs = substitute_ast(rhs,rn)
    if eqs:
        drhs = Ite(And(*eqs),drhs,n(*dlhs.args))
    new_clauses = Clauses([],[Definition(dlhs,drhs)])
    return new_clauses
コード例 #8
0
ファイル: ivy_actions.py プロジェクト: JJTRX/ivy
    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)

        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))

        new_n = new(n)
        args = lhs.args
        dlhs = new_n(*sym_placeholders(n))
        vs = dlhs.args
        eqs = [eq_atom(v, a) for (v, a) in zip(vs, args) if not isinstance(a, Variable)]
        rn = dict((a.rep, v) for v, a in zip(vs, args) if isinstance(a, Variable))
        drhs = substitute_ast(rhs, rn)
        if eqs:
            drhs = Ite(And(*eqs), drhs, n(*dlhs.args))
        new_clauses = Clauses([], [Definition(dlhs, drhs)])
        #        print "assign new_clauses = {}".format(new_clauses)
        return ([n], new_clauses, false_clauses())
コード例 #9
0
ファイル: ivy_proof.py プロジェクト: hannesm/ivy
    def property_tactic(self, decls, proof):
        cut = proof.args[0]
        goal = decls[0]
        subgoal = goal_subst(goal, cut, cut.lineno)
        lhs = proof.args[1]
        if not isinstance(lhs, ia.NoneAST):
            fmla = il.drop_universals(cut.formula)
            if not il.is_exists(fmla) or len(fmla.variables) != 1:
                raise IvyError(proof, 'property is not existential')
            evar = list(fmla.variables)[0]
            rng = evar.sort
            vmap = dict((x.name, x) for x in lu.variables_ast(fmla))
            used = set()
            args = lhs.args
            targs = []
            for a in args:
                if a.name in used:
                    raise IvyError(lhs, 'repeat parameter: {}'.format(a.name))
                used.add(a.name)
                if a.name in vmap:
                    v = vmap[a.name]
                    targs.append(v)
                    if not (il.is_topsort(a.sort) or a.sort != v.sort):
                        raise IvyError(lhs, 'bad sort for {}'.format(a.name))
                else:
                    if il.is_topsort(a.sort):
                        raise IvyError(
                            lhs, 'cannot infer sort for {}'.format(a.name))
                    targs.append(a)
            for x in vmap:
                if x not in used:
                    raise IvyError(
                        lhs, '{} must be a parameter of {}'.format(x, lhs.rep))
            dom = [x.sort for x in targs]
            sym = il.Symbol(lhs.rep, il.FuncConstSort(*(dom + [rng])))
            if sym in self.stale or sym in goal_defns(goal):
                raise iu.IvyError(lhs, '{} is not fresh'.format(sym))
            term = sym(*targs) if targs else sym
            fmla = lu.substitute_ast(fmla.body, {evar.name: term})
            cut = clone_goal(cut, [], fmla)
            goal = goal_add_prem(goal, ia.ConstantDecl(sym), goal.lineno)

        return [goal_add_prem(goal, cut, cut.lineno)] + decls[1:] + [subgoal]
コード例 #10
0
ファイル: ivy_proof.py プロジェクト: hannesm/ivy
def transform_defn_match(prob):
    """ Transform a problem of matching definitions to a problem of
    matching the right-hand sides. Requires prob.inst is a definition. """

    schema, conc, decl, freesyms = prob.schema, prob.pat, prob.inst, prob.freesyms
    if not (isinstance(decl, il.Definition)
            and isinstance(conc, il.Definition)):
        return prob
    declsym = decl.defines()
    concsym = conc.defines()
    # dmatch = match(conc.lhs(),decl.lhs(),freesyms)
    # if dmatch is None:
    #     print "left-hand sides didn't match: {}, {}".format(conc.lhs(),decl.lhs())
    #     return None
    declargs = decl.lhs().args
    concargs = conc.lhs().args
    if len(declargs) < len(concargs):
        return None
    declrhs = decl.rhs()
    concrhs = conc.rhs()
    vmap = dict((x.name, y.resort(x.sort)) for x, y in zip(concargs, declargs))
    concrhs = lu.substitute_ast(concrhs, vmap)
    dmatch = {concsym: declsym}
    for x, y in zip(func_sorts(concsym), func_sorts(declsym)):
        if x in freesyms:
            if x in dmatch and dmatch[x] != y:
                print "lhs sorts didn't match: {}, {}".format(x, y)
                return None
            dmatch[x] = y
        else:
            if x != y:
                print "lhs sorts didn't match: {}, {}".format(x, y)
                return None
    concrhs = apply_match(dmatch, concrhs)
    freesyms = apply_match_freesyms(dmatch, freesyms)
    freesyms = [x for x in freesyms if x not in concargs]
    constants = set(x for x in prob.constants if x not in declargs)
    vvmap = dict((x, y.resort(x.sort)) for x, y in zip(concargs, declargs))
    schema = apply_match_goal(vvmap, schema, apply_match_alt)
    schema = apply_match_goal(dmatch, schema, apply_match_alt)
    return MatchProblem(schema, concrhs, declrhs, freesyms, constants)
コード例 #11
0
ファイル: ivy_proof.py プロジェクト: yotamfe/ivy
def transform_defn_match(prob):
    """ Transform a problem of matching definitions to a problem of
    matching the right-hand sides. Requires prob.inst is a definition. """

    conc,decl,freesyms = prob.pat,prob.inst,prob.freesyms
    if not(isinstance(decl,il.Definition) and isinstance(conc,il.Definition)):
        return prob
    declsym = decl.defines()
    concsym = conc.defines()
    # dmatch = match(conc.lhs(),decl.lhs(),freesyms)
    # if dmatch is None:
    #     print "left-hand sides didn't match: {}, {}".format(conc.lhs(),decl.lhs())
    #     return None
    declargs = decl.lhs().args
    concargs = conc.lhs().args
    if len(declargs) < len(concargs):
        return None
    declrhs = decl.rhs()
    concrhs = conc.rhs()
    vmap = dict((x.name,y.resort(x.sort)) for x,y in zip(concargs,declargs))
    concrhs = lu.substitute_ast(concrhs,vmap)
    dmatch = {concsym:declsym}
    for x,y in zip(func_sorts(concsym),func_sorts(declsym)):
        if x in freesyms:
            if x in dmatch and dmatch[x] != y:
                print "lhs sorts didn't match: {}, {}".format(x,y)
                return None
            dmatch[x] = y
        else:
            if x != y:
                print "lhs sorts didn't match: {}, {}".format(x,y)
                return None
    concrhs = apply_match(dmatch,concrhs)
    freesyms = apply_match_freesyms(dmatch,freesyms)
    freesyms = [x for x in freesyms if x not in concargs]
    constants = set(x for x in prob.constants if x not in declargs)
    return MatchProblem(concrhs,declrhs,freesyms,constants)
コード例 #12
0
ファイル: ivy_to_cpp.py プロジェクト: xornand/ivy
def emit_tick(header, impl, classname):
    global indent_level
    indent_level += 1
    indent(header)
    header.append('void __tick(int timeout);\n')
    indent_level -= 1
    indent(impl)
    impl.append('void ' + classname + '::__tick(int __timeout){\n')
    indent_level += 1

    rely_map = defaultdict(list)
    for df in im.module.rely:
        key = df.args[0] if isinstance(df, il.Implies) else df
        rely_map[key.rep].append(df)

    for df in im.module.progress:
        vs = list(lu.free_variables(df.args[0]))
        open_loop(impl, vs)
        code = []
        indent(code)
        df.args[0].emit(impl, code)
        code.append(' = ')
        df.args[1].emit(impl, code)
        code.append(' ? 0 : ')
        df.args[0].emit(impl, code)
        code.append(' + 1;\n')
        impl.extend(code)
        close_loop(impl, vs)

    for df in im.module.progress:
        if any(not isinstance(r, il.Implies) for r in rely_map[df.defines()]):
            continue
        vs = list(lu.free_variables(df.args[0]))
        open_loop(impl, vs)
        maxt = new_temp(impl)
        indent(impl)
        impl.append(maxt + ' = 0;\n')
        for r in rely_map[df.defines()]:
            if not isinstance(r, il.Implies):
                continue
            rvs = list(lu.free_variables(r.args[0]))
            assert len(rvs) == len(vs)
            subs = dict(zip(rvs, vs))

            ## TRICKY: If there are any free variables on rhs of
            ## rely not occuring on left, we must prevent their capture
            ## by substitution

            xvs = set(lu.free_variables(r.args[1]))
            xvs = xvs - set(rvs)
            for xv in xvs:
                subs[xv.name] = xv.rename(xv.name + '__')
            xvs = [subs[xv.name] for xv in xvs]

            e = ilu.substitute_ast(r.args[1], subs)
            open_loop(impl, xvs)
            indent(impl)
            impl.append('{} = std::max({},'.format(maxt, maxt))
            e.emit(impl, impl)
            impl.append(');\n')
            close_loop(impl, xvs)
        indent(impl)
        impl.append('if (' + maxt + ' > __timeout)\n    ')
        indent(impl)
        df.args[0].emit(impl, impl)
        impl.append(' = 0;\n')
        indent(impl)
        impl.append('ivy_check_progress(')
        df.args[0].emit(impl, impl)
        impl.append(',{});\n'.format(maxt))
        close_loop(impl, vs)

    indent_level -= 1
    indent(impl)
    impl.append('}\n')
コード例 #13
0
def to_aiger(mod,ext_act):

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

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

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

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

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

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

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

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

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

    # axioms = mod.background_theory()

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

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

    # Propositionally abstract

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

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

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

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

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

    # step 4: instantiate the axioms using patterns

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#    aiger.sub.debug()

    # make a decoder for the abstract propositions

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

    cnsts = set(sym for syms in sort_constants.values() for sym in syms)
    return aiger,decoder,annot,cnsts,action,stvarset
コード例 #14
0
ファイル: ivy_to_cpp.py プロジェクト: jamella/ivy
def emit_tick(header,impl,classname):
    global indent_level
    indent_level += 1
    indent(header)
    header.append('void __tick(int timeout);\n')
    indent_level -= 1
    indent(impl)
    impl.append('void ' + classname + '::__tick(int __timeout){\n')
    indent_level += 1

    rely_map = defaultdict(list)
    for df in im.module.rely:
        key = df.args[0] if isinstance(df,il.Implies) else df
        rely_map[key.rep].append(df)

    for df in im.module.progress:
        vs = list(lu.free_variables(df.args[0]))
        open_loop(impl,vs)
        code = []
        indent(code)
        df.args[0].emit(impl,code)
        code.append(' = ')
        df.args[1].emit(impl,code)
        code.append(' ? 0 : ')
        df.args[0].emit(impl,code)
        code.append(' + 1;\n')
        impl.extend(code)
        close_loop(impl,vs)


    for df in im.module.progress:
        if any(not isinstance(r,il.Implies) for r in rely_map[df.defines()]):
            continue
        vs = list(lu.free_variables(df.args[0]))
        open_loop(impl,vs)
        maxt = new_temp(impl)
        indent(impl)
        impl.append(maxt + ' = 0;\n') 
        for r in rely_map[df.defines()]:
            if not isinstance(r,il.Implies):
                continue
            rvs = list(lu.free_variables(r.args[0]))
            assert len(rvs) == len(vs)
            subs = dict(zip(rvs,vs))

            ## TRICKY: If there are any free variables on rhs of
            ## rely not occuring on left, we must prevent their capture
            ## by substitution

            xvs = set(lu.free_variables(r.args[1]))
            xvs = xvs - set(rvs)
            for xv in xvs:
                subs[xv.name] = xv.rename(xv.name + '__')
            xvs = [subs[xv.name] for xv in xvs]
    
            e = ilu.substitute_ast(r.args[1],subs)
            open_loop(impl,xvs)
            indent(impl)
            impl.append('{} = std::max({},'.format(maxt,maxt))
            e.emit(impl,impl)
            impl.append(');\n')
            close_loop(impl,xvs)
        indent(impl)
        impl.append('if (' + maxt + ' > __timeout)\n    ')
        indent(impl)
        df.args[0].emit(impl,impl)
        impl.append(' = 0;\n')
        indent(impl)
        impl.append('ivy_check_progress(')
        df.args[0].emit(impl,impl)
        impl.append(',{});\n'.format(maxt))
        close_loop(impl,vs)

    indent_level -= 1
    indent(impl)
    impl.append('}\n')