コード例 #1
0
    def _poly_weight(variable, coefficients):
        monomials = []
        max_degree = len(coefficients) - 1

        for i, coefficient in enumerate(coefficients):
            exponent = max_degree - i
            if exponent > 0:
                monomial = Times(
                    [Real(coefficient),
                     Pow(variable, Real(exponent))])
            else:
                monomial = Real(coefficient)

            monomials.append(monomial)
        return Plus(monomials)
コード例 #2
0
    def _init_vars(self, t_init):
        t_vars = [Real(t_init)]
        x_vars = []
        loc_vars = []
        aux_vars = []

        for k in xrange(self.n_steps + 1):
            loc_k = []
            for l in xrange(len(self.locations)):
                var = PlanPRAiSE.LOC_NAME.format(k, l)
                loc_k.append(var)

            loc_vars.append(loc_k)

        for k in xrange(self.n_steps):
            x_vars.append(PlanPRAiSE.JOURNEY_NAME.format(k))
            prev = " + ".join(x_vars)
            tvar = "({} + {})".format(t_init, prev)
            t_vars.append(tvar)
            aux_k = []
            for p in xrange(len(self.partitions) - 1):

                if self.use_aux_vars:
                    avar = PlanPRAiSE.AUX_NAME.format(p, k)
                else:
                    last = (p == len(self.partitions) - 2)
                    partition = (self.partitions[p], self.partitions[p + 1])
                    avar = IntoInterval(t_vars[k], partition, last)

                aux_k.append(avar)

            aux_vars.append(aux_k)

        return t_vars, x_vars, loc_vars, aux_vars
コード例 #3
0
    def compile_knowledge(self, path, t_departure):
        """Generates the model according to the given path.

        Keyword arguments:
        path -- a path in the SRN graph
        t_departure -- departure time.

        """
        if len(path) <= 1:
            raise WMIRuntimeException("Path length should be > 1")

        self.n_steps = len(path) - 1
        t_vars, x_vars, aux_vars = self._init_vars(t_departure)
        variable_definitions = [RealVar(x) for x in x_vars]

        if self.use_aux_vars:
            variable_definitions += [
                BooleanVar(a) for ak in aux_vars for a in ak
            ]

        statements = []
        cond_weights = []

        # initialize t_0 (in WMI, this is passed as evidence)
        #time_equations.append(Equals(t_vars[0], str(t_departure)))

        for k in xrange(self.n_steps):

            # t^(k+1) = t^k + x^k
            #teq = Equals(t_vars[k+1], Plus([t_vars[k], x_vars[k]]))
            #time_equations.append(teq)

            src, dst = path[k], path[k + 1]

            # subformula encoding the transition from step k to step k+1
            trans_k = self._transition(k, src, dst, t_vars, x_vars, aux_vars)
            statements.append(trans_k)

            for p in xrange(len(self.partitions) - 1):
                poly_var = x_vars[k]
                coeffs = self.graph[src][dst][p]['coefficients']

                weight_f = SRNPRAiSE._poly_weight(poly_var, coeffs)
                cond_w = Ite(aux_vars[(p, k)], weight_f, Real(1))
                cond_weights.append(cond_w)

        if self.encoding[UNION_CONSTRAINTS]:
            # bound each t^k to fall into a partition
            union_interval = self.partitions[0], self.partitions[-1]
            union_constraints = [
                IntoInterval(t_vars[k], union_interval, True)
                for k in xrange(len(t_vars))
            ]
            statements = statements + union_constraints

        add_terminator = lambda s: s + ";"
        statements = map(add_terminator, statements + cond_weights)
        self.model = "\n".join(variable_definitions + statements)
        self.time_vars = t_vars
コード例 #4
0
    def _transition(self, step, src, dst, t_vars, x_vars, aux_vars):
        auxiliary_vars = []
        auxiliary_defs = []
        support_constraints = []

        for p in xrange(len(self.partitions) - 1):
            last = (p == len(self.partitions) - 2)
            aux = aux_vars[(p, step)]
            auxiliary_vars.append(aux)
            pt = (self.partitions[p], self.partitions[p + 1])

            if self.use_aux_vars:
                interval = IntoInterval(t_vars[step], pt, last)
                if self.encoding[AUX_IFF]:
                    aux_def = Iff(aux, interval)
                else:
                    aux_def = Implies(interval, aux)

                auxiliary_defs.append(aux_def)

            if self.encoding[THEORY_CHAINS] and not last:
                lb1 = LE(Real(pt[0]), t_vars[step])
                lb2 = LE(Real(pt[1]), t_vars[step])
                auxiliary_defs.append(Implies(lb2, lb1))

            # current time partition defines the range of the weight function
            # aux_p^k -> (R_p^min <= x^k <= R_p^max)
            rng = self.graph[src][dst][p]['range']
            support_constr = Implies(aux_vars[(p, step)],
                                     IntoInterval(x_vars[step], rng, True))
            support_constraints.append(support_constr)

        # bigwedge_p (aux_p^k <-> (P_p^begin <= t^k <= P_p^end))
        trans_formula = And(support_constraints)
        if len(auxiliary_defs) > 0:
            trans_formula = And([trans_formula, And(auxiliary_defs)])

        if self.use_aux_vars:
            if self.encoding[AUX_CONSTRAINTS] == 'xor':
                trans_formula = And(
                    [trans_formula, ExactlyOne(auxiliary_vars)])
            elif self.encoding[AUX_CONSTRAINTS] == 'or':
                trans_formula = And([trans_formula, Or(auxiliary_vars)])

        return trans_formula
