Beispiel #1
0
 def bq(fmla):
     """ Bound the free variables in fmla of uninterpeted sort """
     vs = list(sorted(used_variables_ast(fmla)))
     vs = [v for v in vs if not ivy_logic.is_interpreted_sort(v.sort)]
     cnsts = [bdv(v) for v in vs]
     bq_res = ivy_logic.Implies(ivy_logic.And(*cnsts), fmla) if cnsts else fmla
     return bq_res
Beispiel #2
0
def map_fmla(fmla, strat_map):
    if il.is_binder(fmla):
        return map_fmla(fmla.body, strat_map)
    if il.is_variable(fmla):
        if fmla not in strat_map:
            res = UFNode()
            res.variables.add(fmla)
            strat_map[fmla] = res
        return strat_map[fmla]
    nodes = [map_fmla(f, strat_map) for f in fmla.args]
    if il.is_eq(fmla):
        unify(*nodes)
        if il.is_interpreted_sort(fmla.args[0].sort):
            unify(strat_map[(fmla.rep, 0)], nodes[0])
        return None
    if il.is_ite(fmla):
        unify(*nodes[1:])
        return nodes[1]
    if il.is_app(fmla):
        func = fmla.rep
        if func in symbols_over_universals or True:
            for idx, node in enumerate(nodes):
                if node is not None:
                    unify(strat_map[(func, idx)], node)
            return strat_map[func]
    return None
Beispiel #3
0
    def universes(self, numerals=False):
#        print "sorts: {!r}".format(self.sorts())
        if numerals:
            return dict((s,[c.rename(lambda s:str(i)) for i,c in enumerate(self.sorted_sort_universe(s))]
                           if not ivy_logic.is_interpreted_sort(s) else list(self.sort_universe(s)))
                        for s in self.sorts())
        return dict((s,[c.skolem() for c in self.sort_universe(s)]) for s in self.sorts())
Beispiel #4
0
def numeral_assign(clauses, h):
    num_by_sort = defaultdict(list)
    numerals = [c for c in used_constants_clauses(clauses) if c.is_numeral()]
    for num in numerals:
        num_by_sort[num.sort].append(num)
    #    print "num_by_sort: {}".format(numerals)
    foom = dict()
    used = set()
    #    print "starting: foom = {}".format(foom)
    for s in h.sorts():
        #        print "na sort: {}".format(repr(s))
        if ivy_logic.is_interpreted_sort(s):
            continue
        #        print "sort loop: sort = {}, foom = {}".format(s,foom)
        for num in num_by_sort[s]:
            #            print "foom = {}".format(foom)
            numv = h.eval_constant(num)
            #            print "eval: {}:{} = {}".format(num,num.sort,numv)
            if numv in foom:
                print "two numerals assigned same value!: {} = {}".format(num, foom[numv])
            else:
                #                print "assigning {} to {}".format(num,numv)
                foom[numv] = num
            used.add(num)
        i = 0
        for c in h.sorted_sort_universe(s):
            if c not in foom:
                while True:
                    num = ivy_logic.Constant(c.rep.rename(lambda s: str(i)))
                    i = i + 1
                    if num not in used:
                        foom[c.rep] = num
                        break
    return foom
Beispiel #5
0
def map_fmla(fmla,strat_map):
    if il.is_binder(fmla):
        return map_fmla(fmla.body,strat_map)
    if il.is_variable(fmla):
        if fmla not in strat_map:
            res = UFNode()
            res.variables.add(fmla)
            strat_map[fmla] = res
        return strat_map[fmla]
    nodes = [map_fmla(f,strat_map) for f in fmla.args]
    if il.is_eq(fmla):
        unify(*nodes)
        if il.is_interpreted_sort(fmla.args[0].sort):
            unify(strat_map[(fmla.rep,0)],nodes[0])
        return None
    if il.is_ite(fmla):
        unify(*nodes[1:])
        return nodes[1]
    if il.is_app(fmla):
        func = fmla.rep
        if func in symbols_over_universals or True:
            for idx,node in enumerate(nodes):
                if node is not None:
                    unify(strat_map[(func,idx)],node)
            return strat_map[func]
    return None
