Example #1
0
def test_delta():
    parser = LDLfParser()
    sa, sb, sc = "A", "B", "C"
    a, b, c = PLAtomic(sa), PLAtomic(sb), PLAtomic(sc)

    i_ = PLFalseInterpretation()
    i_a = PLInterpretation({sa})
    i_b = PLInterpretation({sb})
    i_ab = PLInterpretation({sa, sb})

    true = PLTrue()
    false = PLFalse()
    tt = LDLfLogicalTrue()
    ff = LDLfLogicalFalse()

    assert parser("<A>tt").delta(i_) == false
    assert parser("<A>tt").delta(i_a) == PLAtomic(tt)
    assert parser("<A>tt").delta(i_b) == false
    assert parser("<A>tt").delta(i_ab) == PLAtomic(tt)

    assert parser("[B]ff").delta(i_) == true
    assert parser("[B]ff").delta(i_a) == true
    assert parser("[B]ff").delta(i_b) == PLAtomic(ff)
    assert parser("[B]ff").delta(i_ab) == PLAtomic(ff)

    f = parser("!(<!(A<->B)+(B;A)*+(!last)?>[(true)*]end)")
    assert f.delta(i_) == f.to_nnf().delta(i_)
    assert f.delta(i_ab) == f.to_nnf().delta(i_ab)

    assert f.delta(i_, epsilon=True) == f.to_nnf().delta(i_, epsilon=True)
    assert f.delta(i_ab, epsilon=True) == f.to_nnf().delta(i_ab, epsilon=True)
    # with epsilon=True, the result is either PLTrue or PLFalse
    assert f.delta(i_, epsilon=True) in [PLTrue(), PLFalse()]
Example #2
0
def test_nnf():
    parser = PLParser()
    sa, sb = "A", "B"
    a, b = PLAtomic(sa), PLAtomic(sb)
    i_ = PLInterpretation(set())
    i_a = PLInterpretation({sa})
    i_b = PLInterpretation({sb})
    i_ab = PLInterpretation({sa, sb})

    not_a_and_b = parser("!(A&B)")
    nnf_not_a_and_b = parser("!A | !B")
    assert not_a_and_b.to_nnf() == nnf_not_a_and_b
    assert nnf_not_a_and_b == nnf_not_a_and_b.to_nnf()

    dup = parser("!(A | A)")
    nnf_dup = dup.to_nnf()
    assert nnf_dup == PLNot(a)

    material_implication = parser("!A | B <-> !(A & !B) <-> A->B")
    nnf_material_implication = parser(
        "((!A | B) & (!A | B) & (!A | B)) | ((A & !B) & (A & !B) & (A & !B))")
    nnf_m = material_implication.to_nnf()
    assert nnf_m == nnf_material_implication.to_nnf()

    assert nnf_m.truth(i_) == material_implication.truth(
        i_) == nnf_material_implication.truth(i_) == True
    assert nnf_m.truth(i_a) == material_implication.truth(
        i_a) == nnf_material_implication.truth(i_a) == True
    assert nnf_m.truth(i_b) == material_implication.truth(
        i_b) == nnf_material_implication.truth(i_b) == True
    assert nnf_m.truth(i_ab) == material_implication.truth(
        i_ab) == nnf_material_implication.truth(i_ab) == True
Example #3
0
    def setup_class(cls):
        cls.parser = LTLfParser()
        cls.a, cls.b, cls.c = "A", "B", "C"
        cls.alphabet_abc = {cls.a, cls.b, cls.c}

        cls.i_ = PLInterpretation(set())
        cls.i_a = PLInterpretation({cls.a})
        cls.i_b = PLInterpretation({cls.b})
        cls.i_ab = PLInterpretation({cls.a, cls.b})
