expert-system
This commit is contained in:
parent
e3ded9ec84
commit
fdf374dcd7
|
@ -1,4 +1,3 @@
|
||||||
# ---> Python
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
@ -48,7 +47,6 @@ htmlcov/
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
*.cover
|
*.cover
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
|
|
||||||
|
@ -60,7 +58,6 @@ coverage.xml
|
||||||
*.log
|
*.log
|
||||||
local_settings.py
|
local_settings.py
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
# Flask stuff:
|
||||||
instance/
|
instance/
|
||||||
|
@ -85,19 +82,8 @@ ipython_config.py
|
||||||
# pyenv
|
# pyenv
|
||||||
.python-version
|
.python-version
|
||||||
|
|
||||||
# pipenv
|
# celery beat schedule file
|
||||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
||||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
||||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
||||||
# install all needed dependencies.
|
|
||||||
#Pipfile.lock
|
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
||||||
__pypackages__/
|
|
||||||
|
|
||||||
# Celery stuff
|
|
||||||
celerybeat-schedule
|
celerybeat-schedule
|
||||||
celerybeat.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
# SageMath parsed files
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
@ -129,3 +115,27 @@ dmypy.json
|
||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
|
wap
|
||||||
|
[._]*.s[a-v][a-z]
|
||||||
|
[._]*.sw[a-p]
|
||||||
|
[._]s[a-rt-v][a-z]
|
||||||
|
[._]ss[a-gi-z]
|
||||||
|
[._]sw[a-p]
|
||||||
|
|
||||||
|
# Session
|
||||||
|
Session.vim
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
.netrwhist
|
||||||
|
*~
|
||||||
|
# Auto-generated tag files
|
||||||
|
tags
|
||||||
|
# Persistent undo
|
||||||
|
[._]*.un~
|
||||||
|
|
||||||
|
#VSCODE
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
class Ft_op:
|
||||||
|
|
||||||
|
# def __init__ (self):
|
||||||
|
def ft_and(a, b):
|
||||||
|
return a & b
|
||||||
|
|
||||||
|
def ft_or(a, b):
|
||||||
|
return a | b
|
||||||
|
|
||||||
|
def ft_xor(a, b):
|
||||||
|
return a ^ b
|
||||||
|
|
||||||
|
def ft_not(a, b):
|
||||||
|
return not a
|
|
@ -0,0 +1,60 @@
|
||||||
|
from fact import Fact, check_fact
|
||||||
|
from user import *
|
||||||
|
from Ft_op import Ft_op
|
||||||
|
from config import *
|
||||||
|
import config
|
||||||
|
|
||||||
|
@v_args(inline=True) # Affects the signatures of the methods
|
||||||
|
class InferenceEngine(Transformer):
|
||||||
|
|
||||||
|
def iter_subtree(self, fact_tree):
|
||||||
|
for fact in fact_tree.children:
|
||||||
|
self.set_fact(str(fact))
|
||||||
|
|
||||||
|
def set_fact(self, *string):
|
||||||
|
for letter in string:
|
||||||
|
self.assign_var(letter, True)
|
||||||
|
|
||||||
|
def print_state(self, string):
|
||||||
|
for letter in string:
|
||||||
|
print(letter, '=', self.var(letter))
|
||||||
|
|
||||||
|
def apply_func(self, tree):
|
||||||
|
if (isinstance(tree, Tree) == False):
|
||||||
|
return self.var(str(tree))
|
||||||
|
else:
|
||||||
|
return getattr(Ft_op, tree.data)(self.apply_func(tree.children[0]),
|
||||||
|
self.apply_func(tree.children[1] if len(tree.children) > 1 else 0))
|
||||||
|
|
||||||
|
def assign_var(self, name, state):
|
||||||
|
config.fact_dict[name] = Fact(state=state, key=name, isset=True)
|
||||||
|
return state
|
||||||
|
|
||||||
|
def var(self, name):
|
||||||
|
if (config.glob != True):
|
||||||
|
return name
|
||||||
|
if (config.fact_dict.get(name) == None):
|
||||||
|
config.fact_dict[name] = Fact(key=name)
|
||||||
|
return config.fact_dict[name].get_state(self)
|
||||||
|
|
||||||
|
|
||||||
|
def set_state(self, tree, op_tree, is_not=False, is_iff=False):
|
||||||
|
if (isinstance(tree, Tree) == False):
|
||||||
|
check_fact(str(tree))
|
||||||
|
config.fact_dict[str(tree)].trees.append((op_tree, is_not, is_iff))
|
||||||
|
elif (tree.data == 'ft_and'):
|
||||||
|
self.set_state(tree.children[0], op_tree, is_not, is_iff)
|
||||||
|
self.set_state(tree.children[1], op_tree, is_not, is_iff)
|
||||||
|
elif (tree.data == 'ft_not'):
|
||||||
|
self.set_state(tree.children[0], op_tree, not is_not)
|
||||||
|
elif (tree.data == 'ft_or'):
|
||||||
|
choice = ask_or(tree)
|
||||||
|
if (choice is 2):
|
||||||
|
self.set_state(tree.children[0], op_tree, is_not, is_iff)
|
||||||
|
self.set_state(tree.children[1], op_tree, is_not, is_iff)
|
||||||
|
else:
|
||||||
|
self.set_state(tree.children[choice], op_tree, is_not, is_iff)
|
||||||
|
elif (tree.data == 'ft_xor'):
|
||||||
|
choice = ask_xor(tree)
|
||||||
|
self.set_state(tree.children[choice], op_tree, False, is_iff)
|
||||||
|
self.set_state(tree.children[not choice], op_tree, True, is_iff)
|
|
@ -0,0 +1,8 @@
|
||||||
|
from lark import Lark, Transformer, v_args, Tree
|
||||||
|
from InferenceEngine import InferenceEngine
|
||||||
|
computer = InferenceEngine()
|
||||||
|
pstr ="\033[1;32m--->\033[0m"
|
||||||
|
skip = False
|
||||||
|
glob = False
|
||||||
|
fact_dict = {}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import sys
|
||||||
|
from user import *
|
||||||
|
from lark import Tree
|
||||||
|
import config
|
||||||
|
|
||||||
|
def check_fact(key, state=False):
|
||||||
|
|
||||||
|
if (config.fact_dict.get(key) == None):
|
||||||
|
config.fact_dict[key] = Fact(state, key)
|
||||||
|
|
||||||
|
class Fact:
|
||||||
|
|
||||||
|
def __init__(self, state = False, key = 0, isset=False):
|
||||||
|
self.trees = list()
|
||||||
|
self.isset = isset
|
||||||
|
self.mutex_lock = 0
|
||||||
|
self.key = key
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
def check_fact(self,fact):
|
||||||
|
if (self.key == str(fact)):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def remove_tree(self, tree, idx, computer):
|
||||||
|
if (config.skip):
|
||||||
|
sys.exit('Conflict between rules')
|
||||||
|
choice = 'w'
|
||||||
|
st = ("<=>" if tree[2] else "=>") + ('!' if tree[1] else '') + self.key
|
||||||
|
while choice not in ['y', 'n']:
|
||||||
|
choice = input(str("There is an error in operation, would you like to remove this one ? {"
|
||||||
|
+ set_choices(tree[0]) + st+ "} y/n?\n"))
|
||||||
|
if (choice == 'n'):
|
||||||
|
sys.exit('Conflict between rules')
|
||||||
|
self.trees.pop(idx)
|
||||||
|
return self.get_state(computer)
|
||||||
|
|
||||||
|
def check_imply(self,tree):
|
||||||
|
ret = 0
|
||||||
|
if (isinstance(tree, Tree)):
|
||||||
|
fact = tree.find_data("query")
|
||||||
|
for truc in fact:
|
||||||
|
ret = self.check_fact(fact)
|
||||||
|
else:
|
||||||
|
ret = self.check_fact(tree)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def get_state(self, computer):
|
||||||
|
if (self.mutex_lock >= 2):
|
||||||
|
return self.state
|
||||||
|
self.mutex_lock += 1
|
||||||
|
config.glob = True
|
||||||
|
idx =0
|
||||||
|
for tree in self.trees:
|
||||||
|
is_set = self.isset is True or idx > 0
|
||||||
|
if (self.check_imply(tree[0]) and tree[1] is True):
|
||||||
|
return self.remove_tree(tree, idx, computer)
|
||||||
|
new_state = computer.apply_func(tree[0])
|
||||||
|
if new_state is False :
|
||||||
|
continue
|
||||||
|
new_state = False if tree[1] and new_state is True else True
|
||||||
|
if (tree[2] is False and is_set and new_state != self.state):
|
||||||
|
return self.remove_tree(tree, idx, computer)
|
||||||
|
self.state |= new_state
|
||||||
|
idx+=1
|
||||||
|
self.mutex_lock -= 1
|
||||||
|
return self.state
|
|
@ -0,0 +1,71 @@
|
||||||
|
import config
|
||||||
|
from config import *
|
||||||
|
from parse import *
|
||||||
|
|
||||||
|
interactive_grammar = r"""
|
||||||
|
?start: imply
|
||||||
|
| initial_fact | query
|
||||||
|
|
||||||
|
?imply: xor "=>" xor -> imply
|
||||||
|
| xor "<=>" xor -> iff
|
||||||
|
?xor: or
|
||||||
|
| xor "^" or -> ft_xor
|
||||||
|
?or: and
|
||||||
|
| or "|" and -> ft_or
|
||||||
|
?and: atom
|
||||||
|
| and "+" atom -> ft_and
|
||||||
|
?atom: UCASE_LETTER -> var
|
||||||
|
| "!" atom -> ft_not
|
||||||
|
| "(" xor ")"
|
||||||
|
|
||||||
|
?initial_fact: "=" UCASE_LETTER* -> set_fact
|
||||||
|
?query: "?" UCASE_LETTER+ ->query
|
||||||
|
|
||||||
|
_LI: (_COMMENT | LF+)
|
||||||
|
_COMMENT: /#[^\n].*\n/
|
||||||
|
|
||||||
|
%import common.UCASE_LETTER
|
||||||
|
%import common.NUMBER
|
||||||
|
%import common.WS_INLINE
|
||||||
|
%import common.LF
|
||||||
|
%ignore WS_INLINE
|
||||||
|
%ignore _COMMENT
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def reset_states():
|
||||||
|
for idx in fact_dict:
|
||||||
|
fact_dict[idx].state = False
|
||||||
|
fact_dict[idx].is_set = False
|
||||||
|
|
||||||
|
def interactive():
|
||||||
|
print('Welcome to the best expert system in the world wide web')
|
||||||
|
calc_parser = Lark(interactive_grammar, parser='lalr',
|
||||||
|
debug=True, transformer=computer)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
s = input('> ')
|
||||||
|
except EOFError:
|
||||||
|
break
|
||||||
|
if (s == 'exit'):
|
||||||
|
exit('Good bye')
|
||||||
|
continue
|
||||||
|
elif (s == 'reset'):
|
||||||
|
reset_states()
|
||||||
|
continue
|
||||||
|
elif (s == 'reset --hard'):
|
||||||
|
config.fact_dict = {}
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
tree = calc_parser.parse(s)
|
||||||
|
except UnexpectedInput as e:
|
||||||
|
print(e)
|
||||||
|
continue
|
||||||
|
if (tree == None):
|
||||||
|
continue
|
||||||
|
if (tree.data == "imply" or tree.data == "iff"):
|
||||||
|
set_trees(tree)
|
||||||
|
else:
|
||||||
|
query(tree)
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import argparse
|
||||||
|
from lark import Lark, Transformer, v_args, Tree, UnexpectedInput
|
||||||
|
import traceback
|
||||||
|
import logging
|
||||||
|
from config import *
|
||||||
|
import config
|
||||||
|
import interactive_m
|
||||||
|
|
||||||
|
try:
|
||||||
|
input = raw_input # For Python2 compatibility
|
||||||
|
except NameError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
calc_grammar = r"""
|
||||||
|
?start: (imply _LI)+ initial_fact _LI query _LI
|
||||||
|
|
||||||
|
?imply: xor "=>" xor -> imply
|
||||||
|
| xor "<=>" xor -> iff
|
||||||
|
?xor: or
|
||||||
|
| xor "^" or -> ft_xor
|
||||||
|
?or: and
|
||||||
|
| or "|" and -> ft_or
|
||||||
|
?and: atom
|
||||||
|
| and "+" atom -> ft_and
|
||||||
|
?atom: UCASE_LETTER -> var
|
||||||
|
| "!" atom -> ft_not
|
||||||
|
| "(" xor ")"
|
||||||
|
|
||||||
|
?initial_fact: "=" UCASE_LETTER* -> set_fact
|
||||||
|
?query: "?" UCASE_LETTER+ ->query
|
||||||
|
|
||||||
|
_LI: (_COMMENT | LF+)
|
||||||
|
_COMMENT: /#[^\n].*\n/
|
||||||
|
|
||||||
|
%import common.UCASE_LETTER
|
||||||
|
%import common.NUMBER
|
||||||
|
%import common.WS_INLINE
|
||||||
|
%import common.LF
|
||||||
|
%ignore WS_INLINE
|
||||||
|
%ignore _COMMENT
|
||||||
|
"""
|
||||||
|
|
||||||
|
def set_fact(tree):
|
||||||
|
ifact = tree.find_data("initial_fact")
|
||||||
|
for fact in ifact:
|
||||||
|
computer.iter_subtree(fact)
|
||||||
|
|
||||||
|
def set_trees(tree):
|
||||||
|
implies = tree.find_data("imply")
|
||||||
|
for imply in list(implies):
|
||||||
|
new_tree = imply.children[0]
|
||||||
|
computer.set_state(imply.children[1], new_tree)
|
||||||
|
iffs = tree.find_data("iff")
|
||||||
|
for iff in list(iffs):
|
||||||
|
new_tree1 = iff.children[0]
|
||||||
|
new_tree2 = iff.children[1]
|
||||||
|
computer.set_state(iff.children[1], new_tree1, is_iff=True)
|
||||||
|
computer.set_state(iff.children[0], new_tree2, is_iff=True)
|
||||||
|
|
||||||
|
def query(tree):
|
||||||
|
config.glob = True
|
||||||
|
queries = list(tree.find_data("query"))
|
||||||
|
if (len(queries) <= 0):
|
||||||
|
return
|
||||||
|
st = str()
|
||||||
|
for token in queries[0].children:
|
||||||
|
st += str(token)
|
||||||
|
computer.print_state(st)
|
||||||
|
|
||||||
|
def test(args):
|
||||||
|
if (args.interactive == True):
|
||||||
|
interactive_m.interactive()
|
||||||
|
return
|
||||||
|
calc_parser = Lark(calc_grammar, parser='lalr',
|
||||||
|
debug=True, transformer=computer)
|
||||||
|
with open(args.path, 'r') as myfile:
|
||||||
|
string=myfile.read()
|
||||||
|
print(string)
|
||||||
|
try:
|
||||||
|
tree = calc_parser.parse(string)
|
||||||
|
except UnexpectedInput as e:
|
||||||
|
print(e)
|
||||||
|
return
|
||||||
|
if (args.pretty):
|
||||||
|
print(tree.pretty(pstr))
|
||||||
|
set_trees(tree)
|
||||||
|
query(tree)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Smarter expert system you have ever seen')
|
||||||
|
parser.add_argument("-i", "--interactive", default=False, action="store_true",
|
||||||
|
help="interactive expert system")
|
||||||
|
parser.add_argument("-b", "--batch", default=False, action="store_true",
|
||||||
|
help="run install in batch mode (without manual intervention)")
|
||||||
|
parser.add_argument("-p", "--pretty", default=False, action="store_true",
|
||||||
|
help="print pretty trees")
|
||||||
|
parser.add_argument("path", type=str, default="none", help="input file name")
|
||||||
|
args = parser.parse_args()
|
||||||
|
config.skip = args.batch
|
||||||
|
test(args)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,13 @@
|
||||||
|
B => A
|
||||||
|
D + E => B
|
||||||
|
G + H => F
|
||||||
|
I + J => G
|
||||||
|
G => H
|
||||||
|
L + M => K
|
||||||
|
O + P => L + N
|
||||||
|
N => M
|
||||||
|
|
||||||
|
=DEIJOP
|
||||||
|
?AFKP
|
||||||
|
|
||||||
|
#AFKP is true
|
|
@ -0,0 +1,13 @@
|
||||||
|
B => A
|
||||||
|
D + E => B
|
||||||
|
G + H => F
|
||||||
|
I + J => G
|
||||||
|
G => H
|
||||||
|
L + M => K
|
||||||
|
O + P => L + N
|
||||||
|
N => M
|
||||||
|
|
||||||
|
=DEIJP
|
||||||
|
?AFKP
|
||||||
|
|
||||||
|
#AFP is true, K is false
|
|
@ -0,0 +1,8 @@
|
||||||
|
A <=> B
|
||||||
|
C <=> D
|
||||||
|
C => A
|
||||||
|
=D
|
||||||
|
|
||||||
|
?ABCD
|
||||||
|
|
||||||
|
# ABCD should be true
|
|
@ -0,0 +1,5 @@
|
||||||
|
A => C
|
||||||
|
B => !C
|
||||||
|
|
||||||
|
=
|
||||||
|
?ABC
|
|
@ -0,0 +1,5 @@
|
||||||
|
A => C
|
||||||
|
B => !C
|
||||||
|
|
||||||
|
=A
|
||||||
|
?ABC
|
|
@ -0,0 +1,5 @@
|
||||||
|
A => C
|
||||||
|
B => !C
|
||||||
|
|
||||||
|
=B
|
||||||
|
?ABC
|
|
@ -0,0 +1,5 @@
|
||||||
|
A => C
|
||||||
|
B => !C
|
||||||
|
|
||||||
|
=AB
|
||||||
|
?ABC
|
|
@ -0,0 +1,5 @@
|
||||||
|
B => !C
|
||||||
|
A => C
|
||||||
|
|
||||||
|
=ABC
|
||||||
|
?ABC
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D | E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be false
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D | E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=D
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D | E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=E
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D | E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=DE
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,6 @@
|
||||||
|
A => B | C
|
||||||
|
B => D
|
||||||
|
C => E | B
|
||||||
|
|
||||||
|
=A
|
||||||
|
?ABCDE
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=FH
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=GH
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=A
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=B
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=C
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=AC
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=BC
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=F
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=G
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
A | B + C => E
|
||||||
|
(F | G) + H => E
|
||||||
|
|
||||||
|
=H
|
||||||
|
?E
|
||||||
|
|
||||||
|
# E should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
B => A
|
||||||
|
C => A
|
||||||
|
|
||||||
|
=
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be false
|
|
@ -0,0 +1,7 @@
|
||||||
|
B => A
|
||||||
|
C => A
|
||||||
|
|
||||||
|
=B
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
B => A
|
||||||
|
C => A
|
||||||
|
|
||||||
|
=C
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,7 @@
|
||||||
|
B => A
|
||||||
|
C => A
|
||||||
|
|
||||||
|
=BC
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D ^ E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be false
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D ^ E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=D
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D ^ E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=E
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be true
|
|
@ -0,0 +1,8 @@
|
||||||
|
B + C => A
|
||||||
|
D ^ E => B
|
||||||
|
B => C
|
||||||
|
|
||||||
|
=DE
|
||||||
|
?A
|
||||||
|
|
||||||
|
# A should be false
|
|
@ -0,0 +1,6 @@
|
||||||
|
A => B ^ C
|
||||||
|
B => D
|
||||||
|
C => E ^ B
|
||||||
|
|
||||||
|
=A
|
||||||
|
?ABCDE
|
|
@ -0,0 +1,6 @@
|
||||||
|
for file in test/*
|
||||||
|
do
|
||||||
|
python3 parse.py $file
|
||||||
|
echo "\n\n\033[32mPress ENTER\033[0m\n"
|
||||||
|
read
|
||||||
|
done
|
|
@ -0,0 +1,25 @@
|
||||||
|
import config
|
||||||
|
from config import *
|
||||||
|
def set_choices(tree):
|
||||||
|
if (isinstance(tree, Tree) == False):
|
||||||
|
return str(tree)
|
||||||
|
else:
|
||||||
|
return tree.pretty().replace('\n', '')
|
||||||
|
|
||||||
|
def ask_xor(tree):
|
||||||
|
if (config.skip is True):
|
||||||
|
return 0
|
||||||
|
choices = [set_choices(tree.children[0]), set_choices(tree.children[1])]
|
||||||
|
choice = 0
|
||||||
|
while choice not in [ '0', '1']:
|
||||||
|
choice = input(str('Would you like to choose 0:{'+ choices[0]+ '} or 1:{'+ choices[1]+ '}\n'))
|
||||||
|
return int(choice)
|
||||||
|
|
||||||
|
def ask_or(tree):
|
||||||
|
if (config.skip is True):
|
||||||
|
return 0
|
||||||
|
choices = [set_choices(tree.children[0]), set_choices(tree.children[1])]
|
||||||
|
choice = 0
|
||||||
|
while choice not in [ '0', '1', '2']:
|
||||||
|
choice = input(str('Would you like to choose 0:{'+ choices[0]+ '} or 1:{'+ choices[1]+ '} or 2: for both\n'))
|
||||||
|
return int(choice)
|
Loading…
Reference in New Issue