diff --git a/program.py b/program.py index cc565f8..b918dcf 100644 --- a/program.py +++ b/program.py @@ -1,15 +1,16 @@ import sys +import subprocess #TODO: dodać parentices class AbstractInterpreter: def __init__(self): pass - def isValid(formula:str)->bool: + def isValid(self,formula:str)->bool: raise NotImplementedError class SimpleInterpreter(AbstractInterpreter): def __init__(self): pass def isValid(self,formula)->bool: - print("is valid?") + variables = {} f=[] def isBlacklisted(char): @@ -17,6 +18,8 @@ class SimpleInterpreter(AbstractInterpreter): def isSign(char): logic_signs = ['=', '>', '&', '|', '!', '(', ')'] return char in logic_signs + def isParentice(char): + return char in ('(', ')') def isVariable(char): return not isSign(char) def isNegation(char): @@ -24,14 +27,16 @@ class SimpleInterpreter(AbstractInterpreter): #print(vars(formula)) for i,char in enumerate(formula.s): if isBlacklisted(char): return False - print(char) + prev = formula.s[i-1] if i>0 else None #None, gdy jesteśmy na pierwszym znaku + if (char=='(' and isVariable(prev) and prev is not None): #a(b|c) + return False if isSign(char): if (not isNegation(char)): if isSign(prev) and not isNegation(prev): # tylko negacje mogą się powtarzać po innym znaku return False else: - if isVariable(prev): # obrona przed a!>b + if isVariable(prev) and prev is not None: # obrona przed a!>b return False else: #if current char is a variable @@ -43,16 +48,24 @@ class RegexInterpreter(AbstractInterpreter): def __init__(self): #check if grep is available import subprocess - r=subprocess.run("grep") + # r=subprocess.run("grep") - def isValid(self,formula)->bool: + def isValid(self,f)->bool: + formula = f.s.replace("!", "\\!") + make_reg = lambda formula,pattern: 'echo "{0}" | grep -P "{1}"'.format(formula,pattern) def check_assertion(formula, pattern): - result = subprocess.run([make_reg(formula,pattern)], shell=True, stdout=subprocess.PIPE) + cmd = make_reg(formula,pattern) + print("EXECUTING... ",cmd) + result = subprocess.run([cmd], shell=True, stdout=subprocess.PIPE) return len(result.stdout)>0 - - result = subprocess.run([make_reg(formula,'^(\((?:[^()]++|(?1))*\))$')], shell=True, stdout=subprocess.PIPE) + + cmd =make_reg(formula,'^(\((?:[^()]++|(?1))*\))$') + print("EXECUTING... ",cmd) + + result = subprocess.run([cmd], shell=True, stdout=subprocess.PIPE) + return None isValid = len(result.stdout)>0 if not isValid: return False @@ -74,31 +87,114 @@ class RegexInterpreter(AbstractInterpreter): # \((?:[>|&|\|=][\(\)]*) - (>b) # [a-z]{2,} - czy powtarzają się jakieś lierki obok siebie? # \((?:[>|&|\|=|!])?\) - czy istnieją puste nawiasy, bądź nawiasy z samym operatorem? +class ProperInterpreter(AbstractInterpreter): + class Expression: + def __init__(self,operator,left,right): + self.right=right + self.left = left + self.operator = operator + + def __init__(self): + pass + def isValid(self,formula)->bool: + try: + self.parse(formula.s) + except Exception as e: + print(e) + return False + else: + return True + def check_simple_formula(self,simple_formula:str)->bool: + #używamy SimpleInterpretera + n = SimpleInterpreter() + return Formula(simple_formula,n).isValid() + def parse(self,formula:str): + #przypisywanie głębi do każdego znaku + if len(formula)==0: + # print("Empty subformula") + return None + x=[0 for u in formula] + current_depth=0 + for i,char in enumerate(formula): + if current_depth<0: + break + if char == '(': + current_depth+=1 + x[i] = current_depth + elif char == ')': + x[i] = current_depth + current_depth-=1 + else: + x[i] = current_depth + + + if current_depth!=0: + raise Exception("Nawiasy źle umieszczone w podformule: {0}".format(formula)) + + #print(formula) + + min_depth = min(x) + + slice_point = 0 + #czy formuła jest prosta? + is_simple = True + for i in x: + if i != x[0]: + is_simple=False; + break + #Szukanie najbardziej znaczącego spójnika + for i,char in enumerate(formula): + if char in ('>', '&', '|', '=') and x[i] == min_depth: + slice_point = i + break + if is_simple: + # print(formula, " is simple") + if not self.check_simple_formula(formula): + raise Exception("Błąd na poziomie formuły bez zagnieżdzeń: {0}".format(formula)) + return False + + else: + s=0 + e=len(formula) + if min_depth>0: + # print("There are useless parentices... Deleting") + s=1 + e=-1 + # print("Slice point: ", slice_point) + # print("min depth: ", min_depth) + if (s==slice_point): + #print("Nie ma spójnika - formuła jest jednak prosta") + if not self.check_simple_formula(formula): + raise Exception("Błąd na poziomie formuły bez zagnieżdzeń: {0}".format(formula)) + return False + self.parse(formula[s:slice_point]) + self.parse(formula[slice_point+1:e]) class Formula: - def __init__(self, formula_string:str, interpreter:AbstractInterpreter): + def __init__(self, formula_string:str, interpreter:AbstractInterpreter=None): self.s = formula_string self.__i = interpreter - if not self.isValid(self.__i): - assert "formula in invalid!" - else: - print("given formula is valid") - def isValid(self, interpreter)->bool: - return interpreter.isValid(self) + def isValid(self, interpreter=None)->bool: + i = self.__i if interpreter is None else interpreter + return i.isValid(self) -#g = RegexInterpreter() -i = SimpleInterpreter() -print(sys.argv) -if sys.argv[1] == '-f': - #open from file - print("opening from file") - g = open(sys.argv[1], 'r') - u = g.readlines() - for l in u: - Formula(l,i) -else: - Formula( sys.argv[1],i) +if len(sys.argv) > 1 : + i = ProperInterpreter() + if '-g' in sys.argv: + i = RegexInterpreter() + print(sys.argv) + + if '-f' in sys.argv: + #open from file + print("opening from file") + g = open(sys.argv[sys.argv.index('-f')+1], 'r') + u = g.readlines() + for l in u: + print(Formula(l,i).isValid()) + else: + print(Formula( sys.argv[1],i).isValid()) - +else: + print("help?")