Beispiel #6
0
 def bq(fmla):
     """ Bound the free variables in fmla of uninterpeted sort """
     vs = list(sorted(used_variables_ast(fmla)))
     vs = [v for v in vs if not ivy_logic.is_interpreted_sort(v.sort)]
     cnsts = [bdv(v) for v in vs]
     bq_res = ivy_logic.Implies(ivy_logic.And(*cnsts),fmla) if cnsts else fmla
     return bq_res
Beispiel #7
0
def numeral_assign(clauses,h):
    num_by_sort = defaultdict(list)
    numerals = [c for c in used_constants_clauses(clauses) if c.is_numeral()]
    for num in numerals:
        num_by_sort[num.sort].append(num)
#    print "num_by_sort: {}".format(numerals)
    foom = dict()
    used = set()
#    print "starting: foom = {}".format(foom)
    for s in h.sorts():
#        print "na sort: {}".format(repr(s))
        if ivy_logic.is_interpreted_sort(s):
            continue
#        print "sort loop: sort = {}, foom = {}".format(s,foom)
        for num in num_by_sort[s]:
#            print "foom = {}".format(foom)
            numv = h.eval_constant(num)
#            print "eval: {}:{} = {}".format(num,num.sort,numv)
            if numv in foom:
                print "two numerals assigned same value!: {} = {}".format(num,foom[numv])
            else:
#                print "assigning {} to {}".format(num,numv)
                foom[numv] = num
            used.add(num)
        i = 0
        for c in h.sorted_sort_universe(s):
            if c not in foom:
                while True:
                    num = ivy_logic.Constant(c.rep.rename(lambda s:str(i)))
                    i = i + 1
                    if num not in used:
                        foom[c.rep] = num
                        break
    return foom
Beispiel #8
0
    def universes(self, numerals=False):
#        print "sorts: {!r}".format(self.sorts())
        if numerals:
            return dict((s,[c.rename(lambda s:str(i)) for i,c in enumerate(self.sorted_sort_universe(s))]
                           if not ivy_logic.is_interpreted_sort(s) else list(self.sort_universe(s)))
                        for s in self.sorts())
        return dict((s,[c.skolem() for c in self.sort_universe(s)]) for s in self.sorts())
Beispiel #9
0
def term_to_z3(term):
    if ivy_logic.is_boolean(term):
        return formula_to_z3_int(term)
    if not term.args:
        if isinstance(term, ivy_logic.Variable):
            sorted = hasattr(term, 'sort')
            sksym = term.rep + ':' + str(term.sort) if sorted else term.rep
            res = z3_constants.get(sksym)
            if res is not None: return res
            #            print str(term.sort)
            sig = lookup_native(term.sort, sorts, "sort") if sorted else S
            if sig == None:
                sig = term.sort.to_z3()


#            if sorted:
#                print type(term.sort)
#                print term.sort
#            print type(sksym)
#            print sksym
#            print sig
            res = z3.Const(sksym, sig)
            z3_constants[sksym] = res
            return res
        res = z3_constants.get(term.rep)
        if res is None:
            #            if isinstance(term.rep,str):
            #                print "{} : {}".format(term,term.rep)
            if term.is_numeral():
                res = numeral_to_z3(term.rep)
            elif ivy_logic.is_enumerated(
                    term) and ivy_logic.is_interpreted_sort(term.sort):
                res = enumerated_to_numeral(term)
            else:
                iso = term.rep.sort
                # TODO: this is dangerous
                sig = iso.to_z3() if iso is not None else S
                #                print "term: {}, iso : {}, sig = {}".format(term,iso,sig)
                res = z3.Const(term.rep.name, sig)
            z3_constants[term.rep] = res
    elif isinstance(term, ivy_logic.Ite):
        return z3.If(formula_to_z3_int(term.args[0]), term_to_z3(term.args[1]),
                     term_to_z3(term.args[2]))
    else:
        if not hasattr(term, 'rep'):
            print term
            print term.lineno
        fun = z3_functions.get(term.rep)
        if fun is None:
            fun = lookup_native(term.rep, functions, "function")
            if fun is None:
                sig = term.rep.sort.to_z3()
                fun = z3.Function(term.rep.name, *sig)
            z3_functions[term.rep] = fun
        args = [term_to_z3(arg) for arg in term.args]
        res = apply_z3_func(fun, args)
    return res