コード例 #5
0
    def _compute_weights(self, subgraph, edges, aux_vars, loc_vars, x_vars):
        conditionals = []
        for i in xrange(self.n_steps):
            for src, dst in edges:
                l1 = self.locations.index(src)
                l2 = self.locations.index(dst)
                cond = And([loc_vars[i][l1], loc_vars[i + 1][l2]])
                subconditionals = []
                for p in xrange(len(self.partitions) - 1):
                    subcond = aux_vars[i][p]
                    poly_var = x_vars[i]
                    coeffs = subgraph[src][dst][p]['coefficients']
                    weight_f = PlanPRAiSE._poly_weight(poly_var, coeffs)
                    subconditionals.append(Ite(subcond, weight_f, Real(1)))

                conditional = Ite(cond, Times(subconditionals), Real(1))
                conditionals.append(conditional)

        return conditionals
コード例 #6
0
 def departing_at(self, time):
     return Equals(self.time_vars[0], Real(time))
コード例 #7
0
 def arriving_before(self, time, index=-1):
     return LE(self.time_vars[index], Real(time))
コード例 #8
0
 def arriving_after(self, time, index=-1):
     return Not(LE(self.time_vars[index], Real(time)))
コード例 #9
0
    def compile_knowledge(self, subgraph, n_steps, init_location,
                          final_location, t_departure):
        """Generates the model according to the path length, initial and final
        locations.

        Keyword arguments:
        subgraph -- subpart of the road network
        n_steps -- path length
        init_location -- str
        final_location -- str
        t_departure -- departure time

        """
        if n_steps < 1:
            raise WMIRuntimeException("Path length should be > 0")

        self.n_steps = n_steps
        self.locations = subgraph.nodes()

        t_vars, x_vars, loc_vars, aux_vars = self._init_vars(t_departure)
        variable_definitions = [RealVar(x) for x in x_vars] + \
                               [BooleanVar(l) for lk in loc_vars
                                for l in lk]

        if self.use_aux_vars:
            variable_definitions += [
                BooleanVar(a) for ak in aux_vars for a in ak
            ]

        subformulas = []

        for k in xrange(self.n_steps + 1):
            # exactly one location at each step
            subformulas.append(ExactlyOne(loc_vars[k]))

        relevant_edges = set()
        for k in xrange(self.n_steps):
            # each x^k should be nonnegative
            nonneg_x_k = LE(Real(0), x_vars[k])
            subformulas.append(nonneg_x_k)

            if self.use_aux_vars:
                if self.encoding[AUX_CONSTRAINTS] == 'xor':
                    subformulas.append(ExactlyOne(aux_vars[k]))
                elif self.encoding[AUX_CONSTRAINTS] == 'or':
                    subformulas.append(Or(aux_vars[k]))

            #step_xor = set()
            for l in xrange(len(self.locations)):
                src = self.locations[l]
                cond = loc_vars[k][l]
                subsubformulas = []

                for p in xrange(len(self.partitions) - 1):
                    nxt = self.conditional_plan[(src, p, final_location)]
                    if nxt in self.locations:
                        nxt_expr = loc_vars[k + 1][self.locations.index(nxt)]

                        if src != nxt:
                            relevant_edges.add((src, nxt))
                            rng = subgraph[src][nxt][p]['range']
                            rng_expr = IntoInterval(x_vars[k], rng, True)
                        else:
                            rng_expr = Equals(x_vars[k], Real(0))

                        ssf = Implies(aux_vars[k][p], And([rng_expr,
                                                           nxt_expr]))
                        subsubformulas.append(ssf)

                if len(subsubformulas) > 0:
                    subformulas.append(Implies(cond, And(subsubformulas)))

            for p in xrange(len(self.partitions) - 1):
                last = (p == len(self.partitions) - 2)
                partition = (self.partitions[p], self.partitions[p + 1])

                if self.use_aux_vars:
                    interval = IntoInterval(t_vars[k], partition, last)
                    if self.encoding[AUX_IFF]:
                        subformulas.append(Iff(aux_vars[k][p], interval))
                    else:
                        subformulas.append(Implies(interval, aux_vars[k][p]))

                if self.encoding[THEORY_CHAINS] and not last:
                    lb1 = LE(Real(partition[0]), t_vars[k])
                    lb2 = LE(Real(partition[1]), t_vars[k])
                    subformulas.append(Implies(lb2, lb1))

        # initialization
        subformulas.append(loc_vars[0][self.locations.index(init_location)])
        subformulas.append(
            loc_vars[self.n_steps][self.locations.index(final_location)])

        if self.encoding[UNION_CONSTRAINTS]:
            # bound each t^k to fall into a partition
            union_interval = self.partitions[0], self.partitions[-1]
            union_constraints = [
                IntoInterval(t_vars[k], union_interval, True)
                for k in xrange(len(t_vars))
            ]
            subformulas.append(And(union_constraints))

        cond_weights = self._compute_weights(subgraph, relevant_edges,
                                             aux_vars, loc_vars, x_vars)

        add_terminator = lambda s: s + ";"
        subformulas = map(add_terminator, subformulas + cond_weights)
        self.model = "\n".join(variable_definitions + subformulas)
        self.time_vars = t_vars
コード例 #10
0
 def arriving_before(self, time):
     return LE(self.time_vars[-1], Real(time))