Skip to content

Commit

Permalink
correct formal objects equality
Browse files Browse the repository at this point in the history
  • Loading branch information
bygu4 committed Dec 29, 2024
1 parent 510e04b commit 1f312ef
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 60 deletions.
3 changes: 3 additions & 0 deletions pyformlang/objects/base_epsilon.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ def __hash__(self) -> int:

def __repr__(self) -> str:
return "epsilon"

def _is_equal_to(self, other: FormalObject) -> bool:
return isinstance(other, BaseEpsilon)
14 changes: 3 additions & 11 deletions pyformlang/objects/base_terminal.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
""" General terminal representation """

from typing import Any
from abc import abstractmethod

from .formal_object import FormalObject
Expand All @@ -9,16 +8,9 @@
class BaseTerminal(FormalObject):
""" General terminal representation """

def __eq__(self, other: Any) -> bool:
if isinstance(other, BaseTerminal):
return self.value == other.value
if isinstance(other, FormalObject):
return False
return self.value == other

def __hash__(self) -> int:
return super().__hash__()

@abstractmethod
def __repr__(self):
raise NotImplementedError

def _is_equal_to(self, other: FormalObject) -> bool:
return isinstance(other, BaseTerminal) and self.value == other.value
14 changes: 3 additions & 11 deletions pyformlang/objects/cfg_objects/variable.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
""" A variable in a CFG """

from typing import Any
from string import ascii_uppercase

from .cfg_object import CFGObject
Expand All @@ -16,16 +15,6 @@ class Variable(CFGObject):
The value of the variable
"""

def __eq__(self, other: Any) -> bool:
if isinstance(other, Variable):
return self.value == other.value
if isinstance(other, FormalObject):
return False
return self.value == other

def __hash__(self) -> int:
return super().__hash__()

def __repr__(self) -> str:
return f"Variable({self})"

Expand All @@ -34,3 +23,6 @@ def to_text(self) -> str:
if text and text[0] not in ascii_uppercase:
return '"VAR:' + text + '"'
return text

def _is_equal_to(self, other: FormalObject) -> bool:
return isinstance(other, Variable) and self.value == other.value
15 changes: 3 additions & 12 deletions pyformlang/objects/finite_automaton_objects/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Representation of a state in a finite state automaton
"""

from typing import Any

from .finite_automaton_object import FiniteAutomatonObject
from ..formal_object import FormalObject

Expand All @@ -24,15 +22,8 @@ class State(FiniteAutomatonObject):
"""

def __eq__(self, other: Any) -> bool:
if isinstance(other, State):
return self.value == other.value
if isinstance(other, FormalObject):
return False
return self.value == other

def __hash__(self) -> int:
return super().__hash__()

def __repr__(self) -> str:
return f"State({self})"

def _is_equal_to(self, other: FormalObject) -> bool:
return isinstance(other, State) and self.value == other.value
9 changes: 7 additions & 2 deletions pyformlang/objects/formal_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ def value(self) -> Hashable:
"""
return self._value

@abstractmethod
def __eq__(self, other: Any) -> bool:
raise NotImplementedError
if not isinstance(other, FormalObject):
return self.value == other
return self._is_equal_to(other) and other._is_equal_to(self)

def __hash__(self) -> int:
if self._hash is None:
Expand All @@ -38,3 +39,7 @@ def __str__(self) -> str:
@abstractmethod
def __repr__(self) -> str:
raise NotImplementedError

@abstractmethod
def _is_equal_to(self, other: "FormalObject") -> bool:
raise NotImplementedError
15 changes: 3 additions & 12 deletions pyformlang/objects/pda_objects/stack_symbol.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
""" A StackSymbol in a pushdown automaton """

from typing import Any

from .symbol import Symbol
from ..formal_object import FormalObject

Expand All @@ -16,15 +14,8 @@ class StackSymbol(Symbol):
"""

def __eq__(self, other: Any) -> bool:
if isinstance(other, StackSymbol):
return self.value == other.value
if isinstance(other, FormalObject):
return False
return self.value == other

def __hash__(self) -> int:
return super().__hash__()

def __repr__(self) -> str:
return f"StackSymbol({self})"

def _is_equal_to(self, other: FormalObject) -> bool:
return isinstance(other, StackSymbol) and self.value == other.value
15 changes: 3 additions & 12 deletions pyformlang/objects/pda_objects/state.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
""" A State in a pushdown automaton """

from typing import Any

from .pda_object import PDAObject
from ..formal_object import FormalObject

Expand All @@ -16,15 +14,8 @@ class State(PDAObject):
"""

def __eq__(self, other: Any) -> bool:
if isinstance(other, State):
return self.value == other.value
if isinstance(other, FormalObject):
return False
return self.value == other

def __hash__(self) -> int:
return super().__hash__()

def __repr__(self) -> str:
return f"State({self})"

