Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AICogSciFinalProject
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mrk022
AICogSciFinalProject
Commits
449c84ec
Commit
449c84ec
authored
Dec 04, 2019
by
mrk022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
got tree working better, need to tie in with RBES noe
parent
6180fd72
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
278 additions
and
25 deletions
+278
-25
__pycache__/queue.cpython-35.pyc
__pycache__/queue.cpython-35.pyc
+0
-0
__pycache__/tree.cpython-35.pyc
__pycache__/tree.cpython-35.pyc
+0
-0
tree.py
tree.py
+184
-8
tutor.py
tutor.py
+94
-17
No files found.
__pycache__/queue.cpython-35.pyc
0 → 100644
View file @
449c84ec
File added
__pycache__/tree.cpython-35.pyc
0 → 100644
View file @
449c84ec
File added
tree.py
View file @
449c84ec
...
...
@@ -4,11 +4,89 @@
import
queue
class
EquationTree
:
def
__init__
(
self
):
self
.
root
=
EqualsNode
()
self
.
root
.
left
=
None
self
.
root
.
right
=
None
def
updateNode
(
self
,
parent
,
left
,
newNode
):
if
left
:
parent
.
left
=
newNode
else
:
parent
.
right
=
newNode
self
.
printTree
()
def
get_expression
(
self
):
self
.
output
=
""
self
.
inorder
(
self
.
root
)
print
(
"output is: "
,
self
.
output
)
return
self
.
output
def
inorder
(
self
,
node
):
if
node
:
self
.
inorder
(
node
.
left
)
self
.
output
+=
str
(
node
.
value
)
self
.
inorder
(
node
.
right
)
def
evaluate
(
self
,
parent
,
left
):
if
left
:
if
parent
.
left
.
canEval
():
if
isinstance
(
parent
.
left
.
left
,
NumNode
):
print
(
"evaluating"
,
parent
.
left
.
eval
())
newNode
=
NumNode
(
parent
.
left
.
eval
())
else
:
print
(
"evaluating"
,
parent
.
left
.
eval
())
newNode
=
VariableNode
(
str
(
parent
.
left
.
eval
())
+
"x"
)
parent
.
left
=
newNode
elif
parent
.
left
.
left
!=
None
and
parent
.
left
.
left
.
canEval
():
self
.
evaluate
(
parent
.
left
,
True
)
elif
parent
.
left
.
right
!=
None
and
parent
.
left
.
right
.
canEval
():
self
.
evaluate
(
parent
.
left
,
False
)
else
:
if
parent
.
right
.
canEval
():
if
isinstance
(
parent
.
right
.
left
,
NumNode
):
print
(
"evaluating"
,
parent
.
right
.
eval
())
newNode
=
NumNode
(
parent
.
right
.
eval
())
else
:
print
(
"evaluating"
,
parent
.
right
.
eval
())
newNode
=
VariableNode
(
str
(
parent
.
right
.
eval
())
+
"x"
)
parent
.
right
=
newNode
elif
parent
.
right
.
left
!=
None
and
parent
.
right
.
left
.
canEval
():
self
.
evaluate
(
parent
.
right
,
True
)
elif
parent
.
right
.
right
!=
None
and
parent
.
right
.
right
.
canEval
():
self
.
evaluate
(
parent
.
right
,
False
)
def
printTree
(
self
):
q
=
queue
.
Queue
()
q
.
enqueue
(
self
.
root
)
while
not
q
.
isEmpty
():
currentNode
=
q
.
front
()
if
currentNode
.
left
!=
None
:
b
=
Branch
()
q
.
enqueue
(
b
)
q
.
enqueue
(
currentNode
.
left
)
if
currentNode
.
right
!=
None
:
q
.
enqueue
(
currentNode
.
right
)
print
(
q
.
dequeue
()
.
value
,
end
=
' '
)
class
Branch
:
def
__init__
(
self
):
self
.
value
=
"
\n
"
self
.
left
=
None
self
.
right
=
None
class
EqualsNode
:
def
__init__
(
self
):
self
.
value
=
"="
class
TimesNode
:
def
__init__
(
self
,
left
,
right
):
self
.
left
=
left
self
.
right
=
right
self
.
value
=
"*"
def
eval
(
self
):
'''if check_if_variables(str(self.left.eval()), str(self.right.eval())) == "both_vars":
v1 = str(self.left.eval()).split("x")[0]
...
...
@@ -32,7 +110,16 @@ class PlusNode:
def
__init__
(
self
,
left
,
right
):
self
.
left
=
left
self
.
right
=
right
self
.
value
=
"+"
def
canEval
(
self
):
if
isinstance
(
self
.
left
,
VariableNode
)
==
isinstance
(
self
.
right
,
VariableNode
):
return
True
return
False
def
getInverse
(
self
):
return
MinusNode
(
None
,
None
)
def
eval
(
self
):
return
self
.
left
.
eval
()
+
self
.
right
.
eval
()
...
...
@@ -44,6 +131,15 @@ class MinusNode:
def
__init__
(
self
,
left
,
right
):
self
.
left
=
left
self
.
right
=
right
self
.
value
=
"-"
def
canEval
(
self
):
if
isinstance
(
self
.
left
,
VariableNode
)
==
isinstance
(
self
.
right
,
VariableNode
):
return
True
return
False
def
getInverse
(
self
):
return
PlusNode
(
None
,
None
)
def
eval
(
self
):
return
self
.
left
.
eval
()
-
self
.
right
.
eval
()
...
...
@@ -53,21 +149,31 @@ class MinusNode:
class
NumNode
:
def
__init__
(
self
,
num
):
self
.
num
=
num
self
.
value
=
num
self
.
left
=
None
self
.
right
=
None
def
eval
(
self
):
return
self
.
num
return
self
.
value
def
canEval
(
self
):
return
False
# not an operator
def
inorder
(
self
):
return
str
(
self
.
num
)
return
str
(
self
.
value
)
class
VariableNode
:
def
__init__
(
self
,
value
):
self
.
value
=
value
self
.
left
=
None
self
.
right
=
None
def
eval
(
self
):
# get value before x
return
float
(
self
.
value
.
split
(
"x"
)[
0
])
return
int
(
self
.
value
.
split
(
"x"
)[
0
])
def
canEval
(
self
):
return
False
#not an operator
def
inorder
(
self
):
return
str
(
self
.
eval
())
...
...
@@ -99,7 +205,7 @@ def E(q):
output
=
VariableNode
(
token
)
# make a different class for variable node
else
:
output
=
NumNode
(
floa
t
(
token
))
output
=
NumNode
(
in
t
(
token
))
#except:
# print("Not a valid operation, need variables of like terms")
# output = NumNode(float(0))
...
...
@@ -138,9 +244,62 @@ def infix_to_prefix(formula):
a
=
exp_stack
.
pop
()
b
=
exp_stack
.
pop
()
exp_stack
.
append
(
op
+
" "
+
b
+
" "
+
a
)
print
exp_stack
[
-
1
]
print
(
exp_stack
[
-
1
])
return
exp_stack
[
-
1
]
def
add_to_tree
(
q
,
root
,
left
):
if
not
q
.
isEmpty
():
token
=
q
.
dequeue
()
operator
=
False
if
token
==
"+"
:
newNode
=
PlusNode
(
None
,
None
)
operator
=
True
elif
token
==
"*"
:
newNode
=
TimesNode
(
None
,
None
)
operator
=
True
elif
token
==
"-"
:
newNode
=
MinusNode
(
None
,
None
)
operator
=
True
elif
"x"
in
token
:
newNode
=
VariableNode
(
token
)
else
:
newNode
=
NumNode
(
int
(
token
))
if
left
:
root
.
left
=
newNode
else
:
root
.
right
=
newNode
if
operator
:
add_to_tree
(
q
,
newNode
,
True
)
add_to_tree
(
q
,
newNode
,
False
)
return
newNode
def
generate_tree
(
equation
):
t
=
EquationTree
()
expressions
=
equation
.
split
(
"="
)
x1
=
infix_to_prefix
(
expressions
[
0
])
x2
=
infix_to_prefix
(
expressions
[
1
])
lst1
=
x1
.
split
()
q1
=
queue
.
Queue
()
lst2
=
x2
.
split
()
q2
=
queue
.
Queue
()
for
token
in
lst1
:
q1
.
enqueue
(
token
)
add_to_tree
(
q1
,
t
.
root
,
True
)
# add expression tree to left side of equation tree
for
token
in
lst2
:
q2
.
enqueue
(
token
)
add_to_tree
(
q2
,
t
.
root
,
False
)
# add expression tree to right side of equation tree
t
.
printTree
()
return
t
def
eval_tree
(
expression
):
'''x = NumNode(5)
...
...
@@ -174,8 +333,25 @@ def split_equation(equation):
return
expressions
def
main
():
exp
=
split_equation
(
"4x * 3x + 2"
)
x
=
eval_tree
(
exp
[
0
])
#exp = split_equation("4x * 3x + 2")
#x = eval_tree(exp[0])
'''eqTree = EquationTree()
x1 = VariableNode("4x")
x2 = NumNode(3)
x3 = NumNode(2)
x4 = NumNode(7)
t = PlusNode(x1,x2)
t2 = PlusNode(x3,x4)
eqTree.root.left = t
eqTree.root.right = t2
eqTree.printTree()'''
equationTree
=
generate_tree
(
"4x + 3 = 2 + 7"
)
print
(
equationTree
.
root
.
left
.
canEval
())
print
(
equationTree
.
root
.
right
.
canEval
())
newNode
=
NumNode
(
equationTree
.
root
.
right
.
eval
())
equationTree
.
updateNode
(
equationTree
.
root
,
False
,
newNode
)
equationTree
.
printTree
()
equationTree
.
get_expression
()
if
__name__
==
"__main__"
:
...
...
tutor.py
View file @
449c84ec
...
...
@@ -2,11 +2,63 @@ import ccm
import
re
from
ccm.lib.actr
import
*
#from expressionTree import EquationTreeNode
from
tree
import
*
import
tree
import
queue
class
StepGenerator
:
class
TutorState
:
def
__init__
(
self
,
equation
):
self
.
equation
=
equation
self
.
expressions
=
equation
.
split
(
"="
)
self
.
tree
=
tree
.
generate_tree
(
equation
)
def
move_constants_right
(
self
):
moveNode
=
None
node
=
self
.
tree
.
root
.
left
if
isinstance
(
node
,
tree
.
PlusNode
)
or
isinstance
(
node
,
tree
.
MinusNode
):
# if plus or minus node
if
node
.
canEval
()
==
False
:
# if can't evaluate children, need to move one
newOp
=
node
.
getInverse
()
if
isinstance
(
node
.
left
,
tree
.
NumNode
):
moveNode
=
node
.
left
node
.
left
=
tree
.
VariableNode
(
"0x"
)
elif
isinstance
(
node
.
right
,
tree
.
NumNode
):
moveNode
=
node
.
right
node
.
right
=
tree
.
VariableNode
(
"0x"
)
q
=
queue
.
Queue
()
q
.
enqueue
(
self
.
tree
.
root
.
right
)
moved
=
False
while
not
q
.
isEmpty
()
and
not
moved
:
currentNode
=
q
.
front
()
if
currentNode
.
left
!=
None
:
if
isinstance
(
currentNode
.
left
,
tree
.
NumNode
):
oldNum
=
currentNode
.
left
currentNode
.
left
=
newOp
currentNode
.
left
.
left
=
oldNum
currentNode
.
left
.
right
=
moveNode
moved
=
True
q
.
enqueue
(
currentNode
.
left
)
if
currentNode
.
right
!=
None
and
not
moved
:
if
isinstance
(
currentNode
.
right
,
tree
.
NumNode
):
oldNum
=
currentNode
.
right
currentNode
.
right
=
newOp
currentNode
.
right
.
left
=
oldNum
currentNode
.
right
.
right
=
moveNode
moved
=
True
q
.
enqueue
(
currentNode
.
right
)
q
.
dequeue
()
#self.tree.printTree()
#self.tree.get_expression()
def
combine_like_terms
(
self
,
left
):
self
.
tree
.
get_expression
()
print
(
"COMBINING LIKE TERMS"
)
if
left
:
self
.
tree
.
evaluate
(
self
.
tree
.
root
,
True
)
else
:
self
.
tree
.
evaluate
(
self
.
tree
.
root
,
False
)
self
.
tree
.
get_expression
()
class
UserState
(
ccm
.
Model
):
#ccm.ProductionSystem
#moveConstants = "0" # move constants is 0 when need to move them, 1 when move variables, 2 when neither
...
...
@@ -15,6 +67,7 @@ class UserState(ccm.Model): #ccm.ProductionSystem
def
__init__
(
self
,
equation
):
ccm
.
Model
.
__init__
(
self
)
self
.
equation
=
equation
self
.
oldEquation
=
None
self
.
sides
=
self
.
getLeftandRightVals
()
self
.
constantCount
=
self
.
getConstantCount
()
#self.generate_tree()
...
...
@@ -26,19 +79,29 @@ class UserState(ccm.Model): #ccm.ProductionSystem
self
.
end
=
False
def
get_input
(
self
):
user_step
=
input
(
"Please enter your next step: "
)
#figure out what user step means
outputString
=
"Equation is currently: "
+
str
(
self
.
equation
)
+
"
\n
What is your next step? "
user_step
=
input
(
outputString
)
#figure out what user step means
# call some get_state() function comparing user step to what state should be
oldEquation
=
self
.
equation
self
.
oldEquation
=
self
.
equation
self
.
equation
=
user_step
newSides
=
self
.
getLeftandRightVals
()
self
.
state
=
self
.
get_state
(
newSides
)
ready
=
True
return
user_step
oldSides
=
self
.
sides
self
.
sides
=
self
.
getLeftandRightVals
()
oldConstantCount
=
self
.
constantCount
self
.
constantCount
=
self
.
getConstantCount
()
#self.state = self.get_state(oldConstantCount)
#print("state is ", self.state)
return
oldConstantCount
def
getLeftandRightVals
(
self
):
expressions
=
self
.
equation
.
split
(
"="
)
leftVars
=
re
.
split
(
"[+-]"
,
expressions
[
0
])
rightVars
=
re
.
split
(
"[+-]"
,
expressions
[
1
])
try
:
leftVars
=
re
.
split
(
"[+-]"
,
expressions
[
0
])
rightVars
=
re
.
split
(
"[+-]"
,
expressions
[
1
])
except
:
print
(
"INVALID INPUT, try again"
)
self
.
equation
=
self
.
oldEquation
self
.
get_input
()
return
[
leftVars
,
rightVars
]
def
getConstantCount
(
self
):
...
...
@@ -67,17 +130,25 @@ class UserState(ccm.Model): #ccm.ProductionSystem
return
False
return
True
def
get_state
(
self
,
newSides
):
def
get_state
(
self
,
oldConstantCount
):
# based on number of variables constants on each side of the equation, the agent guesses which state the user is moving to
if
newSides
[
0
]
!=
self
.
sides
[
0
]
and
newSides
[
2
]
!=
newSides
[
2
]:
print
(
"old constant count "
,
oldConstantCount
)
print
(
"self.constantcount "
,
self
.
constantCount
)
if
oldConstantCount
[
0
]
!=
self
.
constantCount
[
0
]
and
oldConstantCount
[
2
]
!=
self
.
constantCount
[
2
]:
# if not same number of variables as before for both sides then moved variables
print
(
"variables were moved"
)
self
.
state
=
"move_variables"
elif
newSides
[
0
]
!=
self
.
sides
[
0
]
or
newSides
[
2
]
!=
newSides
[
2
]:
elif
oldConstantCount
[
0
]
!=
self
.
constantCount
[
0
]
or
oldConstantCount
[
2
]
!=
self
.
constantCount
[
2
]:
print
(
"variables were added"
)
self
.
state
=
"add_variables"
elif
newSides
[
1
]
!=
self
.
sides
[
1
]
and
newSides
[
3
]
!=
newSides
[
3
]:
elif
oldConstantCount
[
1
]
!=
self
.
constantCount
[
1
]
and
oldConstantCount
[
3
]
!=
self
.
constantCount
[
3
]:
print
(
"constants were moved"
)
self
.
state
=
"move_constants"
elif
newSides
[
1
]
!=
self
.
sides
[
1
]
or
newSides
[
3
]
!=
newSides
[
3
]:
elif
oldConstantCount
[
1
]
!=
self
.
constantCount
[
1
]
or
oldConstantCount
[
3
]
!=
self
.
constantCount
[
3
]:
print
(
"constants were added"
)
self
.
state
=
"add_constants"
else
:
print
(
"nothing triggered"
)
# need to do this for division and simplifying fraction
def
moveConstants
(
self
):
...
...
@@ -94,15 +165,21 @@ class UserState(ccm.Model): #ccm.ProductionSystem
class
IntelligentTutor
(
ACTR
):
goal
=
Buffer
()
user
=
UserState
(
"4x+7=5x+2"
)
tutor
=
TutorState
(
"4x + 3 = 2x + 7"
)
tutor
.
move_constants_right
()
tutor
.
combine_like_terms
(
False
)
tutor
.
combine_like_terms
(
True
)
def
init
():
user
.
get_input
()
goal
.
set
(
user
.
state
)
cc
=
user
.
get_input
()
print
(
"USER STATE IS "
,
user
.
state
)
# need to get user input to translate to state
goal
.
set
(
"move_constants"
)
#user.get_state(cc)
def
moved_constants
(
goal
=
"move_constants"
):
#user="ready:True"
#execute move constants on current equation
#check if user input is the same as what we expect
#if so then
print
(
"here??"
)
user
.
get_input
()
goal
.
set
(
user
.
state
)
#if it is invalid then move to invalid state, and return correct state we found in that function
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment