2021-05-05 11:07:32 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# IMPORTS
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
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 lark import Tree;
|
2021-05-06 15:29:44 +02:00
|
|
|
from typing import List;
|
2021-05-06 23:34:25 +02:00
|
|
|
from typing import Union;
|
2021-05-05 11:07:32 +02:00
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2021-05-06 12:44:29 +02:00
|
|
|
# GLOBALE KONSTANTEN
|
2021-05-05 11:07:32 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
## lexer
|
2021-05-07 06:37:32 +02:00
|
|
|
with open('aussagenlogik/grammar.lark', 'r') as fp:
|
|
|
|
grammar = ''.join(fp.readlines());
|
|
|
|
lexerAussagenlogik = Lark(grammar, start='expr', regex=True);
|
2021-05-05 11:07:32 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# 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' ]:
|
2021-05-07 06:37:32 +02:00
|
|
|
self.expr = ('(' if self.expr.startswith('(') else '( ') + self.expr;
|
|
|
|
self.expr += (')' if self.expr.endswith(')') else ' )');
|
2021-05-06 23:34:25 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.expr;
|
|
|
|
|
|
|
|
def pretty(self):
|
2021-05-07 06:37:32 +02:00
|
|
|
return self.tree.pretty(indent_str='- ');
|
2021-05-06 23:34:25 +02:00
|
|
|
|
2021-05-05 11:07:32 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2021-05-06 15:29:44 +02:00
|
|
|
# METHODE: string -> Syntaxbaum
|
2021-05-05 11:07:32 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def stringToSyntaxbaum(u: str) -> SyntaxBaum:
|
2021-05-05 11:07:32 +02:00
|
|
|
try:
|
2021-05-06 23:34:25 +02:00
|
|
|
return SyntaxBaum(lexerAussagenlogik.parse(u));
|
2021-05-05 11:07:32 +02:00
|
|
|
except:
|
|
|
|
raise Exception('Ausdruck \033[1m{}\033[0m konnte nicht erkannt werden!'.format(u));
|
2021-05-06 15:29:44 +02:00
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# METHODEN: Erkennung von Formeltypen
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isAtom(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'atom';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isBeliebig(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'beliebig';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isTrueSymbol(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'taut';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isFalseSymbol(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'kontr';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isNegation(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'neg';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isConjunction(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'konj';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isLongConjunction(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'konj_lang';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isDisjunction(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'disj';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isLongDisjunction(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'disj_lang';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def isImplication(fml: SyntaxBaum) -> bool:
|
|
|
|
return fml.kind == 'impl';
|
2021-05-06 15:29:44 +02:00
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2021-05-06 23:34:25 +02:00
|
|
|
# METHODEN: Formel -> Textinhalt
|
2021-05-06 15:29:44 +02:00
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2021-05-06 23:34:25 +02:00
|
|
|
def getText(fml: Tree) -> str:
|
2021-05-06 15:29:44 +02:00
|
|
|
text = fml.children[0];
|
|
|
|
if isinstance(text, str):
|
|
|
|
return text;
|
|
|
|
raise Exception('Konnte Textinhalt nicht ablesen!');
|
2021-05-06 23:34:25 +02:00
|
|
|
|
|
|
|
def getName(fml: SyntaxBaum) -> str:
|
|
|
|
return fml.expr;
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
# METHODEN: Formel -> Textinhalt
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
def prettifyTree(fml: Union[Tree, SyntaxBaum]) -> str:
|
|
|
|
return fml.pretty();
|