Example #4
0
    def setup_class(cls):
        cls.sa, cls.sb = "a", "b"

        cls.i_ = PLInterpretation(set())
        cls.i_a = PLInterpretation({cls.sa})
        cls.i_b = PLInterpretation({cls.sb})
        cls.i_ab = PLInterpretation({cls.sa, cls.sb})

        cls.a, cls.b = PLAtomic(cls.sa), PLAtomic(cls.sb)
Example #5
0
    def __init__(self, dfaotf: DFAOTF, alphabet: Alphabet, reward, gamma=0.99):

        self.dfaotf = dfaotf
        self.alphabet = Alphabet(
            {PLInterpretation(set(sym))
             for sym in powerset(alphabet.symbols)})
        self.reward = reward
        self.gamma = gamma
        self.dfaotf.reset()
        initial_state = self.dfaotf.cur_state

        self.id2state = {0: initial_state}
        self.state2id = {initial_state: 0}

        self.states = {0}
        self.initial_state = 0
        self.transition_function = {}
        self.final_states = set()
        self.failure_states = set()

        # a list of (old_state, label, new_state) to keep track of the sequence of states and labels
        self.trace = []
        self.changed = False

        dfa = DFA(alphabet, frozenset(self.states), self.initial_state,
                  frozenset(self.final_states), self.transition_function)
        self._automaton = RewardAutomaton(dfa,
                                          alphabet,
                                          dfaotf.f,
                                          reward,
                                          gamma=gamma)
    def make_transition(self, s: Set[Symbol]):
        i = PLInterpretation(s)
        old_state = self.cur_state
        super().make_transition(i)
        reward = self.get_immediate_reward(old_state, self.cur_state)
        self.visited_states.add(self.cur_state)

        return reward
Example #7
0
def to_automaton(f, labels: Optional[Set[Symbol]] = None):

    initial_state = frozenset({frozenset({PLAtomic(f)})})
    states = {initial_state}
    final_states = set()
    transition_function = {}

    # the alphabet is the powerset of the set of fluents
    alphabet = powerset(labels if labels is not None else f.find_labels())

    if f.delta(PLFalseInterpretation(), epsilon=True) == PLTrue():
        final_states.add(initial_state)

    visited = set()
    to_be_visited = {initial_state}

    while len(to_be_visited) != 0:

        for q in list(to_be_visited):
            to_be_visited.remove(q)
            for actions_set in alphabet:
                new_state = _make_transition(q, PLInterpretation(actions_set))
                if new_state not in states:
                    states.add(new_state)
                    to_be_visited.add(new_state)

                transition_function.setdefault(
                    q, {})[PLInterpretation(actions_set)] = new_state

                if new_state not in visited:
                    visited.add(new_state)
                    if _is_true(new_state):
                        final_states.add(new_state)

    new_alphabet = {PLInterpretation(set(sym)) for sym in alphabet}
    dfa = DFA(states, new_alphabet, initial_state, final_states,
              transition_function)
    dfa = dfa.minimize()
    dfa = dfa.trim()

    return dfa
Example #8
0
def test_truth():
    sa, sb = "a", "b"
    a, b = PLAtomic(sa), PLAtomic(sb)

    i_ = PLFalseInterpretation()
    i_a = PLInterpretation({sa})
    i_b = PLInterpretation({sb})
    i_ab = PLInterpretation({sa, sb})

    tr_false_a_b_ab = FiniteTrace([i_, i_a, i_b, i_ab, i_])

    tt = LDLfLogicalTrue()
    ff = LDLfLogicalFalse()

    assert tt.truth(tr_false_a_b_ab, 0)
    assert not ff.truth(tr_false_a_b_ab, 0)
    assert not LDLfNot(tt).truth(tr_false_a_b_ab, 0)
    assert LDLfNot(ff).truth(tr_false_a_b_ab, 0)
    assert LDLfAnd([LDLfPropositional(a),
                    LDLfPropositional(b)]).truth(tr_false_a_b_ab, 3)
    assert not LDLfDiamond(RegExpPropositional(PLAnd([a, b])), tt).truth(
        tr_false_a_b_ab, 0)

    parser = LDLfParser()
    trace = FiniteTrace.from_symbol_sets([{}, {"A"}, {"A"}, {"A", "B"}, {}])

    formula = "<true*;A&B>tt"
    parsed_formula = parser(formula)
    assert parsed_formula.truth(trace, 0)

    formula = "[(A+!B)*]<C>tt"
    parsed_formula = parser(formula)
    assert not parsed_formula.truth(trace, 1)

    formula = "<(<!C>tt)?><A>tt"
    parsed_formula = parser(formula)
    assert parsed_formula.truth(trace, 1)

    formula = "<!C+A>tt"
    parsed_formula = parser(formula)
    assert parsed_formula.truth(trace, 1)