Beispiel #10
0
        def recur(expr):
            if isinstance(expr,il.Ite):
                cond = recur(expr.args[0])
                thenterm = recur(expr.args[1])
                elseterm = recur(expr.args[2])
                res = [self.sub.ite(cond[0],x,y) for x,y in zip(thenterm,elseterm)]
            elif il.is_app(expr):
                sym = expr.rep 
                if sym in il.sig.constructors:
                    m = sym.sort.defines().index(sym.name)
                    res = self.binenc(m,ceillog2(len(sym.sort.defines())))
                elif sym.is_numeral() and il.is_interpreted_sort(sym.sort):
                    n = get_encoding_bits(sym.sort)
                    res = self.binenc(int(sym.name),n)
                elif sym.name in self.ops and il.is_interpreted_sort(sym.sort.dom[0]):
                    args = map(recur,expr.args)
                    res = self.ops[sym.name](expr.args[0].sort,*args)
                else:
                    assert len(expr.args) == 0
                    try:
                        res = self.lit(sym)
                    except KeyError:
                        assert getdef is not None, "no definition for {} in aiger output".format(sym)
                        res = getdef(sym)
            else:
                args = map(recur,expr.args)
                if isinstance(expr,il.And):
                    res = self.andl(*args)
                elif isinstance(expr,il.Or):
                    res = self.orl(*args)
                elif isinstance(expr,il.Not):
                    res = self.notl(*args)
                elif isinstance(expr,il.Implies):
                    res = self.implies(*args)
                elif isinstance(expr,il.Iff):
                    res = self.iff(*args)
                elif il.is_eq(expr):
                    res = self.encode_equality(expr.args[0].sort,*args)
                else:
                    assert False,"unimplemented op in aiger output: {}".format(type(expr))
#            iu.dbg('expr')
#            iu.dbg('res')
            return res
Beispiel #11
0
def model_universe_facts(h, sort, upclose):
    if ivy_logic.is_interpreted_sort(sort):
        return []
    # get universe elements
    elems = h.sort_universe(sort)
    # constraint defining universe
    uc = []
    if not upclose:
        uc = [[ivy_logic._eq_lit(ivy_logic.Variable("X", c.sort), c) for c in elems]]
    # universe elements are distinct
    dc = [[ivy_logic._neq_lit(c1, c2)] for (c1, c2) in iu.distinct_unordered_pairs(elems)]
    return uc + dc
Beispiel #12
0
def model_universe_facts(h,sort,upclose):
    if ivy_logic.is_interpreted_sort(sort):
        return []
    # get universe elements
    elems = h.sort_universe(sort)
    # constraint defining universe
    uc = []
    if not upclose:
        uc = [[ivy_logic._eq_lit(ivy_logic.Variable('X',c.sort),c) for c in elems]]
    # universe elements are distinct
    dc = [[ivy_logic._neq_lit(c1,c2)]
          for (c1,c2) in iu.distinct_unordered_pairs(elems)]
    return uc+dc
