示例#1
0
 def check_node(self, n):
     x = var_to_skolem('__', Variable('X', n.sort)).suffix(str(n.sort))
     y = var_to_skolem('__', Variable('Y', n.sort)).suffix(str(n.sort))
     #        print "x.sort: {}",format(x.sort)
     self.solver.push()
     s = self.solver
     # if we have a witness we can show node is definite (present in all models)
     wit = get_witness(n)
     #        print "checking: {}".format(n.fmla)
     cube = substitute_clause(n.fmla, {'X': x})
     #        print "cube: {!r}".format(cube)
     #        print wit
     #        if wit != None:
     ##            print "wit: {}, wit.sort: {}, x.sort: {}".format(wit,wit.sort,x.sort)
     res = s_check_cube(s, cube,
                        (Atom(equals, [x, wit]) if wit != None else None))
     ##        print"check cube: %s = %s" % (cube,res)
     #        res = s_check_cube(s,substitute_clause(n.fmla,{'X':x}))
     #        print "status: {}".format(res)
     n.status = res
     s_add(s, cube_to_z3(substitute_clause(n.fmla, {'X': x})))
     s_add(s, cube_to_z3(substitute_clause(n.fmla, {'X': y})))
     s_add(s, cube_to_z3([Literal(0, Atom(equals, [x, y]))]))
     n.summary = s.check() != z3.unsat
     self.solver.pop()
示例#2
0
 def extra_concepts(self):
     tn = self.text_name()
     X, Y = self.variable('X'), self.variable('Y')
     c = [
         Literal(1, Atom(tn, [X])), ~eq_lit(X, Y),
         Literal(1, Atom(tn, [Y]))
     ]
     cs = [ProductSpace([NamedSpace(x) for x in c])]
     w = get_witness(self)
     if w:
         cls = [[~lit, eq_lit(X, w)] for lit in self.fmla]
         cs += [ProductSpace([NamedSpace(x) for x in c]) for c in cls]
     return cs
def update_frame_constraint(update, relations):
    """ Return a clause list constraining all updated symbols
    to keep their previous values """
    clauses = []
    for sym in update[0]:
        if sym in relations:
            arity = relations[sym]
            vs = [Variable("V{}".format(i)) for i in range(0, arity)]
            lit1 = Literal(1, Atom(sym, vs))
            lit2 = Literal(1, Atom(new(sym), vs))
            clauses += [[~lit1, lit2], [lit1, ~lit2]]
        else:
            clauses.append([eq_lit(Constant(sym), Constant(new(sym)))])
    return Clauses(clauses)
示例#4
0
 def action_update(self,domain,pvars):
     lhs = self.args[0]
     n = lhs.rep
     new_n = new(n)
     args = lhs.args
     vs = [Variable("X%d" % i,s) for i,s in enumerate(n.sort.dom)]
     eqs = [eq_atom(v,a) for (v,a) in zip(vs,args) if not isinstance(a,Variable)]
     if is_atom(lhs):
         clauses = And(*([Or(Not(Atom(new_n,vs)),Atom(n,vs),eq) for eq in eqs] +
                         [Or(Atom(new_n,vs),Not(Atom(n,vs)),eq) for eq in eqs]))
     elif is_individual_ast(lhs.rep):
         clauses = And(*[Or(eq_atom(type(lhs)(new_n,vs),type(lhs)(n,vs)),eq) for eq in eqs])
     else: # TODO: ???
         clauses = And()
     clauses = formula_to_clauses(clauses)
     return ([n], clauses, false_clauses())
示例#5
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)

        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())
示例#6
0
def rela_fact(polarity, relname, n1, n2):
    return ([~lit for lit in fmla1] + [
        ~lit
        for lit in substitute_clause(n2.fmla, {'X': Variable('Y', n2.sort)})
    ] + [
        Literal(
            polarity,
            Atom(relname, [Variable('X', n1.sort),
                           Variable('Y', n2.sort)]))
    ])