def to_automaton(f, labels:Set[Symbol]=None, minimize=True):

    initial_state = frozenset({frozenset({f.to_nnf()})})
    states = {initial_state}
    final_states = set()
    transition_function = {}

    # the alphabet is the powerset of the set of fluents
    alphabet = powerset(labels)

    if DFAOTF._is_true(initial_state):
        final_states.add(initial_state)

    visited = set()
    to_be_visited = {initial_state}

    while len(to_be_visited)!=0:

        for q in list(to_be_visited):
            to_be_visited.remove(q)
            for actions_set in alphabet:
                new_state = DFAOTF._make_transition(q, PLInterpretation(actions_set))
                if not new_state in states:
                    states.add(new_state)
                    to_be_visited.add(new_state)

                transition_function.setdefault(q, {})[PLInterpretation(actions_set)] = new_state

                if new_state not in visited:
                    visited.add(new_state)
                    if DFAOTF._is_true(new_state): final_states.add(new_state)


    new_alphabet = PythomataAlphabet({PLInterpretation(set(sym)) for sym in alphabet})
    dfa = DFA(new_alphabet, frozenset(states), initial_state, frozenset(final_states), transition_function)

    if minimize:
        dfa = dfa.minimize().trim()

    return dfa
Example #10
0
    def make_transition(self, s: Set[Symbol]):
        i = PLInterpretation(s)
        old_state = self.dfaotf.cur_state
        self.dfaotf.make_transition(i)

        new_state = self.dfaotf.cur_state
        self._update_from_transition(old_state, i, new_state)

        if len(self._automaton.accepting_states) > 0:
            reward = self._automaton.get_immediate_reward(
                self.state2id[old_state], self.state2id[self.dfaotf.cur_state])
        else:
            if self.is_failed():
                reward = -self.reward
            elif old_state != new_state:
                # give an optimistic reward to help exploration
                reward = self.reward * 10e-4
            else:
                reward = 0

        return reward
 def fromStringSets(l:List[Set[str]]):
     return FiniteTrace([PLInterpretation(frozenset({Symbol(string) for string in s})) for s in l])
 def fromSymbolSets(l:List[Set[Symbol]]):
     return FiniteTrace([PLInterpretation(s) for s in l])
Example #13
0
 def setup_class(cls):
     cls.parser = LDLfParser()
     cls.i_ = PLInterpretation(set())
     cls.i_a = PLInterpretation({"A"})
     cls.i_b = PLInterpretation({"B"})
     cls.i_ab = PLInterpretation({"A", "B"})
Example #14
0
 def setup_class(cls):
     cls.parser = LTLfParser()
     cls.i_, cls.i_a, cls.i_b, cls.i_ab = \
         PLFalseInterpretation(), PLInterpretation({"A"}), PLInterpretation({"B"}), PLInterpretation({"A", "B"})
     cls.true = PLTrue()
     cls.false = PLFalse()
