Esempio n. 1
0
 def flip(sym): return clingo.Function(
     sym.name, sym.arguments[:-1] + [clingo.Number(s - sym.arguments[-1].number)], sym.positive)
 ret = [flip(sym) for sym in ret]
Esempio n. 2
0
 def test_number(self):
     nc = noclingo.Number(1)
     c = clingo.Number(1)
     self.assertEqual(nc.number, c.number)
     self.assertEqual(str(nc), str(c))
     self.assertEqual(nc.type, noclingo.SymbolType.Number)
Esempio n. 3
0
def transform(inputs, callback):
    """
    Transforms the given list of temporal programs in string form into an ASP
    program.

    Returns the future predicates whose atoms have to be set to false if
    referring to the future, and program parts that have to be regrounded if
    there are constraints referring to the future.

    Arguments:
    inputs   -- The list of inputs.
    callback -- Callback for rewritten statements.
    """
    loc = _ast.Location(_ast.Position('<transform>', 1, 1),
                        _ast.Position('<transform>', 1, 1))
    future_predicates = set()
    constraint_parts = {}
    time = _ast.SymbolicTerm(loc, _clingo.Function(_tf.g_time_parameter_name))
    wrap_lit = lambda a: _ast.Literal(loc, _ast.Sign.NoSign, a)

    # apply transformer to program
    def append(s):
        if s is not None:
            callback(s)

    aux_rules = []
    transformer = _prg.ProgramTransformer(future_predicates, constraint_parts,
                                          aux_rules)
    for i in inputs:
        _ast.parse_string(i, lambda s: append(transformer.visit(s)))
    if aux_rules:
        callback(
            _ast.Program(loc, "always", [
                _ast.Id(loc, _tf.g_time_parameter_name),
                _ast.Id(loc, _tf.g_time_parameter_name_alt)
            ]))
        for rule in aux_rules:
            callback(rule)

    # add auxiliary rules for future predicates
    future_sigs = []
    if len(future_predicates) > 0:
        callback(
            _ast.Program(loc, "always", [
                _ast.Id(loc, _tf.g_time_parameter_name),
                _ast.Id(loc, _tf.g_time_parameter_name_alt)
            ]))
        for name, arity, positive, shift in sorted(future_predicates):
            variables = [
                _ast.Variable(loc, "{}{}".format(_tf.g_variable_prefix, i))
                for i in range(arity)
            ]
            s = _ast.SymbolicTerm(loc, _clingo.Number(shift))
            t_shifted = _ast.BinaryOperation(loc, _ast.BinaryOperator.Plus,
                                             time, s)
            add_sign = lambda lit: lit if positive else _ast.UnaryOperation(
                loc, _ast.UnaryOperator.Minus, lit)
            p_current = _ast.SymbolicAtom(
                add_sign(_ast.Function(loc, name, variables + [time], False)))
            f_current = _ast.SymbolicAtom(
                add_sign(
                    _ast.Function(loc, _tf.g_future_prefix + name,
                                  variables + [s, time], False)))
            callback(_ast.Rule(loc, wrap_lit(p_current),
                               [wrap_lit(f_current)]))
            future_sigs.append(
                (_tf.g_future_prefix + name, arity + 2, positive))

    # gather rules for constraints referring to the future
    reground_parts = []
    if len(constraint_parts) > 0:
        for (name, shift), rules in constraint_parts.items():
            assert (shift > 0)
            params = [
                _ast.Id(loc, _tf.g_time_parameter_name),
                _ast.Id(loc, _tf.g_time_parameter_name_alt)
            ]
            # parts to be regrounded
            part = "{}_0_{}".format(name, shift - 1)
            callback(_ast.Program(loc, part, params))
            for p, l in rules:
                callback(p)
            reground_parts.append((name, part, range(shift)))
            # parts that no longer have to be regrounded
            last_part = "{}_{}".format(name, shift)
            callback(_ast.Program(loc, last_part, params))
            for p, l in rules:
                callback(l)
            reground_parts.append((name, last_part, range(shift, shift + 1)))

    def add_part(part_name, atom_name, statement, wrap=lambda x: x):
        params = [
            _ast.Id(loc, _tf.g_time_parameter_name),
            _ast.Id(loc, _tf.g_time_parameter_name_alt)
        ]
        callback(_ast.Program(loc, part_name, params))
        atom = wrap(
            _ast.SymbolicAtom(_ast.Function(loc, atom_name, [time], False)))
        callback(statement(loc, atom, []))

    add_part('initial', '__initial', _ast.Rule, wrap_lit)
    add_part('always', '__final', _tf.External)

    reground_parts.append(('always', 'always', range(1)))
    reground_parts.append(('dynamic', 'dynamic', range(1)))
    reground_parts.append(('initial', 'initial', range(1)))

    def no_program(s):
        if s.ast_type != _ast.ASTType.Program:
            callback(s)

    _ast.parse_string(
        _dedent('''\
        #theory tel {
            formula_body  {
                &   : 7, unary;         % prefix for keywords
                -   : 7, unary;         % classical negation
                +   : 6, binary, left;  % arithmetic +
                -   : 6, binary, left;  % arithmetic -
                ~   : 5, unary;         % negation
                <   : 5, unary;         % previous
                <   : 5, binary, right; % n x previous
                <:  : 5, unary;         % weak previous
                <:  : 5, binary, right; % n x weak previous
                <?  : 5, unary;         % eventually-
                <*  : 5, unary;         % always-
                <<  : 5, unary;         % initially
                >   : 5, unary;         % next
                >   : 5, binary, right; % n x next
                >:  : 5, unary;         % weak next
                >:  : 5, binary, right; % n x weak next
                >?  : 5, unary;         % eventually+
                >*  : 5, unary;         % always+
                >>  : 5, unary;         % finally
                >*  : 4, binary, left;  % release
                >?  : 4, binary, left;  % until
                <*  : 4, binary, left;  % trigger
                <?  : 4, binary, left;  % since
                &   : 3, binary, left;  % and
                |   : 2, binary, left;  % or
                <-  : 1, binary, left;  % left implication
                ->  : 1, binary, left;  % right implication
                <>  : 1, binary, left;  % equivalence
                ;>  : 0, binary, right; % sequence next
                ;>: : 0, binary, right; % sequence weak next
                <;  : 0, binary, left;  % sequence previous
                <:; : 0, binary, left   % sequence weak previous
            };
            formula_head  {
                &   : 7, unary;         % prefix for keywords
                -   : 7, unary;         % classical negation
                +   : 6, binary, left;  % arithmetic +
                -   : 6, binary, left;  % arithmetic -
                ~   : 5, unary;         % negation
                >   : 5, unary;         % next
                >   : 5, binary, right; % n x next
                >:  : 5, unary;         % weak next
                >:  : 5, binary, right; % n x weak next
                >?  : 5, unary;         % eventually+
                >*  : 5, unary;         % always+
                >>  : 5, unary;         % finally
                >*  : 4, binary, left;  % release
                >?  : 4, binary, left;  % until
                &   : 3, binary, left;  % and
                |   : 2, binary, left;  % or
                ;>  : 0, binary, right; % sequence next
                ;>: : 0, binary, right  % sequence weak next
            };
            &tel/1 : formula_body, body;
            &__tel_head/1 : formula_body, head
        }.
        '''), no_program)

    _ast.parse_string(
        _dedent('''\
        #theory del {
            formula_body  {
                &   : 7, unary;         % prefix for keywords
                ?   : 4, unary;         % check
                *   : 3, unary;         % kleene star
                +   : 2, binary, left;  % choice
                ;;  : 1, binary, left;  % sequence
                .>? : 0, binary, right; % diamond (eventually)
                .>* : 0, binary, right  % box (always)
            };
            &del/1 : formula_body, body
        }.
        '''), no_program)

    return future_sigs, reground_parts
