class Export: runs_file = os.path.join(_current_path, "..", "data", "Runs", Settings()["Output File"]) atoms_file = os.path.join(_current_path, "..", "data", "Atoms.json") def __init__(self, data): self.data = data def to_runs(self): str_forest = {} for tree in self.data: tree_dict = { str(key): str(sequent) for key, sequent in tree.items() } str_forest.update({str(tree.root): tree_dict}) with open(self.runs_file, "w") as file: file.write(json.dumps(str_forest, indent=4)) def to_atoms(self): with open(self.atoms_file, "r") as file: atoms = set(json.load(file)) for tree in self.data: atomic_sequents = [ str(sequent) for sequent in tree.values() if sequent.complexity == 0 ] atoms.update(atomic_sequents) with open(self.atoms_file, "w") as file: file.write(json.dumps(list(atoms), indent=4))
def change_single(): """Change single rule.""" menu_file = os.path.join(_data_dir, "Menus", "Change_SingleRule.json") rule_menu = Menu(file=menu_file) Settings().print_rules() rule = rule_menu.open() if rule: Rules.change_single(rule)
def __init__(self, tree: Tree) -> None: self.is_contractive: bool = Settings()['Contraction'] self.display_list: list = [Key('0000')] self.declined: set = set() self._exit: bool = False self.tree = tree self._keys = [Key(k) for k in tree.keys()] self._max_len = max([len(k) for k in self._keys])
def change_structure(): """Change structural rule.""" menu_file = os.path.join(_data_dir, "Menus", "Change_StructuralRule.json") menu = Menu(file=menu_file) Settings().print_rules() rule = menu.open() if rule: Rules.change_structure(rule)
def decompose_sequents(): input_file = Settings()["Input File"] if _names_file_is_empty(): raise ValueError("Names.json contains no names.") try: Decompose(input_file).sequents() except FileNotFoundError: print("Input file could not be found at: \n" f"{input_file} \n" f"Please verify file name and location.") except ValueError as e: print(e)
def change_multiple(): """Change multiple rules.""" rule_file = os.path.join(_data_dir, "Menus", "Change_MultipleRules.json") rules_menu = Menu(file=rule_file) Settings().print_rules() group = rules_menu.open() mode_file = os.path.join(_data_dir, "Menus", "Change_RuleMode.json") mode_menu = Menu(file=mode_file) mode = mode_menu.open() if group and mode: Rules.change_multiple(group, mode)
def change_multiple(rule, mode): if mode == "Reverse": rule_list = [r for r in rules() if (r[0] == rule or r[1:] == rule)] for r in rule_list: change_single(r) else: preset = _load_preset(mode) rule_list = [] if rule: rule_list = [r for r in rules() if (r[0] == rule or r[1:] == rule)] else: rule_list = [r for r in rules()] for r in rule_list: Settings()["Sequent Rules"][r] = preset[r]
def _decompose(self, key: str, sequent: Sequent) -> dict: """Returns the results of decomposing a sequent as a dictionary with keys matching their locations in the tree. If reflexivity is off, deletes reflexive results and marks the tree as having been truncated.""" new_items = {} children: tuple = sequent.decompose() if sequent.principal.proposition.is_invertible: new_items.update(_invertible_decomp(children, key)) else: new_items.update(_non_invertible_decomp(children, key)) if not Settings()['Reflexivity']: for new_key, new_sequent in new_items.items(): if new_sequent.is_reflexive: del new_items[new_key] if not self.has_been_truncated: self.has_been_truncated = True return new_items
class TestNonInvertibleDecomp(unittest.TestCase): rules = {k: v for k, v in Settings()["Sequent Rules"].items()} alpha = Atom("Predicate", ("alpha", )) beta = Atom("Predicate", ("beta", )) names = ["Adrian", "Eve"] def setUp(self) -> None: Rules.change_multiple("", "NonInvertible") def tearDown(self) -> None: for k, v in self.rules.items(): Settings()["Sequent Rules"][k] = v def test_left_universal(self): """forall(x)(Predicate(x)) |~""" with patch("json.load", lambda *args: self.names): sequent = Sequent([Universal("alpha", self.alpha)], []) decomp = sequent.decompose() self.assertEqual(Sequent([Atom("Predicate", ("Adrian", ))], []), decomp[0][0]) self.assertEqual(Sequent([Atom("Predicate", ("Eve", ))], []), decomp[1][0]) def test_right_existential(self): """|~ exists(x)(Predicate(x)) """ with patch("json.load", lambda *args: self.names): sequent = Sequent([], [Existential("alpha", self.alpha)]) decomp = sequent.decompose() self.assertEqual(Sequent([], [Atom("Predicate", ("Adrian", ))]), decomp[0][0]) self.assertEqual(Sequent([], [Atom("Predicate", ("Eve", ))]), decomp[1][0]) def test_nested_quantified_sequents(self): """forall(x)(exists(y)(Predicate(x; y)) |~""" sequent = Sequent([ Universal( "alpha", Existential("beta", Atom("Predicate", ("alpha", "beta")))) ], []) with patch("json.load", lambda *args: self.names): decomp = sequent.decompose() self.assertEqual( Sequent( [Existential("beta", Atom("Predicate", ("Adrian", "beta")))], []), decomp[0][0]) self.assertEqual( Sequent([Existential("beta", Atom("Predicate", ("Eve", "beta")))], []), decomp[1][0]) def test_complex_quantified_sequent(self): sequent = Sequent([ Existential( "alpha", Conjunction( Universal("beta", Atom("Predicate", ("alpha", "beta"))), Atom("AnotherPredicate", ("alpha", )))) ], []) with patch("json.load", lambda *args: self.names): decomp = sequent.decompose() self.assertEqual( Sequent([ Conjunction( Universal("beta", Atom("Predicate", ("Adrian", "beta"))), Atom("AnotherPredicate", ("Adrian", ))) ], []), decomp[0][0])
def tearDown(self) -> None: for k, v in self.rules.items(): Settings()["Sequent Rules"][k] = v
def change_structure(rule): if Settings()[rule] == "On": Settings()[rule] = "Off" elif Settings()[rule] == "Off": Settings()[rule] = "On"
def change_single(rule): if Settings()["Sequent Rules"][rule] == "Add": Settings()["Sequent Rules"][rule] = "Mult" elif Settings()["Sequent Rules"][rule] == "Mult": Settings()["Sequent Rules"][rule] = "Add"
def change_rules(): """Handle menu for changing rules.""" menu_file = os.path.join(_data_dir, "Menus", "Change_RulesSuperMenu.json") rules_menu = Menu(file=menu_file) Settings().print_rules() rules_menu.open()
class TestInvertibleDecomp(unittest.TestCase): rules = {k: v for k, v in Settings()["Sequent Rules"].items()} alpha = Atom("Predicate", ("alpha", )) beta = Atom("Predicate", ("beta", )) names = ["Adrian", "Eve"] def setUp(self) -> None: Rules.change_multiple("", "Invertible") def tearDown(self) -> None: for k, v in self.rules.items(): Settings()["Sequent Rules"][k] = v def test_inv_left_conditional(self): """Predicate(alpha) implies Predicate(beta) |~ """ sequent = Sequent([Conditional(self.alpha, self.beta)], []) decomp = sequent.decompose()[0] self.assertEqual(Sequent([], [self.alpha]), decomp[0]) self.assertEqual(Sequent([self.beta], []), decomp[1]) def test_inv_right_conditional(self): """|~ Predicate(alpha) implies Predicate(beta)""" sequent = Sequent([], [Conditional(self.alpha, self.beta)]) decomp = sequent.decompose()[0][0] self.assertEqual(Sequent([self.alpha], [self.beta]), decomp) def test_inv_left_conjunction(self): """Predicate(alpha) and Predicate(beta) |~""" sequent = Sequent([Conjunction(self.alpha, self.beta)], []) decomp = sequent.decompose()[0][0] self.assertEqual(Sequent([self.alpha, self.beta], []), decomp) def test_inv_right_conjunction(self): """|~ Predicate(alpha) and Predicate(beta)""" sequent = Sequent([], [Conjunction(self.alpha, self.beta)]) decomp = sequent.decompose()[0] self.assertEqual(Sequent([], [self.alpha]), decomp[0]) self.assertEqual(Sequent([], [self.beta]), decomp[1]) def test_inv_left_disjunction(self): """Predicate(alpha) or Predicate(beta) |~""" sequent = Sequent([Disjunction(self.alpha, self.beta)], []) decomp = sequent.decompose()[0] self.assertEqual(Sequent([self.alpha], []), decomp[0]) self.assertEqual(Sequent([self.beta], []), decomp[1]) def test_inv_right_disjunction(self): """|~ Predicate(alpha) or Predicate(beta)""" sequent = Sequent([], [Disjunction(self.alpha, self.beta)]) decomp = sequent.decompose()[0][0] self.assertEqual(Sequent([], [self.alpha, self.beta]), decomp) def test_inv_left_negation(self): """not Predicate(alpha) |~""" sequent = Sequent([Negation(self.alpha)], []) decomp = sequent.decompose()[0][0] self.assertEqual(Sequent([], [self.alpha]), decomp) def test_inv_right_negation(self): """|~ not Predicate(alpha)""" sequent = Sequent([], [Negation(self.alpha)]) decomp = sequent.decompose()[0][0] self.assertEqual(Sequent([self.alpha], []), decomp) def test_right_universal(self): """|~ forall(x)(Predicate(x))""" with patch("json.load", lambda *args: self.names): sequent = Sequent([], [Existential("alpha", self.alpha)]) decomp = sequent.decompose() self.assertEqual(Sequent([], [Atom("Predicate", ("Adrian", ))]), decomp[0][0]) self.assertEqual(Sequent([], [Atom("Predicate", ("Eve", ))]), decomp[1][0]) def test_left_existential(self): """exists(x)(Predicate(x)) |~""" with patch("json.load", lambda *args: self.names): sequent = Sequent([Existential("alpha", self.alpha)], []) decomp = sequent.decompose() self.assertEqual(Sequent([Atom("Predicate", ("Adrian", ))], []), decomp[0][0]) self.assertEqual(Sequent([Atom("Predicate", ("Eve", ))], []), decomp[1][0])
def main_menu(): """Handle main menu.""" menu_file = os.path.join(_data_dir, "Menus", "Main.json") main = Menu(file=menu_file) Settings().print_rules() main.open()
def __init__(self, prop): super(Negation, self).__init__(prop) self.rule = Settings().get_rule(self.side + self.symbol)
def __init__(self, left, right): super(Disjunction, self).__init__(left, right) self.rule = Settings().get_rule(self.side + self.symbol)
def __init__(self): self.rule = Settings().get_rule(self.side + self.symbol)
def __init__(self, left, right): super(Conditional, self).__init__(left, right) self.rule = Settings().get_rule(self.side + self.symbol)