master > master: Schema robuster gemacht; simple class, um Aspekte leichter aufzurufen
This commit is contained in:
parent
6f6de00296
commit
28a1e313b3
@ -5,7 +5,7 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from __future__ import annotations;
|
from __future__ import annotations
|
||||||
from lark import Tree;
|
from lark import Tree;
|
||||||
from typing import List;
|
from typing import List;
|
||||||
|
|
||||||
@ -15,10 +15,12 @@ from aussagenlogik.schema import isTrueSymbol;
|
|||||||
from aussagenlogik.schema import isFalseSymbol;
|
from aussagenlogik.schema import isFalseSymbol;
|
||||||
from aussagenlogik.schema import isNegation;
|
from aussagenlogik.schema import isNegation;
|
||||||
from aussagenlogik.schema import isConjunction;
|
from aussagenlogik.schema import isConjunction;
|
||||||
|
from aussagenlogik.schema import isLongConjunction;
|
||||||
from aussagenlogik.schema import isDisjunction;
|
from aussagenlogik.schema import isDisjunction;
|
||||||
|
from aussagenlogik.schema import isLongDisjunction;
|
||||||
from aussagenlogik.schema import isImplication;
|
from aussagenlogik.schema import isImplication;
|
||||||
from aussagenlogik.schema import getTeilformeln;
|
|
||||||
from aussagenlogik.schema import getName;
|
from aussagenlogik.schema import getName;
|
||||||
|
from aussagenlogik.schema import SyntaxBaum;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# GLOBALE KONSTANTEN
|
# GLOBALE KONSTANTEN
|
||||||
@ -30,8 +32,8 @@ from aussagenlogik.schema import getName;
|
|||||||
# METHODEN
|
# METHODEN
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def rekursiv_eval(fml: Tree, I: List[str]) -> int:
|
def rekursiv_eval(fml: SyntaxBaum, I: List[str]) -> int:
|
||||||
teilfml = getTeilformeln(fml);
|
subfml = fml.children;
|
||||||
if isAtom(fml):
|
if isAtom(fml):
|
||||||
name = getName(fml);
|
name = getName(fml);
|
||||||
return 1 if (name in I) else 0;
|
return 1 if (name in I) else 0;
|
||||||
@ -43,19 +45,25 @@ def rekursiv_eval(fml: Tree, I: List[str]) -> int:
|
|||||||
elif isFalseSymbol(fml):
|
elif isFalseSymbol(fml):
|
||||||
return 0;
|
return 0;
|
||||||
elif isNegation(fml):
|
elif isNegation(fml):
|
||||||
val0 = rekursiv_eval(teilfml[0], I);
|
val0 = rekursiv_eval(subfml[0], I);
|
||||||
return 1 - val0;
|
return 1 - val0;
|
||||||
elif isConjunction(fml):
|
elif isConjunction(fml):
|
||||||
val0 = rekursiv_eval(teilfml[0], I);
|
val0 = rekursiv_eval(subfml[0], I);
|
||||||
val1 = rekursiv_eval(teilfml[1], I);
|
val1 = rekursiv_eval(subfml[1], I);
|
||||||
return min(val0, val1);
|
return min(val0, val1);
|
||||||
|
elif isLongConjunction(fml):
|
||||||
|
values = [rekursiv_eval(t, I) for t in subfml];
|
||||||
|
return min(values);
|
||||||
elif isDisjunction(fml):
|
elif isDisjunction(fml):
|
||||||
val0 = rekursiv_eval(teilfml[0], I);
|
val0 = rekursiv_eval(subfml[0], I);
|
||||||
val1 = rekursiv_eval(teilfml[1], I);
|
val1 = rekursiv_eval(subfml[1], I);
|
||||||
return max(val0, val1);
|
return max(val0, val1);
|
||||||
|
elif isLongDisjunction(fml):
|
||||||
|
values = [rekursiv_eval(t, I) for t in subfml];
|
||||||
|
return max(values);
|
||||||
elif isImplication(fml):
|
elif isImplication(fml):
|
||||||
val0 = rekursiv_eval(teilfml[0], I);
|
val0 = rekursiv_eval(subfml[0], I);
|
||||||
val1 = rekursiv_eval(teilfml[1], I);
|
val1 = rekursiv_eval(subfml[1], I);
|
||||||
return 0 if val0 == 1 and val1 == 0 else 1;
|
return 0 if val0 == 1 and val1 == 0 else 1;
|
||||||
raise Exception('Evaluation nicht möglich!');
|
raise Exception('Evaluation nicht möglich!');
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ from __future__ import annotations;
|
|||||||
from lark import Lark;
|
from lark import Lark;
|
||||||
from lark import Tree;
|
from lark import Tree;
|
||||||
from typing import List;
|
from typing import List;
|
||||||
|
from typing import Union;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# GLOBALE KONSTANTEN
|
# GLOBALE KONSTANTEN
|
||||||
@ -24,42 +25,84 @@ lexerAussagenlogik = Lark(
|
|||||||
%import common.WORD
|
%import common.WORD
|
||||||
%ignore WS
|
%ignore WS
|
||||||
|
|
||||||
?start: expr
|
?start: expr | open
|
||||||
|
|
||||||
?expr: atomic | expr_not | expr_and | expr_or | expr_implies
|
?expr: atomic | not | closed
|
||||||
?literal: atomic | "not" atomic
|
?open: and | and_long | or | or_long | impl
|
||||||
|
?closed: "(" open ")"
|
||||||
|
|
||||||
// atomische Ausdrücke
|
// atomische Ausdrücke
|
||||||
?atomic: false | true | atom | generic
|
?atomic: false | true | atom | generic
|
||||||
?false: "0" -> wahr
|
?false: "0" -> kontr
|
||||||
?true: "1" -> falsch
|
?true: "1" -> taut
|
||||||
?atom: /A[0-9]+/ -> atom
|
?atom: /A[0-9]+/ -> atom
|
||||||
?generic: "{" /((?!({|})).)+/ "}" -> beliebig
|
?generic: "{" /((?!({|})).)+/ "}" -> beliebig
|
||||||
|
|
||||||
// Symbole
|
// Symbole
|
||||||
?conn_not: "!" -> junktor
|
?symb_not: /!/ -> symb
|
||||||
?conn_and: /&+/ -> junktor
|
?symb_and: /&+/ -> symb
|
||||||
?conn_or: /\\|+/ -> junktor
|
?symb_or: /\\|+/ -> symb
|
||||||
?conn_impl: /->|=>/ -> junktor
|
?symb_impl: /->|=>/ -> symb
|
||||||
|
|
||||||
// Junktoren
|
// Junktoren
|
||||||
?expr_not: conn_not expr -> negation
|
?not: symb_not expr -> neg
|
||||||
?expr_and: "(" expr conn_and expr ")" -> konjunktion
|
?and: expr symb_and expr -> konj
|
||||||
?expr_or: "(" expr conn_or expr ")" -> disjunktion
|
?and_long: [ expr ( symb_and expr )+ ] -> konj_lang
|
||||||
?expr_implies: "(" expr conn_impl expr ")" -> implikation
|
?or: expr symb_or expr -> disj
|
||||||
|
?or_long: [ expr ( symb_or expr )+ ] -> disj_lang
|
||||||
|
?impl: expr symb_impl expr -> impl
|
||||||
''',
|
''',
|
||||||
start="expr",
|
|
||||||
regex=True
|
regex=True
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# KLASSE: Syntaxbaum
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class SyntaxBaum(object):
|
||||||
|
expr: str;
|
||||||
|
kind: str;
|
||||||
|
children: List[SyntaxBaum];
|
||||||
|
tree: Tree;
|
||||||
|
|
||||||
|
def __init__(self, fml: Tree):
|
||||||
|
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 teilfml in fml.children:
|
||||||
|
if isinstance(teilfml, str):
|
||||||
|
signature_parts.append(teilfml);
|
||||||
|
elif teilfml.data == 'symb':
|
||||||
|
signature_parts.append(getText(teilfml));
|
||||||
|
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' ]:
|
||||||
|
self.expr = '( {} )'.format(self.expr);
|
||||||
|
return;
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.expr;
|
||||||
|
|
||||||
|
def pretty(self):
|
||||||
|
return self.tree.pretty();
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# METHODE: string -> Syntaxbaum
|
# METHODE: string -> Syntaxbaum
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def stringToSyntaxbaum(u: str) -> Tree:
|
def stringToSyntaxbaum(u: str) -> SyntaxBaum:
|
||||||
try:
|
try:
|
||||||
u_lexed = lexerAussagenlogik.parse(u);
|
return SyntaxBaum(lexerAussagenlogik.parse(u));
|
||||||
return u_lexed;
|
|
||||||
except:
|
except:
|
||||||
raise Exception('Ausdruck \033[1m{}\033[0m konnte nicht erkannt werden!'.format(u));
|
raise Exception('Ausdruck \033[1m{}\033[0m konnte nicht erkannt werden!'.format(u));
|
||||||
|
|
||||||
@ -67,47 +110,52 @@ def stringToSyntaxbaum(u: str) -> Tree:
|
|||||||
# METHODEN: Erkennung von Formeltypen
|
# METHODEN: Erkennung von Formeltypen
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def isAtom(fml: Tree) -> bool:
|
def isAtom(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'atom';
|
return fml.kind == 'atom';
|
||||||
|
|
||||||
def isBeliebig(fml: Tree) -> bool:
|
def isBeliebig(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'beliebig';
|
return fml.kind == 'beliebig';
|
||||||
|
|
||||||
def isTrueSymbol(fml: Tree) -> bool:
|
def isTrueSymbol(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'wahr';
|
return fml.kind == 'taut';
|
||||||
|
|
||||||
def isFalseSymbol(fml: Tree) -> bool:
|
def isFalseSymbol(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'falsch';
|
return fml.kind == 'kontr';
|
||||||
|
|
||||||
def isNegation(fml: Tree) -> bool:
|
def isNegation(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'negation';
|
return fml.kind == 'neg';
|
||||||
|
|
||||||
def isConjunction(fml: Tree) -> bool:
|
def isConjunction(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'konjunktion';
|
return fml.kind == 'konj';
|
||||||
|
|
||||||
def isDisjunction(fml: Tree) -> bool:
|
def isLongConjunction(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'disjunktion';
|
return fml.kind == 'konj_lang';
|
||||||
|
|
||||||
def isImplication(fml: Tree) -> bool:
|
def isDisjunction(fml: SyntaxBaum) -> bool:
|
||||||
return fml.data == 'implikation';
|
return fml.kind == 'disj';
|
||||||
|
|
||||||
|
def isLongDisjunction(fml: SyntaxBaum) -> bool:
|
||||||
|
return fml.kind == 'disj_lang';
|
||||||
|
|
||||||
|
def isImplication(fml: SyntaxBaum) -> bool:
|
||||||
|
return fml.kind == 'impl';
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# METHODEN: Formel -> Teilformeln
|
# METHODEN: Formel -> Textinhalt
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def getTeilformeln(fml: Tree) -> List[Tree]:
|
def getText(fml: Tree) -> str:
|
||||||
return [
|
|
||||||
part for part in fml.children
|
|
||||||
if isinstance(part, Tree)
|
|
||||||
and not part.data == 'junktor'
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# METHODEN: Formel (Atom/Beliebig) -> Name
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def getName(fml: Tree) -> str:
|
|
||||||
text = fml.children[0];
|
text = fml.children[0];
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
return text;
|
return text;
|
||||||
raise Exception('Konnte Textinhalt nicht ablesen!');
|
raise Exception('Konnte Textinhalt nicht ablesen!');
|
||||||
|
|
||||||
|
def getName(fml: SyntaxBaum) -> str:
|
||||||
|
return fml.expr;
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# METHODEN: Formel -> Textinhalt
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
def prettifyTree(fml: Union[Tree, SyntaxBaum]) -> str:
|
||||||
|
return fml.pretty();
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# expr = "( A0 && A1 )"
|
# expr = "( A0 && A1 )"
|
||||||
# expr = "( A0 || A1 )"
|
# expr = "( A0 || A1 )"
|
||||||
# expr = "( A0 -> A1 )"
|
# expr = "( A0 -> A1 )"
|
||||||
expr = "( A0 -> ((A0 && A3) || ! A2) )"
|
expr = "( A0 -> ((A0 && A3 && A4) || ! A2) )"
|
||||||
# expr = "( A0 -> ((A0 && A3) || A2) )"
|
# expr = "( A0 -> ((A0 && A3) || A2) )"
|
||||||
# expr = "(( {G} || !{G} ) -> A5)"
|
# expr = "(( {G} || !{G} ) -> A5)"
|
||||||
interpretation = "[ 'A0', 'A2' ]"
|
interpretation = "[ 'A0', 'A2' ]"
|
||||||
|
28
code/main.py
28
code/main.py
@ -5,7 +5,6 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from __future__ import annotations;
|
|
||||||
import os;
|
import os;
|
||||||
import sys;
|
import sys;
|
||||||
# sys.tracebacklimit = 0;
|
# sys.tracebacklimit = 0;
|
||||||
@ -16,7 +15,9 @@ from typing import List;
|
|||||||
|
|
||||||
sys.path.insert(0, os.getcwd());
|
sys.path.insert(0, os.getcwd());
|
||||||
|
|
||||||
|
from aussagenlogik.schema import prettifyTree;
|
||||||
from aussagenlogik.schema import stringToSyntaxbaum;
|
from aussagenlogik.schema import stringToSyntaxbaum;
|
||||||
|
from aussagenlogik.schema import SyntaxBaum;
|
||||||
from aussagenlogik.rekursion import rekursiv_eval;
|
from aussagenlogik.rekursion import rekursiv_eval;
|
||||||
from aussagenlogik.rekursion import rekursiv_atoms;
|
from aussagenlogik.rekursion import rekursiv_atoms;
|
||||||
from aussagenlogik.rekursion import rekursiv_depth;
|
from aussagenlogik.rekursion import rekursiv_depth;
|
||||||
@ -37,17 +38,17 @@ def main():
|
|||||||
## Daten einlesen:
|
## Daten einlesen:
|
||||||
expr, I = getData();
|
expr, I = getData();
|
||||||
## Formel in Teilformeln zerlegen:
|
## Formel in Teilformeln zerlegen:
|
||||||
tree = stringToSyntaxbaum(expr);
|
fml = stringToSyntaxbaum(expr);
|
||||||
## Methoden ausführen:
|
## Methoden ausführen:
|
||||||
results = dict(
|
results = dict(
|
||||||
eval = rekursiv_eval(tree, I),
|
eval = rekursiv_eval(fml, I),
|
||||||
atoms = rekursiv_atoms(tree),
|
atoms = rekursiv_atoms(fml),
|
||||||
d = rekursiv_depth(tree),
|
d = rekursiv_depth(fml),
|
||||||
l = rekursiv_length(tree),
|
l = rekursiv_length(fml),
|
||||||
p = rekursiv_parentheses(tree),
|
p = rekursiv_parentheses(fml),
|
||||||
);
|
);
|
||||||
## Resultate anzeigen:
|
## Resultate anzeigen:
|
||||||
display_results(expr, tree, I, results);
|
display_results(expr, fml, I, results);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
@ -61,17 +62,18 @@ def getData():
|
|||||||
I = eval(data['interpretation'] or '[]');
|
I = eval(data['interpretation'] or '[]');
|
||||||
return expr, I;
|
return expr, I;
|
||||||
|
|
||||||
def display_results(expr: str, tree: Tree, I: List[str], results: dict):
|
def display_results(expr: str, fml: SyntaxBaum, I: List[str], results: dict):
|
||||||
print(dedent(
|
print(dedent(
|
||||||
'''
|
'''
|
||||||
Syntaxbaum von
|
Syntaxbaum von
|
||||||
F := \033[92;1m{F}\033[0m:
|
F := \033[92;1m{F}\033[0m:
|
||||||
'''.format(F=expr)
|
'''.format(F=fml)
|
||||||
));
|
));
|
||||||
print(tree.pretty());
|
print(prettifyTree(fml));
|
||||||
print(dedent(
|
print(dedent(
|
||||||
'''
|
'''
|
||||||
eval(F, I) = \033[94;1m{eval}\033[0m;
|
Für I = [{I}] und F wie oben gilt
|
||||||
|
eval(F, I) = \033[94;1m{eval}\033[0m,
|
||||||
\033[2matoms(F) = \033[94;1m{atoms}\033[0m; \033[91;1m<- *\033[0m
|
\033[2matoms(F) = \033[94;1m{atoms}\033[0m; \033[91;1m<- *\033[0m
|
||||||
\033[2mdepth(F) = \033[94;1m{d}\033[0m; \033[91;1m<- *\033[0m
|
\033[2mdepth(F) = \033[94;1m{d}\033[0m; \033[91;1m<- *\033[0m
|
||||||
\033[2mlength(F) = \033[94;1m{l}\033[0m; \033[91;1m<- *\033[0m
|
\033[2mlength(F) = \033[94;1m{l}\033[0m; \033[91;1m<- *\033[0m
|
||||||
@ -79,7 +81,7 @@ def display_results(expr: str, tree: Tree, I: List[str], results: dict):
|
|||||||
|
|
||||||
\033[91;1m*\033[0m \033[2mnoch nicht implementiert!\033[0m
|
\033[91;1m*\033[0m \033[2mnoch nicht implementiert!\033[0m
|
||||||
\033[1;2;4mChallenge:\033[0m \033[2mschreibe diese Methoden! (siehe README.md)\033[0m
|
\033[1;2;4mChallenge:\033[0m \033[2mschreibe diese Methoden! (siehe README.md)\033[0m
|
||||||
'''.format(**results)
|
'''.format(**results, I=', '.join(I))
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user