Skip to content

Commit b0ee784

Browse files
committed
debug indexed grammar intersection and generating variables obtaining
1 parent 132ee96 commit b0ee784

File tree

6 files changed

+85
-38
lines changed

6 files changed

+85
-38
lines changed

pyformlang/fst/fst.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ def add_transitions(self, transitions: Iterable[InputTransition]) -> None:
146146
s_to,
147147
output_symbols)
148148

149+
def remove_transition(self,
150+
s_from: Hashable,
151+
input_symbol: Hashable,
152+
s_to: Hashable,
153+
output_symbols: Iterable[Hashable]) -> None:
154+
""" Removes the given transition from the FST """
155+
s_from = to_state(s_from)
156+
input_symbol = to_symbol(input_symbol)
157+
s_to = to_state(s_to)
158+
output_symbols = tuple(to_symbol(x) for x in output_symbols)
159+
head = (s_from, input_symbol)
160+
self._delta.get(head, set()).discard((s_to, output_symbols))
161+
149162
def add_start_state(self, start_state: Hashable) -> None:
150163
""" Add a start state
151164

pyformlang/fst/tests/test_fst.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,29 @@ def test_paper(self):
190190
assert len(translation) == 2
191191
fst.write_as_dot("fst.dot")
192192
assert path.exists("fst.dot")
193+
194+
def test_contains(self, fst0: FST):
195+
""" Tests the containment of transition in the FST """
196+
assert ("q0", "a", "q1", ["b"]) in fst0
197+
assert ("a", "b", "c", "d") not in fst0
198+
fst0.add_transition("a", "b", "c", "d")
199+
assert ("a", "b", "c", "d") in fst0
200+
201+
def test_iter(self, fst0: FST):
202+
""" Tests the iteration of FST transitions """
203+
fst0.add_transition("q1", "A", "q2", ["B"])
204+
fst0.add_transition("q1", "A", "q2", ["C", "D"])
205+
transitions = list(iter(fst0))
206+
assert (("q0", "a"), ("q1", tuple("b"))) in transitions
207+
assert (("q1", "A"), ("q2", tuple("B"))) in transitions
208+
assert (("q1", "A"), ("q2", ("C", "D"))) in transitions
209+
assert len(transitions) == 3
210+
211+
def test_remove_transition(self, fst0: FST):
212+
""" Tests the removal of transition from the FST """
213+
assert ("q0", "a", "q1", "b") in fst0
214+
fst0.remove_transition("q0", "a", "q1", "b")
215+
assert ("q0", "a", "q1", "b") not in fst0
216+
fst0.remove_transition("q0", "a", "q1", "b")
217+
assert ("q0", "a", "q1", "b") not in fst0
218+
assert fst0.get_number_transitions() == 0

pyformlang/fst/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" Class for renaming the states in FST """
1+
""" Utility for FST """
22

33
from typing import Dict, Set, Iterable, Tuple
44

