master > master: allgemeine Aufräumung
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
%import common.WS
|
||||
%import common.NUMBER
|
||||
%import common.WORD
|
||||
|
||||
%ignore WS
|
||||
|
||||
// Schemata für Ausdrücke
|
||||
// 'open' = äußerste Klammern fehlen, wenn nötig.
|
||||
// 'closed' = sonst
|
||||
?expr: open | closed
|
||||
?closed: atomic | not | "(" open ")"
|
||||
?open: and | and_long | or | or_long | impl
|
||||
|
||||
// Schemata für atomische Ausdrücke
|
||||
?atomic: false | true | atom | generic
|
||||
?false: /0|false/ -> kontr
|
||||
?true: /1|true/ -> taut
|
||||
?atom: /A[0-9]+/ -> atom
|
||||
// als 'generische' Formeln schreibe bspw. {F}, {G}, {F1}, usw.
|
||||
?generic: "{" /((?!({|})).)+/ "}" -> beliebig
|
||||
|
||||
// Symbole (erlaube mehrere Varianten)
|
||||
?symb_not: /!|~|not/ -> symb
|
||||
?symb_and: /&+|\^|and/ -> symb
|
||||
?symb_or: /\|+|v|or/ -> symb
|
||||
?symb_impl: /->|=>/ -> symb
|
||||
|
||||
// Schema für Negation: ¬ F
|
||||
?not: symb_not closed -> neg
|
||||
// Schemata für Konjunktion: F1 ⋀ F2 bzw. F1 ⋀ F2 ⋀ ... ⋀ Fn
|
||||
?and: closed symb_and closed -> konj
|
||||
?and_long: [ closed ( symb_and closed )+ ] -> konj_lang
|
||||
// Schemata für Disjunktion: F1 ⋁ F2 bzw. F1 ⋁ F2 ⋁ ... ⋁ Fn
|
||||
?or: closed symb_or closed -> disj
|
||||
?or_long: [ closed ( symb_or closed )+ ] -> disj_lang
|
||||
// Schema für Implikation: F1 ⟶ F2
|
||||
?impl: closed symb_impl closed -> impl
|
||||
@@ -5,21 +5,9 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from __future__ import annotations
|
||||
from lark import Tree;
|
||||
from typing import List;
|
||||
|
||||
from aussagenlogik.schema import isAtom;
|
||||
from aussagenlogik.schema import isBeliebig;
|
||||
from aussagenlogik.schema import isTrueSymbol;
|
||||
from aussagenlogik.schema import isFalseSymbol;
|
||||
from aussagenlogik.schema import isNegation;
|
||||
from aussagenlogik.schema import isConjunction;
|
||||
from aussagenlogik.schema import isLongConjunction;
|
||||
from aussagenlogik.schema import isDisjunction;
|
||||
from aussagenlogik.schema import isLongDisjunction;
|
||||
from aussagenlogik.schema import isImplication;
|
||||
from aussagenlogik.schema import SyntaxBaum;
|
||||
from aussagenlogik.syntaxbaum import SyntaxBaum;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBALE KONSTANTEN
|
||||
@@ -31,53 +19,69 @@ from aussagenlogik.schema import SyntaxBaum;
|
||||
# METHODEN
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def rekursiv_eval(fml: SyntaxBaum, I: List[str]) -> int:
|
||||
def rekursivEval(fml: SyntaxBaum, I: List[str]) -> int:
|
||||
subfml = fml.children;
|
||||
if isAtom(fml):
|
||||
########
|
||||
# FÄLLE AUS DER VORLESUNG
|
||||
########
|
||||
# Fall Atom
|
||||
if fml.isAtom():
|
||||
name = fml.expr;
|
||||
return 1 if (name in I) else 0;
|
||||
if isBeliebig(fml):
|
||||
name = fml.expr;
|
||||
return 1 if (name in I) else 0;
|
||||
elif isTrueSymbol(fml):
|
||||
return 1;
|
||||
elif isFalseSymbol(fml):
|
||||
return 0;
|
||||
elif isNegation(fml):
|
||||
val0 = rekursiv_eval(subfml[0], I);
|
||||
# Fall ¬F
|
||||
elif fml.isNegation():
|
||||
val0 = rekursivEval(subfml[0], I);
|
||||
return 1 - val0;
|
||||
elif isConjunction(fml):
|
||||
val0 = rekursiv_eval(subfml[0], I);
|
||||
val1 = rekursiv_eval(subfml[1], I);
|
||||
# Fall F1 ⋀ F2
|
||||
elif fml.isConjunction2():
|
||||
val0 = rekursivEval(subfml[0], I);
|
||||
val1 = rekursivEval(subfml[1], I);
|
||||
return min(val0, val1);
|
||||
elif isLongConjunction(fml):
|
||||
values = [rekursiv_eval(t, I) for t in subfml];
|
||||
return min(values);
|
||||
elif isDisjunction(fml):
|
||||
val0 = rekursiv_eval(subfml[0], I);
|
||||
val1 = rekursiv_eval(subfml[1], I);
|
||||
# Fall F1 ⋁ F2
|
||||
elif fml.isDisjunction2():
|
||||
val0 = rekursivEval(subfml[0], I);
|
||||
val1 = rekursivEval(subfml[1], I);
|
||||
return max(val0, val1);
|
||||
elif isLongDisjunction(fml):
|
||||
values = [rekursiv_eval(t, I) for t in subfml];
|
||||
return max(values);
|
||||
elif isImplication(fml):
|
||||
val0 = rekursiv_eval(subfml[0], I);
|
||||
val1 = rekursiv_eval(subfml[1], I);
|
||||
########
|
||||
# WEITERE FÄLLE NICHT IN VORLESUNG
|
||||
########
|
||||
# Sonderfall: generische Formel als Variable
|
||||
if fml.isGeneric():
|
||||
name = fml.expr;
|
||||
return 1 if (name in I) else 0;
|
||||
# Sonderfall: Tautologiesymbol
|
||||
elif fml.isTautologySymbol():
|
||||
return 1;
|
||||
# Sonderfall: Kontradiktionssymbol
|
||||
elif fml.isContradictionSymbol():
|
||||
return 0;
|
||||
# Fall Implikation: F1 ⟶ F2
|
||||
elif fml.isImplication():
|
||||
val0 = rekursivEval(subfml[0], I);
|
||||
val1 = rekursivEval(subfml[1], I);
|
||||
return 0 if val0 == 1 and val1 == 0 else 1;
|
||||
# Fall F1 ⋀ F2 ⋀ ... ⋀ Fn
|
||||
elif fml.isConjunction():
|
||||
values = [rekursivEval(t, I) for t in subfml];
|
||||
return min(values);
|
||||
# Fall F1 ⋁ F2 ⋁ ... ⋁ Fn
|
||||
elif fml.isDisjunction():
|
||||
values = [rekursivEval(t, I) for t in subfml];
|
||||
return max(values);
|
||||
raise Exception('Evaluation nicht möglich!');
|
||||
|
||||
def rekursiv_atoms(fml: Tree) -> List[str]:
|
||||
def rekursivAtoms(fml: SyntaxBaum) -> List[str]:
|
||||
## Herausforderung: schreibe diese Funktion!
|
||||
return [];
|
||||
|
||||
def rekursiv_depth(fml: Tree) -> int:
|
||||
def rekursivDepth(fml: SyntaxBaum) -> int:
|
||||
## Herausforderung: schreibe diese Funktion!
|
||||
return 0;
|
||||
|
||||
def rekursiv_length(fml: Tree) -> int:
|
||||
def rekursivLength(fml: SyntaxBaum) -> int:
|
||||
## Herausforderung: schreibe diese Funktion!
|
||||
return 0;
|
||||
|
||||
def rekursiv_parentheses(fml: Tree) -> int:
|
||||
def rekursivParentheses(fml: SyntaxBaum) -> int:
|
||||
## Herausforderung: schreibe diese Funktion!
|
||||
return 0
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from __future__ import annotations;
|
||||
# install: lark; lark-parser; lark-parser[regex].
|
||||
# https://lark-parser.readthedocs.io/en/latest/grammar.html
|
||||
from lark import Lark;
|
||||
|
||||
from aussagenlogik.syntaxbaum import SyntaxBaum;
|
||||
@@ -16,10 +14,10 @@ from aussagenlogik.syntaxbaum import SyntaxBaum;
|
||||
# GLOBALE KONSTANTEN
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
## lexer
|
||||
with open('aussagenlogik/grammar.lark', 'r') as fp:
|
||||
# lexer durch LARK erzeugen
|
||||
with open('grammars/grammar.lark', 'r') as fp:
|
||||
grammar = ''.join(fp.readlines());
|
||||
lexerAussagenlogik = Lark(grammar, start='expr', regex=True);
|
||||
lexer = Lark(grammar, start='expr', regex=True);
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# METHODE: string -> Syntaxbaum
|
||||
@@ -27,43 +25,6 @@ with open('aussagenlogik/grammar.lark', 'r') as fp:
|
||||
|
||||
def stringToSyntaxbaum(expr: str) -> SyntaxBaum:
|
||||
try:
|
||||
return SyntaxBaum(lexerAussagenlogik.parse(expr));
|
||||
return SyntaxBaum(lexer.parse(expr));
|
||||
except:
|
||||
raise Exception('Ausdruck \033[1m{}\033[0m konnte nicht erkannt werden!'.format(expr));
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# METHODEN: Erkennung von Formeltypen
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def isAtom(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'atom';
|
||||
|
||||
def isLiteral(fml: SyntaxBaum) -> bool:
|
||||
return isAtom(fml) or (isNegation(fml) and isAtom(fml.child));
|
||||
|
||||
def isBeliebig(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'beliebig';
|
||||
|
||||
def isTrueSymbol(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'taut';
|
||||
|
||||
def isFalseSymbol(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'kontr';
|
||||
|
||||
def isNegation(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'neg';
|
||||
|
||||
def isConjunction(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'konj';
|
||||
|
||||
def isLongConjunction(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind in ['konj', 'konj_lang'];
|
||||
|
||||
def isDisjunction(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'disj';
|
||||
|
||||
def isLongDisjunction(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind in ['disj', 'disj_lang'];
|
||||
|
||||
def isImplication(fml: SyntaxBaum) -> bool:
|
||||
return fml.kind == 'impl';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from __future__ import annotations;
|
||||
from lark import Tree;
|
||||
from lark import Tree as larkTree;
|
||||
from typing import Generator;
|
||||
from typing import List;
|
||||
|
||||
@@ -21,37 +21,31 @@ from typing import List;
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class SyntaxBaum(object):
|
||||
expr: str;
|
||||
kind: str;
|
||||
expr: str;
|
||||
valence: int;
|
||||
children: List[SyntaxBaum];
|
||||
tree: Tree;
|
||||
|
||||
def __init__(self, fml: Tree):
|
||||
def __init__(self, fml: larkTree):
|
||||
self.kind = fml.data;
|
||||
if len(fml.children) == 1 and isinstance(fml.children[0], str):
|
||||
self.expr = fml.children[0];
|
||||
self.children = [];
|
||||
self.tree = Tree(self.kind, fml.children);
|
||||
else:
|
||||
self.children = [ SyntaxBaum(child) for child in fml.children if isinstance(child, Tree) and child.data != 'symb' ];
|
||||
self.tree = Tree(self.kind, [child.tree for child in self.children]);
|
||||
signature_parts = [];
|
||||
i = 0;
|
||||
for subfml in fml.children:
|
||||
if isinstance(subfml, str):
|
||||
signature_parts.append(subfml);
|
||||
elif subfml.data == 'symb':
|
||||
symb = str(subfml.children[0]);
|
||||
signature_parts.append(symb);
|
||||
else:
|
||||
signature_parts.append('{{{}}}'.format(i));
|
||||
i += 1;
|
||||
signature = ' '.join(signature_parts);
|
||||
self.expr = signature.format(*self.children);
|
||||
if self.kind in [ 'konj', 'konj_lang', 'disj', 'disj_lang', 'impl' ]:
|
||||
lbrace = '(' if self.expr.startswith('(') else '( ';
|
||||
rbrace = ')' if self.expr.endswith(')') else ' )';
|
||||
self.expr = lbrace + self.expr + rbrace;
|
||||
self.children = [];
|
||||
self.valence = 0;
|
||||
expr_parts = []
|
||||
for child in fml.children:
|
||||
if isinstance(child, str):
|
||||
expr_parts.append(child);
|
||||
## subfml is instance larkTree:
|
||||
elif child.data == 'symb':
|
||||
symb = str(child.children[0]);
|
||||
expr_parts.append(symb);
|
||||
else:
|
||||
subtree = SyntaxBaum(child);
|
||||
self.children.append(subtree);
|
||||
self.valence += 1;
|
||||
expr_parts.append(subtree.expr);
|
||||
self.expr = ' '.join(expr_parts);
|
||||
if self.valence > 1:
|
||||
self.expr = '(' + self.expr + ')';
|
||||
return;
|
||||
|
||||
def __str__(self):
|
||||
@@ -65,5 +59,58 @@ class SyntaxBaum(object):
|
||||
def child(self) -> SyntaxBaum:
|
||||
return self.children[0];
|
||||
|
||||
def pretty(self):
|
||||
return self.tree.pretty(indent_str='- ');
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# METHOD: Pretty
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def pretty(self, preindent: str = '', tab: str = ' ', prepend: str = '', depth: int = 0) -> str:
|
||||
indent = preindent + tab*depth;
|
||||
if self.valence == 0 and self.kind in [ 'atom', 'generic' ]:
|
||||
return indent + prepend + self.kind + ' ' + self.expr;
|
||||
return '\n'.join(
|
||||
[indent + prepend + self.kind] \
|
||||
+ [subtree.pretty(preindent, tab, '|__ ', depth+1) for subtree in self.children]
|
||||
);
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# METHODS: Erkennung von Formeltypen
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def isIrreducible(self) -> bool:
|
||||
return self.valence == 0;
|
||||
|
||||
def isAtom(self) -> bool:
|
||||
return self.kind == 'atom';
|
||||
|
||||
def isLiteral(self) -> bool:
|
||||
return self.isAtom() or (self.isNegation() and self.child.isAtom());
|
||||
|
||||
def isGeneric(self) -> bool:
|
||||
return self.kind == 'generic';
|
||||
|
||||
def isTautologySymbol(self) -> bool:
|
||||
return self.kind == 'taut';
|
||||
|
||||
def isContradictionSymbol(self) -> bool:
|
||||
return self.kind == 'contradiction';
|
||||
|
||||
def isConnective(self) -> bool:
|
||||
return self.valence > 0;
|
||||
|
||||
def isNegation(self) -> bool:
|
||||
return self.kind == 'not';
|
||||
|
||||
def isConjunction2(self) -> bool:
|
||||
return self.kind == 'and2';
|
||||
|
||||
def isConjunction(self) -> bool:
|
||||
return self.kind in ['and', 'and2'];
|
||||
|
||||
def isDisjunction2(self) -> bool:
|
||||
return self.kind == 'or2';
|
||||
|
||||
def isDisjunction(self) -> bool:
|
||||
return self.kind in ['or', 'or2'];
|
||||
|
||||
def isImplication(self) -> bool:
|
||||
return self.kind == 'implies';
|
||||
|
||||
Reference in New Issue
Block a user