예제 #1
0
 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, []))
예제 #2
0
    def visit_Program(self, prg):
        """
        Adds the time parameter to the given program given directive.

        Furthermore, the final program part is turned into an always program
        part and the __final flag set accordingly.
        """
        self.__final = prg.name == "final"
        if self.__final:
            prg.name = "always"
        if prg.name == "base":
            prg.name = "initial"
        prg.parameters.append(_ast.Id(prg.location, _tf.g_time_parameter_name))
        prg.parameters.append(_ast.Id(prg.location, _tf.g_time_parameter_name_alt))
        self.__part = prg.name
        return prg
예제 #3
0
 def visit_Program(self, prg):
     self.final = prg.name == "final"
     prg = copy(prg)
     if self.final:
         prg.name = "static"
     prg.parameters.append(ast.Id(prg.location, self.parameter.name))
     return prg
예제 #4
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 = {
        'begin': {
            'line': 1,
            'column': 1,
            'filename': '<transform>'
        },
        'end': {
            'line': 1,
            'column': 1,
            'filename': '<transform>'
        }
    }
    future_predicates = set()
    constraint_parts = {}
    time = _ast.Symbol(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:
        _clingo.parse_program(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.Symbol(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.type != _ast.ASTType.Program:
            callback(s)

    _clingo.parse_program(
        _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)

    _clingo.parse_program(
        _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