pyformlang/indexed_grammar/indexed_grammar.py

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def get_generating_non_terminals(self) -> Set[Variable]:
259259
"""
260260
# Preprocess
261261
generating_from: Dict[Variable, Set[Variable]] = {}
262-
duplication_pointer: Dict[CFGObject, List[Tuple[Variable, int]]] = {}
262+
duplication_pointer: Dict[CFGObject, List[List]] = {}
263263
generating = set()
264264
to_process = []
265265
self._preprocess_rules_generating(duplication_pointer, generating,
@@ -272,12 +272,12 @@ def get_generating_non_terminals(self) -> Set[Variable]:
272272
if symbol not in generating:
273273
generating.add(symbol)
274274
to_process.append(symbol)
275-
for symbol, pointer in duplication_pointer.get(current, []):
276-
pointer -= 1
277-
if pointer == 0:
278-
if symbol not in generating:
279-
generating.add(symbol)
280-
to_process.append(symbol)
275+
for duplication in duplication_pointer.get(current, []):
276+
duplication[1] -= 1
277+
if duplication[1] == 0:
278+
if duplication[0] not in generating:
279+
generating.add(duplication[0])
280+
to_process.append(duplication[0])
281281
return generating
282282

283283
def _preprocess_consumption_rules_generating(
@@ -295,7 +295,7 @@ def _preprocess_consumption_rules_generating(
295295

296296
def _preprocess_rules_generating(
297297
self,
298-
duplication_pointer: Dict[CFGObject, List[Tuple[Variable, int]]],
298+
duplication_pointer: Dict[CFGObject, List[List]],
299299
generating: Set[Variable],
300300
generating_from: Dict[Variable, Set[Variable]],
301301
to_process: List[Variable]) \
@@ -305,7 +305,7 @@ def _preprocess_rules_generating(
305305
left = rule.left_term
306306
right0 = rule.right_terms[0]
307307
right1 = rule.right_terms[1]
308-
temp = (left, 2)
308+
temp = [left, 2]
309309
duplication_pointer.setdefault(right0, []).append(temp)
310310
duplication_pointer.setdefault(right1, []).append(temp)
311311
if isinstance(rule, ProductionRule):
@@ -424,7 +424,7 @@ def _extract_fst_duplication_rules_intersection(
424424
for start_state in other.start_states:
425425
new_rules.append(DuplicationRule(
426426
"S",
427-
(start_state, "S", final_state),
427+
(start_state.value, "S", final_state.value),
428428
"T"))
429429

430430
def _extract_fst_epsilon_intersection(
@@ -434,7 +434,7 @@ def _extract_fst_epsilon_intersection(
434434
-> None:
435435
for state in other.states:
436436
new_rules.append(EndRule(
437-
(state, "epsilon", state),
437+
(state.value, "epsilon", state.value),
438438
"epsilon"))
439439

440440
def _extract_fst_delta_intersection(
@@ -444,8 +444,8 @@ def _extract_fst_delta_intersection(
444444
-> None:
445445
for (s_from, symb_from), (s_to, symb_to) in other:
446446
new_rules.append(EndRule(
447-
(s_from, symb_from, s_to),
448-
symb_to))
447+
(s_from.value, symb_from.value, s_to.value),
448+
tuple(map(lambda x: x.value, symb_to))))
449449

450450
def _extract_epsilon_transitions_intersection(
451451
self,
@@ -456,9 +456,9 @@ def _extract_epsilon_transitions_intersection(
456456
for state_q in other.states:
457457
for state_r in other.states:
458458
new_rules.append(DuplicationRule(
459-
(state_p, "epsilon", state_q),
460-
(state_p, "epsilon", state_r),
461-
(state_r, "epsilon", state_q)))
459+
(state_p.value, "epsilon", state_q.value),
460+
(state_p.value, "epsilon", state_r.value),
461+
(state_r.value, "epsilon", state_q.value)))
462462

463463
def _extract_indexed_grammar_rules_intersection(
464464
self,
@@ -471,22 +471,29 @@ def _extract_indexed_grammar_rules_intersection(
471471
for state_q in other.states:
472472
for state_r in other.states:
473473
new_rules.append(DuplicationRule(
474-
(state_p, rule.left_term, state_q),
475-
(state_p, rule.right_terms[0], state_r),
476-
(state_r, rule.right_terms[1], state_q)))
474+
(state_p.value, rule.left_term.value,
475+
state_q.value),
476+
(state_p.value, rule.right_terms[0].value,
477+
state_r.value),
478+
(state_r.value, rule.right_terms[1].value,
479+
state_q.value)))
477480
elif isinstance(rule, ProductionRule):
478481
for state_p in other.states:
479482
for state_q in other.states:
480483
new_rules.append(ProductionRule(
481-
(state_p, rule.left_term, state_q),
482-
(state_p, rule.right_term, state_q),
483-
rule.production))
484+
(state_p.value, rule.left_term.value,
485+
state_q.value),
486+
(state_p.value, rule.right_term.value,
487+
state_q.value),
488+
rule.production.value))
484489
elif isinstance(rule, EndRule):
485490
for state_p in other.states:
486491
for state_q in other.states:
487492
new_rules.append(DuplicationRule(
488-
(state_p, rule.left_term, state_q),
489-
(state_p, rule.right_term, state_q),
493+
(state_p.value, rule.left_term.value,
494+
state_q.value),
495+
(state_p.value, rule.right_term.value,
496+
state_q.value),
490497
"T"))
491498

492499
def _extract_terminals_intersection(
@@ -499,13 +506,13 @@ def _extract_terminals_intersection(
499506
for state_q in other.states:
500507
for state_r in other.states:
501508
new_rules.append(DuplicationRule(
502-
(state_p, terminal, state_q),
503-
(state_p, "epsilon", state_r),
504-
(state_r, terminal, state_q)))
509+
(state_p.value, terminal.value, state_q.value),
510+
(state_p.value, "epsilon", state_r.value),
511+
(state_r.value, terminal.value, state_q.value)))
505512
new_rules.append(DuplicationRule(
506-
(state_p, terminal, state_q),
507-
(state_p, terminal, state_r),
508-
(state_r, "epsilon", state_q)))
513+
(state_p.value, terminal.value, state_q.value),
514+
(state_p.value, terminal.value, state_r.value),
515+
(state_r.value, "epsilon", state_q.value)))
509516

510517
def _extract_consumption_rules_intersection(
511518
self,
@@ -518,6 +525,8 @@ def _extract_consumption_rules_intersection(
518525
for state_r in other.states:
519526
for state_s in other.states:
520527
new_rules.append(ConsumptionRule(
521-
consumption.f_parameter,
522-
(state_r, consumption.left_term, state_s),
523-
(state_r, consumption.right_term, state_s)))
528+
consumption.f_parameter.value,
529+
(state_r.value, consumption.left_term.value,
530+
state_s.value),
531+
(state_r.value, consumption.right_term.value,
532+
state_s.value)))

pyformlang/indexed_grammar/rules.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ def non_terminals(self) -> Set[Variable]:
123123
The non terminals used in the rule
124124
"""
125125
non_terminals = set()
126-
for temp_rule in self._consumption_rules.values():
127-
for rule in temp_rule:
126+
for rules in self._consumption_rules.values():
127+
for rule in rules:
128128
non_terminals.update(rule.non_terminals)
129129
for rule in self._rules:
130130
non_terminals.update(rule.non_terminals)

pyformlang/pda/transition_function.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ def remove_transition(self,
6464
stack_to: Tuple[StackSymbol, ...]) -> None:
6565
""" Remove the given transition from the function """
6666
key = (s_from, input_symbol, stack_from)
67-
if key in self._transitions:
68-
self._transitions[key].discard((s_to, stack_to))
67+
self._transitions.get(key, set()).discard((s_to, stack_to))
6968

7069
def copy(self) -> "TransitionFunction":
7170
""" Copy the current transition function

0 commit comments

Comments
 (0)