This commit is contained in:
emilekm2142 2019-05-31 19:25:20 +02:00
parent 23abf51c5f
commit fddaec2b01
3 changed files with 61 additions and 6 deletions

View File

@ -4,7 +4,7 @@ import subprocess
class AbstractInterpreter:
def __init__(self):
pass
def isValid(self,formula:str)->bool:
def isValid(self,formula)->bool:
raise NotImplementedError
class SimpleInterpreter(AbstractInterpreter):
def __init__(self):
@ -34,7 +34,7 @@ class SimpleInterpreter(AbstractInterpreter):
return False
if (prev is None):
if not (isVariable(char) or isParentice(char) or isNegation(char)):
return False
if isSign(char) and prev is not None:
@ -50,7 +50,7 @@ class SimpleInterpreter(AbstractInterpreter):
if isNegation(char):
if isVariable(prev): #a!
return False
else:
elif not isSign(char) and prev is not None:
#if current char is a variable
if isVariable(prev) and prev is not None: #Obrona abc>d
print("previous is also a variable");
@ -112,7 +112,7 @@ class ProperInterpreter(AbstractInterpreter):
try:
self.parse(formula.s)
except Exception as e:
print(e)
#print(e)
return False
else:
return True
@ -144,7 +144,7 @@ class ProperInterpreter(AbstractInterpreter):
if current_depth!=0:
raise Exception("Nawiasy źle umieszczone w podformule: {0}".format(formula))
print(formula)
#print(formula)
min_depth = min(x)
@ -203,7 +203,7 @@ if len(sys.argv) > 1 :
g = open(sys.argv[sys.argv.index('-f')+1], 'r')
u = g.readlines()
for l in u:
print(Formula(l,i).isValid())
print(Formula(l.replace("\n",'').replace("\r",''),i).isValid())
else:
print(
Formula(sys.argv[1] if sys.argv[1] != '-g' else sys.argv[2],i).isValid()

48
readme.md Normal file
View File

@ -0,0 +1,48 @@
#Uzycie
`python program.py -f plik.txt`, gdzie każda linia to nowa formuła
`python program.py a&b>c|(a&!g)`
Opcjonalny przełącznik `-g`, który przełącza tryb sprawdzania na Regexp
#Założenia:
1. Algorytm sprawdzający poprawność nie musi parsować wyrażenia
2. Można było po prostu napisać parser - gdy formuła nie będzie poprawna to gdzieś dostaniemy błąd - ciekawiej jest jednak wymyślić coś nowego samemu.
#Co to jest poprawna formuła?
Dowolne wyrażenie KRZ, gdzie zmienną jest dowolny znak od `a` do `z` A znakiem specjalnym jest znak zawierający się w zbiorze { (, ), &, >, =, | }. Nawiasy muszą być zamknięte
#Algorytm
W osobnej tablicy o długości równej ilości znaków formuły zapisujemy `głębkość` (dalej nazywaną `depth`) danego znaku. Nim bardziej zagnieżdżone jest podwyrażenie, tym większa wartość `głębkokości`. Tak dla formuły `a>b`, tablica `depth` przyjmie wartości `0,0,0`, ale dla `a|(a&b)>(c|q)` będzie to już `0,0,1,1,1,1,1,0,1,1,1,1,1`. Widać zatem, że można tak znaleźć zagnieżdżone podformuły.
Algorytm szuka pierwszego znaku z wartością `depth` równą `min(depth)`, który jest operatorem dwuargumentowym. Formuła jest dzielona na stronę prawą i lewą od operatora i proces jest powtarzany aż do momentu, kiedy nie będzie już żadnych formuł zagnieżdżonych tj. kiedy wszystkie wartości w tablicy `depth`, będą równe `min(depth)`.
Występują przypadki skrajne, gdzie lewa bądź prawa część jest pusta - wtedy kończy się rekurencja na danej gałęzi.
Gdy spełniony jest wcześniej wspomniany warunek, uruchamiana jest inna procedura, która bada czy nie występują zabronione ciągi. Są one zapisane jak sztywny zbiór reguł. Algorytm iteruje przez każdy znak w formule, pamiętając swojego poprzednika.
Istnieje skończona ilość reguł, które określają formułę jako niepoprawną.
1. Błędnie postawione nawiasy
2. Negacja za zmienną bądź przed innym operatorem
3. Dwa operatory obok siebie
4. Dwie zmienne obok siebie
5. Zmienna po lewej stronie nawiasu otwierającego lub po prawej zamykającego
6. Operator dwuargumentowy bez wyrażeń po obu stronach
#Przełącznik -g
Zadaniem było tylko sprawdzenie, czy formuła jest poprawnie zapisana. Jak zostało wcześniej wspomniane istnieje skończona ilość reguł które mówią że formuła jest **niepoprawna**.
Można więc przeszukiwać formułę w poszukiwaniu niepoprawnych ciągów. Do przeszukiwania tekstu w poszukiwaniu wzorców idealnie nadaje się dowolny silnik wyrażeń regularnych (ten z pythona nie miał opcji przeszukiwania rekursywnego, więc używamy programu `grep` z przełącznikiem `-P` żeby przełączyć się na silnik z Perla - jest to potrzebne przy sprawdzaniu, czy nawiasy są poprawnie zamknięte).
Dla każdej z powyższych reguł można sformułować odpowiednie wyrażenie, które znajdując (bądź nie) dopasowanie poinformuje nas czy formuła zawiera jakiś niedozwolony ciąg.
Taki sposób jest o wiele wolniejszy i mniej ciekawy niż poprzedni, ale też działa. Do tego, wyrażenia KRZ nie są regularne, więc używanie narzędzia zupełnie do tego nieprzeznaczonego wydało się nam ciekawe do zaprezentowania.

7
testy.txt Normal file
View File

@ -0,0 +1,7 @@
(a>)
(>)
()(a)
a
a(b&c)>d
(b&d)d
(a>b)>k