Beispiel #13
0
def term_to_z3(term):
    if ivy_logic.is_boolean(term):
        return formula_to_z3_int(term)
    if not term.args:
        if isinstance(term, ivy_logic.Variable):
            sorted = hasattr(term, "sort")
            sksym = term.rep + ":" + str(term.sort) if sorted else term.rep
            res = z3_constants.get(sksym)
            if res is not None:
                return res
            #            print str(term.sort)
            sig = lookup_native(term.sort, sorts, "sort") if sorted else S
            if sig == None:
                sig = term.sort.to_z3()
            #            if sorted:
            #                print type(term.sort)
            #                print term.sort
            #            print type(sksym)
            #            print sksym
            #            print sig
            res = z3.Const(sksym, sig)
            z3_constants[sksym] = res
            return res
        res = z3_constants.get(term.rep)
        if res is None:
            #            if isinstance(term.rep,str):
            #                print "{} : {}".format(term,term.rep)
            if term.is_numeral():
                res = numeral_to_z3(term.rep)
            elif ivy_logic.is_enumerated(term) and ivy_logic.is_interpreted_sort(term.sort):
                res = enumerated_to_numeral(term)
            else:
                iso = term.rep.sort
                # TODO: this is dangerous
                sig = iso.to_z3() if iso != None else S
                #                print "term: {}, iso : {}, sig = {}".format(term,iso,sig)
                res = z3.Const(term.rep.name, sig)
            z3_constants[term.rep] = res
    elif isinstance(term, ivy_logic.Ite):
        return z3.If(formula_to_z3_int(term.args[0]), term_to_z3(term.args[1]), term_to_z3(term.args[2]))
    else:
        fun = z3_functions.get(term.rep)
        if fun is None:
            fun = lookup_native(term.rep, functions, "function")
            if fun is None:
                sig = term.rep.sort.to_z3()
                fun = z3.Function(term.rep.name, *sig)
            z3_functions[term.rep] = fun
        args = [term_to_z3(arg) for arg in term.args]
        res = apply_z3_func(fun, args)
    return res
Beispiel #14
0
def map_fmla(lineno, fmla, pol):
    """ Add all of the subterms of `fmla` to the stratification graph. """

    global universally_quantified_variables
    global macro_var_map
    global macro_dep_map
    global macro_map
    global macro_val_map
    global strat_map
    global arcs

    if il.is_binder(fmla):
        return map_fmla(lineno, fmla.body, pol)
    if il.is_variable(fmla):
        if fmla in universally_quantified_variables:
            if fmla not in strat_map:
                res = UFNode()
                strat_map[fmla] = res
            return strat_map[fmla], set()
        node, vs = macro_var_map.get(fmla,
                                     None), macro_dep_map.get(fmla, set())
        return node, vs
    reses = [
        map_fmla(lineno, f, il.polar(fmla, pos, pol))
        for pos, f in enumerate(fmla.args)
    ]
    nodes, uvs = iu.unzip_pairs(reses)
    all_uvs = iu.union_of_list(uvs)
    all_uvs.update(n for n in nodes if n is not None)
    if il.is_eq(fmla):
        if not il.is_interpreted_sort(fmla.args[0].sort):
            S_sigma = strat_map[il.Symbol('=', fmla.args[0])]
            for x, uv in zip(nodes, uvs):
                if x is not None:
                    unify(x, S_sigma)
                arcs.extend((v, S_sigma, fmla, lineno) for v in uv)
        else:
            check_interpreted(fmla, nodes, uvs, lineno, pol)
        return None, all_uvs
    if il.is_ite(fmla):
        # S_sigma = strat_map[il.Symbol('=',fmla.args[1])]
        # for x,uv in zip(nodes[1:],uvs[1:]):
        #     if x is not None:
        #         unify(x,S_sigma)
        #     arcs.extend((v,S_sigma,fmla,lineno) for v in uv)
        # TODO: treat ite as pseudo-macro: does this work?
        if nodes[1] and nodes[2]:
            unify(*nodes[1:])
        return nodes[1] or nodes[2], all_uvs
    if il.is_app(fmla):
        func = fmla.rep
        if not il.is_interpreted_symbol(func):
            if func in macro_value_map:
                return macro_value_map[func]
            if func in macro_map:
                defn, lf = macro_map[func]
                res = map_fmla(lf.lineno, defn.rhs(), None)
                macro_value_map[func] = res
                return res
            for idx, node in enumerate(nodes):
                anode = strat_map[(func, idx)]
                if node is not None:
                    unify(anode, node)
                arcs.extend((v, anode, fmla, lineno) for v in uvs[idx])
        else:
            check_interpreted(fmla, nodes, uvs, lineno, pol)
        return None, all_uvs
    return None, all_uvs