def rule_right_or(left: utils.Sentence, right: utils.Sentence, side: str, used: list[tuple[str]]): # sourcery skip: merge-duplicate-blocks """ ... => (A,B)[side] ______________ ... => AvB """ # Usunięto find bo trochę przesadne chwilowo if not right or side not in ('l', 'r'): return (None, None) split = utils.strip_around(right, 'or', False, PRECEDENCE) if split is None or split[0] is None: return (None, None) left_split, right_split = split[0] if side == 'l': return ((left, ), ), ((left_split, ), ) elif side == 'r': return ((left, ), ), ((right_split, ), ) else: if is_sequent(left, left_split): return ((left, ), ), ((left_split, ), ) elif is_sequent(left, right_split): return ((left, ), ), ((right_split, ), ) else: # Default case return ((left, ), ), ((max(split[0], key=len), ), ) if ret in used: raise utils.FormalError( "Operation prohibited by loop detection algorithm") utils.pop_part(right, 'sep', 0) return ((left, ), ), ((debrac(ret), ), )
def check_closure( branch: list[utils.Sentence], used: set[tuple[str]] ) -> tp.Union[None, tuple[utils.close.Close, str]]: """Sprawdza możliwość zamknięcia gałęzi, zwraca obiekty zamknięcia oraz komunikat do wyświetlenia""" left, right = utils.strip_around(branch[-1], "turnstile", False, PRECEDENCE)[0] left = [i for i in left if i != "^"] seps = sum((i.startswith('sep_') for i in left), 1) # Right part verification empty = len(right) == 1 # Left part verification if not left: return None for i in range(seps): f = utils.pop_part(left[:], 'sep', i) # F, ... => ... if len(f) == 1 and f[0].startswith("falsum_"): return utils.close.Falsum, "Falsum found on the left" # p, ... => p if f == right: return utils.close.Axiom, "Sequent on the right corresponds with a sequent on the left" # Detect finish empty &= not any((any((j.startswith(i) for j in f)) for i in ('and_', 'or_', 'imp_'))) if empty: return utils.close.Emptiness, "Nothing more can be done with this branch, so it was closed."
def rule_left_weak(left: utils.Sentence, right: utils.Sentence, num: int): """ ... => ... ______________ ..., A => ... """ try: conj = utils.pop_part(left, 'sep', num - 1) except IndexError: return (None, None) return ((left, ), ), ((right, ), )
def rule_right_and(left: utils.Sentence, right: utils.Sentence): """ ... => A ... => B __________________________ ... => A&B """ conj = utils.pop_part(right, 'sep', 0) if conj is None: return (None, None) split = utils.strip_around(conj, 'and', False, PRECEDENCE) if split is None or split[0] is None: return (None, None) split = split[0] return ((left,),(left,),), ((split[0],),(split[1],),)
def rule_left_or(left: utils.Sentence, right: utils.Sentence, num: int): """ A,... => ... B,... => ... __________________________ AvB,... => ... """ try: conj = utils.pop_part(left, 'sep', num-1) except IndexError: return (None, None) split = utils.strip_around(conj, 'or', False, PRECEDENCE) if split is None or split[0] is None: return (None, None) split = split[0] return ((split[0]+sep(left)+left,),(split[1]+sep(left)+left,),), ((right,),(right,),)
def rule_right_imp(left: utils.Sentence, right: utils.Sentence): """ ..., A => B ______________ ... => A -> B """ try: conj = utils.pop_part(right, 'sep', 0) except IndexError: return (None, None) split = utils.strip_around(conj, 'imp', False, PRECEDENCE) if split is None or split[0] is None: return (None, None) split = split[0] return ((split[0]+sep(left)+left,),), ((split[1],),)
def rule_left_imp(left: utils.Sentence, right: utils.Sentence, num: int): """ A -> B, ... => A B,... => ... ________________________________ A -> B,... => ... """ try: conj = utils.pop_part(left, 'sep', num - 1) except IndexError: return (None, None) split = utils.strip_around(conj, 'imp', False, PRECEDENCE) if split is None or split[0] is None: return (None, None) split = split[0] return ( (conj + sep(left) + left, ), (debrac(split[1]) + sep(left) + left, ), ), ( (debrac(split[0]), ), (right, ), )
def use_rule( name: str, branch: list[utils.Sentence], used: utils.History, context: dict[str, tp.Any], decisions: dict[str, tp.Any] ) -> tuple[utils.SentenceTupleStructure, utils.HistoryTupleStructure, dict[ str, tp.Any]]: """ Używa określonej reguły na podanej gałęzi. Więcej: https://www.notion.so/szymanski/Gniazda-w-Larchu-637a500c36304ee28d3abe11297bfdb2#98e96d34d3c54077834bc0384020ff38 :param name: Nazwa używanej reguły, listę można uzyskać z pomocą Formal.get_rules_docs() :type name: str :param branch: Lista zdań w gałęzi, na której została użyta reguła :type branch: list[utils.Sentence] :param used: Obiekt historii przechowujący informacje o już rozłożonych zdaniach :type used: utils.History :param context: kontekst wymagany do zastosowania reguły, listę można uzyskać z pomocą Formal.get_needed_context(rule) Kontekst reguł: https://www.notion.so/szymanski/Zarz-dzanie-kontekstem-regu-2a5abea2a1bc492e8fa3f8b1c046ad3a :type context: dict[str, tp.Any] :param auto: , defaults to False :type auto: bool, optional :return: Struktura krotek, reprezentująca wynik reguły oraz strukturę reprezentującą operacje do wykonania na zbiorze zamknięcia. Struktury krotek: https://www.notion.so/szymanski/Reprezentacja-dowod-w-w-Larchu-cd36457b437e456a87b4e0c2c2e38bd5#014dccf44246407380c4e30b2ea598a9 Zamykanie gałęzi: https://www.notion.so/szymanski/Zamykanie-ga-zi-53249279f1884ab4b6f58bbd6346ec8d :rtype: tuple[tp.Union[tuple[tuple[utils.Sentence]], None], tp.Union[tuple[tuple[tp.Union[int, Callable, utils.Sentence]]], None]] """ rule = RULES[name] start = utils.strip_around(branch[-1], "turnstile", False, PRECEDENCE) start_left, start_right = start[0] # Check sequent number if context.get('partID', -1) > sum(i.startswith('sep') for i in start_left) + 1: raise utils.FormalError("Sequent number is too big") # Loop detection history = None if name == "left imp": p = utils.pop_part(start_left[:], 'sep', context['partID'] - 1) l, r = utils.strip_around(p, "imp", False, PRECEDENCE)[0] if tuple(l) in used: raise utils.FormalError( "Operation prohibited by loop detection algorithm") else: history = [[l], [0]] elif name == 'left or': p = utils.pop_part(start_left[:], 'sep', context['partID'] - 1) l, r = utils.strip_around(p, "or", False, PRECEDENCE)[0] if is_sequent(start_left, l) or is_sequent(start_left, r): raise utils.FormalError( "Operation prohibited by loop detection algorithm") else: history = [[-1, start_right], [-1, start_right]] elif name == 'right imp': if (stripped := utils.strip_around(start_right, "imp", False, PRECEDENCE)) is None: return None, None, None l, r = stripped[0] if is_sequent(start_left, l): if tuple(r) not in used: history = [[r]] else: raise utils.FormalError( "Operation prohibited by loop detection algorithm") else: history = [[-1, r]]