示例#7
0
 def get_predicates(self, clauses):
     #        print "get_predicates: {}".format(clauses)
     d = self.parent_state.domain
     sig = d.sig
     urs = [
         x for x in used_unary_relations_clauses(clauses)
         if not is_skolem(x)
     ]
     cs = [
         x for x in used_constants_clauses(clauses) if not is_skolem(x)
         and not has_enumerated_sort(sig, x) and not x.is_numeral()
     ]
     ufs = [
         x for x in used_unary_functions_clauses(clauses)
         if not is_skolem(x) and has_enumerated_sort(sig, x)
     ]
     nrs = [x for x, arity in d.relations.iteritems() if arity == 0]
     union_to_list(
         urs, [x for x, arity in d.relations.iteritems() if arity == 1])
     union_to_list(cs, [
         x for x, arity in d.functions.iteritems()
         if arity == 0 and not has_enumerated_sort(sig, x)
     ])
     union_to_list(ufs, [
         x for x, arity in d.functions.iteritems()
         if arity == 1 and has_enumerated_sort(sig, x)
     ])
     #        print "ufs: {}".format(ufs)
     ccs = [Constant(c) for c in cs]
     #        print "sorts: {}".format([(c,c.get_sort()) for c in ccs])
     return ([Literal(1, Atom(c, [])) for c in nrs] + [
         Literal(1, Atom(equals, [Variable("X", c.get_sort()), c]))
         for c in ccs
     ] + [Literal(1, Atom(r, [Variable("X", r.sort.dom[0])]))
          for r in urs] + [(App(f, Variable('X', f.sort.dom[0])), [
              Constant(Symbol(x, f.sort.rng)) for x in f.sort.rng.defines()
          ]) for f in ufs])
示例#8
0
 def action_update(self,domain,pvars):
     lit = self.args[0]
     n = lit.atom.relname
     new_n = new(n)
     args = lit.atom.args
     vs = sym_placeholders(n)
     eqs = [Atom(equals,[v,a]) for (v,a) in zip(vs,args) if not isinstance(a,Variable)]
     new_clauses = And(*([Or(sign(lit.polarity,Atom(new_n,vs)),sign(1-lit.polarity,Atom(n,vs))),
                          sign(lit.polarity,Atom(new_n,args))] +
                         [Or(*([sign(0,Atom(new_n,vs)),sign(1,Atom(n,vs))] + [eq])) for eq in eqs] +
                         [Or(*([sign(1,Atom(new_n,vs)),sign(0,Atom(n,vs))] + [eq])) for eq in eqs]))
     new_clauses = formula_to_clauses(new_clauses)
     return ([n], new_clauses, false_clauses())
示例#9
0
    def set_state(self, clauses, recomp=True):
        self.state = clauses
        self.solver_clauses = true_clauses()
        self.predicates = self.get_predicates(clauses)
        sig = self.parent_state.domain.sig
        ufs = [
            x for x, arity in self.parent_state.domain.functions.iteritems()
            if arity == 1 and not has_enumerated_sort(sig, x)
        ]
        if not hasattr(self, 'brels'):
            self.brels = ([
                self.make_rel_lit(r, ['X', 'Y'])
                for r, arity in self.parent_state.domain.all_relations
                if arity == 2
            ] + [
                Literal(
                    1,
                    Atom(equals, [
                        App(f, Variable('X', f.sort.dom[0])),
                        Variable('Y', f.sort.rng)
                    ])) for f in ufs
            ])
#        brels =  list(used_binary_relations_clauses(clauses))
#        brels = [r for r in brels if ((r != equals) and not r.startswith('__'))]
##        print "brels: %s" % brels
        self.relations = [GraphRelation(self, rel) for rel in self.brels]
        self.relations += [
            GraphRelationUnary(self, rel) for rel in self.predicates
            if not isinstance(rel, tuple) and used_variables_ast(rel)
        ]
        self.relations += [
            GraphFunctionUnary(self, Literal(1, rel[0]))
            for rel in self.predicates if isinstance(rel, tuple)
        ]
        self.needs_recompute = True
        if recomp:
            self.recompute()
示例#10
0
 def to_concept_space(self):
     return Atom(self.text_name(), [self.variable('X')]), ProductSpace(
         [NamedSpace(x) for x in self.fmla])
示例#11
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())
示例#12
0
def type_ast(domain,ast):
    if is_atom(ast) and ast.rep not in domain.relations and ast.rep != '=':
        return App(ast.rep,ast.args)
    if isinstance(ast,App) and ast.rep in domain.relations:
        return Atom(ast.rep,ast.args)
    return ast
示例#13
0
 def to_concept_space(self):
     rel_lit = self.rel_lit
     return Atom('__' + rel_lit.atom.rep, rel_lit.atom.args), SumSpace(
         [NamedSpace(rel_lit), NamedSpace(~rel_lit)])
示例#14
0
 def status_lit(self, status):
     return Literal(1, Atom(equals, [self.fmla, status]))
示例#15
0
 def make_rel_lit(self, rel, varnames):
     args = [Variable(v, t) for v, t in zip(varnames, rel.sort.dom)]
     return Literal(1, Atom(rel, args))
示例#16
0
def node_concept(sort, varname):
    return Literal(1, Atom('__node:' + sort, [Variable(varname, sort)]))
示例#17
0
def xtra_concept(sort, vn1, vn2):
    return Literal(
        1, Atom('__xtra:' + sort,
                [Variable(vn1, sort), Variable(vn2, sort)]))