Esempio n. 4
0
def imain(prg,
          future_sigs,
          program_parts,
          on_model,
          imin=0,
          imax=None,
          istop="SAT"):
    """
    Take a program object and runs the incremental main solving loop.

    For each pair (name, arity) in future_sigs all atoms in the program base
    with the time parameter referring to the future are set to false. For
    example, given (p, 2) and atoms  p(x,1) in step 0, the atom would p(x,1)
    would be set to false via an assumption. In the following time steps, it
    would not be set to False.

    The list program_parts contains all program parts appearing in the program
    in form of triples (root, name, range) where root is either "initial" (time
    step 0), "always" (time steps >= 0), or "dynamic" (time steps > 0) and
    range is a list of integers for which the part has to be grounded
    backwards. Given range [0, 1] and root "always", at each iteration the
    program part would be grounded at horizon and horizon-1. The latter only if
    the horizon is greater than 0.

    Arguments:
    prg           -- Control object holding the program.
    future_sigs   -- Signatures of predicates whose future incarnations have to
                     be set to False.
    program_parts -- Program parts to ground.
    imin          -- Minimum number of iterations.
    imax          -- Maximum number of iterations.
    istop         -- When to stop.
    """
    f = _ty.Theory()
    step, ret = 0, None
    while ((imax is None or step < imax)
           and (step == 0 or step < imin or
                ((istop == "SAT" and not ret.satisfiable) or
                 (istop == "UNSAT" and not ret.unsatisfiable) or
                 (istop == "UNKNOWN" and not ret.unknown)))):
        parts = []
        for root_name, part_name, rng in program_parts:
            for i in rng:
                if ((step - i >= 0 and root_name == "always")
                        or (step - i > 0 and root_name == "dynamic")
                        or (step - i == 0 and root_name == "initial")):
                    parts.append(
                        (part_name,
                         [_clingo.Number(step - i),
                          _clingo.Number(step)]))
        if step > 0:
            prg.release_external(
                _clingo.Function("__final", [_clingo.Number(step - 1)]))
            prg.cleanup()
        prg.ground(parts)
        f.translate(step, prg)
        prg.assign_external(
            _clingo.Function("__final", [_clingo.Number(step)]), True)
        assumptions = []
        for name, arity, positive in future_sigs:
            for atom in prg.symbolic_atoms.by_signature(name, arity, positive):
                if atom.symbol.arguments[-1].number > step:
                    assumptions.append(-atom.literal)
        ret, step = prg.solve(on_model=lambda m: on_model(m, step),
                              assumptions=assumptions), step + 1