def _is_equal_to(self, other: FormalObject) -> bool:
return isinstance(other, State) and self.value == other.value
2 changes: 2 additions & 0 deletions pyformlang/pda/tests/test_pda.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ def test_object_eq(self):
assert StackSymbol("ABC") != Symbol("ABC")
assert State("ABC") != FAState("ABC")
assert Symbol("s") == Terminal("s")
assert Terminal(1) != StackSymbol(1)
assert StackSymbol(42) != FAState(42)

def test_contains(self, pda_example: PDA):
""" Tests the transition containment checks """
Expand Down

1 comment on commit 1f312ef

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
pyformlang
   __init__.py90100% 
pyformlang/cfg
   __init__.py30100% 
   cfg.py47022 99%
   cfg_variable_converter.py6544 94%
   cyk_table.py790100% 
   formal_grammar.py6911 99%
   llone_parser.py16333 98%
   parse_tree.py6511 98%
   recursive_decent_parser.py6122 97%
   set_queue.py150100% 
   utils.py250100% 
pyformlang/cfg/tests
   __init__.py00100% 
   test_cfg.py62622 99%
   test_llone_parser.py11711 99%
   test_production.py210100% 
   test_recursive_decent_parser.py2511 96%
   test_terminal.py310100% 
   test_variable.py160100% 
pyformlang/fcfg
   __init__.py40100% 
   fcfg.py13111 99%
   feature_production.py250100% 
   feature_structure.py19133 98%
   state.py360100% 
pyformlang/fcfg/tests
   __init__.py00100% 
   test_fcfg.py1690100% 
   test_feature_structure.py1590100% 
pyformlang/finite_automaton
   __init__.py70100% 
   deterministic_finite_automaton.py18333 98%
   deterministic_transition_function.py2411 96%
   doubly_linked_list.py350100% 
   doubly_linked_node.py100100% 
   epsilon_nfa.py22011 99%
   finite_automaton.py23111 99%
   hopcroft_processing_list.py240100% 
   nondeterministic_finite_automaton.py400100% 
   nondeterministic_transition_function.py480100% 
   partition.py400100% 
   transition_function.py320100% 
   utils.py300100% 
pyformlang/finite_automaton/tests
   __init__.py00100% 
   test_deterministic_finite_automaton.py2960100% 
   test_deterministic_transition_function.py8955 94%
   test_epsilon.py130100% 
   test_epsilon_nfa.py5950100% 
   test_nondeterministic_finite_automaton.py1600100% 
   test_nondeterministic_transition_function.py790100% 
   test_state.py270100% 
   test_symbol.py280100% 
pyformlang/fst
   __init__.py20100% 
   fst.py2420100% 
pyformlang/fst/tests
   __init__.py00100% 
   test_fst.py1650100% 
pyformlang/indexed_grammar
   __init__.py70100% 
   consumption_rule.py340100% 
   duplication_rule.py300100% 
   end_rule.py300100% 
   indexed_grammar.py25722 99%
   production_rule.py320100% 
   reduced_rule.py250100% 
   rule_ordering.py700100% 
   rules.py690100% 
pyformlang/indexed_grammar/tests
   __init__.py00100% 
   test_indexed_grammar.py2240100% 
   test_rules.py350100% 
pyformlang/objects
   __init__.py50100% 
   base_epsilon.py1511 93%
   base_terminal.py70100% 
   formal_object.py240100% 
pyformlang/objects/cfg_objects
   __init__.py60100% 
   cfg_object.py50100% 
   epsilon.py30100% 
   production.py4111 98%
   terminal.py1011 90%
   utils.py1411 93%
   variable.py130100% 
pyformlang/objects/finite_automaton_objects
   __init__.py50100% 
   epsilon.py30100% 
   finite_automaton_object.py50100% 
   state.py711 86%
   symbol.py511 80%
   utils.py140100% 
pyformlang/objects/pda_objects
   __init__.py60100% 
   epsilon.py30100% 
   pda_object.py50100% 
   stack_symbol.py70100% 
   state.py70100% 
   symbol.py50100% 
   utils.py2111 95%
pyformlang/objects/regex_objects
   __init__.py20100% 
   regex_objects.py630100% 
   utils.py220100% 
pyformlang/pda
   __init__.py40100% 
   pda.py32822 99%
   transition_function.py4133 93%
   utils.py5322 96%
pyformlang/pda/tests
   __init__.py00100% 
   test_pda.py2990100% 
pyformlang/regular_expression
   __init__.py30100% 
   python_regex.py26966 98%
   regex.py2811414 95%
   regex_reader.py15944 97%
pyformlang/regular_expression/tests
   __init__.py00100% 
   test_python_regex.py2780100% 
   test_regex.py4110100% 
pyformlang/rsa
   __init__.py30100% 
   box.py512525 51%
   recursive_automaton.py7299 88%
pyformlang/rsa/tests
   __init__.py00100% 
   test_rsa.py370100% 
pyformlang/tests
   __init__.py00100% 
TOTAL862010699% 

Tests Skipped Failures Errors Time
305 0 💤 0 ❌ 0 🔥 7.777s ⏱️

Please sign in to comment.