readme
This commit is contained in:
parent
23abf51c5f
commit
fddaec2b01
12
program.py
12
program.py
@ -4,7 +4,7 @@ import subprocess
|
|||||||
class AbstractInterpreter:
|
class AbstractInterpreter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
def isValid(self,formula:str)->bool:
|
def isValid(self,formula)->bool:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
class SimpleInterpreter(AbstractInterpreter):
|
class SimpleInterpreter(AbstractInterpreter):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -34,7 +34,7 @@ class SimpleInterpreter(AbstractInterpreter):
|
|||||||
return False
|
return False
|
||||||
if (prev is None):
|
if (prev is None):
|
||||||
if not (isVariable(char) or isParentice(char) or isNegation(char)):
|
if not (isVariable(char) or isParentice(char) or isNegation(char)):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
if isSign(char) and prev is not None:
|
if isSign(char) and prev is not None:
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ class SimpleInterpreter(AbstractInterpreter):
|
|||||||
if isNegation(char):
|
if isNegation(char):
|
||||||
if isVariable(prev): #a!
|
if isVariable(prev): #a!
|
||||||
return False
|
return False
|
||||||
else:
|
elif not isSign(char) and prev is not None:
|
||||||
#if current char is a variable
|
#if current char is a variable
|
||||||
if isVariable(prev) and prev is not None: #Obrona abc>d
|
if isVariable(prev) and prev is not None: #Obrona abc>d
|
||||||
print("previous is also a variable");
|
print("previous is also a variable");
|
||||||
@ -112,7 +112,7 @@ class ProperInterpreter(AbstractInterpreter):
|
|||||||
try:
|
try:
|
||||||
self.parse(formula.s)
|
self.parse(formula.s)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
#print(e)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
@ -144,7 +144,7 @@ class ProperInterpreter(AbstractInterpreter):
|
|||||||
if current_depth!=0:
|
if current_depth!=0:
|
||||||
raise Exception("Nawiasy źle umieszczone w podformule: {0}".format(formula))
|
raise Exception("Nawiasy źle umieszczone w podformule: {0}".format(formula))
|
||||||
|
|
||||||
print(formula)
|
#print(formula)
|
||||||
|
|
||||||
min_depth = min(x)
|
min_depth = min(x)
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ if len(sys.argv) > 1 :
|
|||||||
g = open(sys.argv[sys.argv.index('-f')+1], 'r')
|
g = open(sys.argv[sys.argv.index('-f')+1], 'r')
|
||||||
u = g.readlines()
|
u = g.readlines()
|
||||||
for l in u:
|
for l in u:
|
||||||
print(Formula(l,i).isValid())
|
print(Formula(l.replace("\n",'').replace("\r",''),i).isValid())
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
Formula(sys.argv[1] if sys.argv[1] != '-g' else sys.argv[2],i).isValid()
|
Formula(sys.argv[1] if sys.argv[1] != '-g' else sys.argv[2],i).isValid()
|
||||||
|
48
readme.md
Normal file
48
readme.md
Normal 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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user