def to_automaton_(f, labels:Set[Symbol]=None):
    """
    DEPRECATED
    From a LDLfFormula, build the automaton.
    :param f:               a LDLfFormula;
    :param labels:          a set of Symbol, the fluents of our domain. If None, retrieve them from the formula;
    :param determinize:     True if you need to determinize the NFA, obtaining a DFA;
    :param minimize:        True if you need to minimize the DFA (if determinize is False this flag has no effect.)
    :return:                a NFA or a DFA which accepts the same traces that makes the formula True.
    """

    nnf = f.to_nnf()

    if labels is None:
        # if the labels of the formula are not specified in input,
        # retrieve them from the formula
        labels = nnf.find_labels()

    # the alphabet is the powerset of the set of fluents
    alphabet = powerset(labels)
    initial_state = MacroState({nnf})
    final_states = {MacroState()}
    delta = set()

    d = f.delta(PLFalseInterpretation(), epsilon=True)
    if d.truth(d):
        final_states.add(initial_state)

    states = {MacroState(), initial_state}

    states_changed, delta_changed = True, True

    while states_changed or delta_changed:

        states_changed, delta_changed = False, False
        for actions_set in alphabet:
            states_list = list(states)
            for q in states_list:

                # delta function applied to every formula in the macro state Q
                delta_formulas = [f.delta(actions_set) for f in q]

                # find the list of atoms, which are "true" atoms (i.e. propositional atoms) or LDLf formulas
                atomics = [s for subf in delta_formulas for s in find_atomics(subf)]

                # "freeze" the found atoms as symbols and build a mapping from symbols to formulas
                symbol2formula = {Symbol(str(f)): f for f in atomics if f != PLTrue() and f != PLFalse()}

                # build a map from formula to a "freezed" propositional Atomic Formula
                formula2atomic_formulas = {
                    f: PLAtomic(Symbol(str(f)))
                    if f != PLTrue() and f != PLFalse()# and not isinstance(f, PLAtomic)
                    else f for f in atomics
                }

                # the final list of Propositional Atomic Formulas, one for each formula in the original macro state Q
                transformed_delta_formulas = [_transform_delta(f, formula2atomic_formulas) for f in delta_formulas]

                # the empty conjunction stands for true
                if len(transformed_delta_formulas) == 0:
                    conjunctions = PLTrue()
                elif len(transformed_delta_formulas) == 1:
                    conjunctions = transformed_delta_formulas[0]
                else:
                    conjunctions = PLAnd(transformed_delta_formulas)

                # the model in this case is the smallest set of symbols s.t. the conjunction of "freezed" atomic formula
                # is true.
                models = frozenset(conjunctions.minimal_models(Alphabet(symbol2formula)))

                if len(models) == 0:
                    continue
                for min_model in models:
                    q_prime = MacroState(
                        {symbol2formula[s] for s in min_model.true_propositions})

                    len_before = len(states)
                    states.add(q_prime)
                    if len(states) == len_before + 1:
                        states_list.append(q_prime)
                        states_changed = True

                    len_before = len(delta)
                    delta.add((q, actions_set, q_prime))
                    if len(delta) == len_before + 1:
                        delta_changed = True

                    # check if q_prime should be added as final state
                    if len(q_prime) == 0:
                        final_states.add(q_prime)
                    else:
                        subf_deltas = [subf.delta(PLFalseInterpretation(), epsilon=True) for subf in q_prime]
                        if len(subf_deltas)==1:
                            q_prime_delta_conjunction = subf_deltas[0]
                        else:
                            q_prime_delta_conjunction = PLAnd(subf_deltas)

                        if q_prime_delta_conjunction.truth(PLFalseInterpretation()):
                            final_states.add(q_prime)


    alphabet = PythomataAlphabet({PLInterpretation(set(sym)) for sym in alphabet})
    delta = frozenset((i, PLInterpretation(set(a)), o) for i, a, o in delta)


    nfa = NFA.fromTransitions(
        alphabet=alphabet,
        states=frozenset(states),
        initial_state=initial_state,
        accepting_states=frozenset(final_states),
        transitions=delta
    )

    return nfa