Esempio n. 5
0
 def test_clingo_noclingo_difference(self):
     self.assertNotEqual(clingo.String("blah"), noclingo.String("blah"))
     self.assertNotEqual(clingo.Number(5), noclingo.Number(5))
Esempio n. 6
0
 def visit_TelAtom(self, x, ctx, step):
     sym = _clingo.Function(x.name, x.arguments + [_clingo.Number(step)],
                            x.positive)
     atom = ctx.symbols[sym]
     if atom is not None:
         self.__head.append(atom.literal)
Esempio n. 7
0
    def main(self, prg, files):

        self.__theory.configure("propagate", "full,1")
        self.__theory.register(prg)
        if not files:
            files.append("-")
        for f in files:
            prg.load(f)

        #JobsNumber     = prg.get_const("numOfJobs").number
        #MachinesNumber = prg.get_const("numOfMachines").number
        numOfTimeWindows = 2
        i, ret = 0, None
        StaticProgramName = "solutionTimeWindow_"
        DynamicProgramName = ""
        TotalFacts = ""
        Lastbound = 0
        wait = True
        while (i <= numOfTimeWindows):
            print("Time Window", i)
            parts = []

            if i > 0:
                parts.append(("subproblem", [i]))
                if i > 1:
                    DynamicProgramName = StaticProgramName + str(i)
                    parts.append((DynamicProgramName, []))
                    prg.add(DynamicProgramName, [], TotalFacts)
            else:
                parts.append(("base", []))
            prg.cleanup()
            prg.ground(parts)
            self.__theory.prepare(prg)
            adjust = self.__theory.lookup_symbol(clingo.Number(0))

            bound = 0

            KillTheSearch = False
            go_out = False
            #startTime = time.time()
            while i > 0:
                #timer = threading.Timer(30.0, StopCurrentTW)
                prg.assign_external(Function("bound", [Lastbound - 1]), False)
                #print(bound)
                #print(Lastbound)
                #print("***********************")
                Lastbound = bound
                #currentTime = time.time()
                with prg.solve(on_model=self.__on_model,
                               on_statistics=self.__on_statistics,
                               yield_=True,
                               async_=True) as handle:
                    wait = handle.wait(60)
                    #if (handle.wait(0.000000000000000000000000000000000000011) != True):
                    #print("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR")
                    #break
                    #wait = handle.wait(60)
                    for model in handle:
                        #print(KillTheSearch)
                        #print(bound)
                        #print(Lastbound)
                        to_join = []
                        a = self.__theory.assignment(model.thread_id)

                        # *********** This is to loop on the current assignment to get the operations and starting time ***********
                        for name, value in a:
                            #sys.stdout.write("{} = {} ".format(name, value))
                            if (str(name) != "bound"):
                                FactsFormat = 'startTime({}, {}). '.format(
                                    name, value)
                                to_join.append(FactsFormat)

                            else:
                                bound = int(value)
                        # *********** This is to loop on the current assignment to get the operations and starting time ***********

                        TotalFacts = ''.join(to_join)
                        break

                    else:
                        sys.stdout.write("Optimum Found\n")
                        break
                    if self.__theory.has_value(model.thread_id, adjust):
                        sys.stdout.write("adjustment: {}\n".format(
                            self.__theory.get_value(model.thread_id, adjust)))
                prg.cleanup()
                prg.ground([("opt", [bound - 1])])
                prg.assign_external(Function("bound", [bound - 1]), True)
            else:
                ret = prg.solve()

            i = i + 1
        print(TotalFacts)
        print("Total Completion Time: {}".format(Lastbound))
Esempio n. 8
0
 def get_holds_function(self, term, y):
     return clingo.Function(self.holds_str, [term, clingo.Number(y)])
Esempio n. 9
0
 def to_symbol(self) -> clingo.Number:
     return clingo.Number(self.number)
Esempio n. 10
0
 def storeInteger(self, i: int):
     return ClingoID(self.ccontext, SymLit(clingo.Number(i), None))
Esempio n. 11
0
    def __get_param(self, name, arity, location, replace_future, fail_future, fail_past, max_shift):
        """
        Strips previous and next operators from function names
        and returns the updated name plus the time arguments to append.
        Furthermore, if the initially operator (_ prefix) is used, then the
        time parameter is replaced with 0. Otherwise, it is treated like a past
        operator.

        If replace_future is set this also introduces a new name for the
        predicate, which is recorded in the list of atoms that have to be made
        redefinable. In this case the name is prefixed with __future_. Such
        dynamic predicates are recorded in the future_predicates list.

        Arguments:
        name           -- The name of the predicate
                          (trailing primes denote previous operators).
        location       -- Location for generated terms.
        replace_future -- Whether atoms referring to the future have to be
                          replaced by a special future atom.
        fail_future    -- Fail if the atom refers to the future.
        fail_past      -- Fail if the atom refers to the past.
        max_shift      -- The maximum number of steps terms look into the
                          future.

        Example for body atoms:

            p(X) :- 'q(X)

        becomes

            p(X,t) :- q(X,t-1)

        Example for head atoms (replace_future=True):

            p''(X) :- q(X).

        becomes

            __future__p(X,2,t) :- q(X,t).

        and future_predicates is extended with (p,1,2) -> False
        """
        n = name.strip("'")
        shift = 0
        for c in name:
            if c == "'":
                shift -= 1
            else:
                break
        shift += len(name) - len(n) + shift

        initially = False
        if n.startswith("_") and not n.startswith("__"):
            n = n[1:]
            if n.startswith("'") or name.startswith("'") or name.endswith("'"):
                raise RuntimeError("initially operator cannot be used with primes: {}".format(_tf.str_location(location)))
            initially = True

        finally_ = False
        if n.endswith("_") and not n.endswith("__"):
            n = n[:-1]
            if n.endswith("'") or name.startswith("'") or name.endswith("'"):
                raise RuntimeError("finally operator cannot be used with primes: {}".format(_tf.str_location(location)))
            finally_ = True
            raise RuntimeError("finally operator not yet supported: {}".format(_tf.str_location(location)))

        if initially and finally_:
            raise RuntimeError("finally and initially operator cannot used together: {}".format(_tf.str_location(location)))
        params = [_ast.SymbolicTerm(location, _clingo.Function(_tf.g_time_parameter_name))]
        if fail_future and (shift > 0 or finally_):
            raise RuntimeError("future atoms not supported in this context: {}".format(_tf.str_location(location)))
        if fail_past and (shift < 0 or initially):
            raise RuntimeError("past atoms not supported in this context: {}".format(_tf.str_location(location)))
        if shift > 0:
            if replace_future:
                self.__future_predicates.add((n, arity, self.__positive, shift))
                n = _tf.g_future_prefix + n
                params.insert(0, _ast.SymbolicTerm(location, _clingo.Number(shift)))
            else:
                max_shift[0] = max(max_shift[0], shift)
        if shift != 0:
            params[-1] = _ast.BinaryOperation(location, _ast.BinaryOperator.Plus, params[-1], _ast.SymbolicTerm(location, _clingo.Number(shift)))
        elif initially:
            params[-1] = _ast.SymbolicTerm(location, _clingo.Number(0))
        return (n, params)
Esempio n. 12
0
 def get_unsat_function(self, term, y):
     return clingo.Function(self.unsat_str, [term, clingo.Number(y)])