Exemplo n.º 1
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())
Exemplo n.º 2
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())
Exemplo n.º 3
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())