bryan-stearns
commited on
Commit
•
2ca6dd2
1
Parent(s):
fc8607f
Adding description labels and content filters
Browse files- Inspect_Logic.py +55 -7
- smem_obj.py +38 -3
Inspect_Logic.py
CHANGED
@@ -21,6 +21,8 @@ def get_smem_root_from_file(smem_file):
|
|
21 |
parser.parse_file(tokens)
|
22 |
return parser.get_context_root()
|
23 |
|
|
|
|
|
24 |
if "col_obj_list" not in st.session_state:
|
25 |
st.session_state["col_obj_list"] = None
|
26 |
|
@@ -37,13 +39,26 @@ if file is not None:
|
|
37 |
else:
|
38 |
st.session_state["col_obj_list"] = None
|
39 |
|
40 |
-
# inpath = "/Users/bstearn1/Documents/Projects/OptumGitHub/Intelligent-Solutions/AICarePlan/agent/D-RULES_082222_smem.soar"
|
41 |
-
# inpath = "SMEM Generator/test_pim_smem.soar"
|
42 |
-
# st.session_state.col_obj_list[0] = get_smem_root_from_file(inpath)
|
43 |
-
|
44 |
if st.session_state.col_obj_list is None:
|
45 |
st.stop()
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
def add_col(index, obj):
|
48 |
st.session_state.col_obj_list = st.session_state.col_obj_list[:index+1]
|
49 |
st.session_state.col_obj_list.append(obj)
|
@@ -62,10 +77,20 @@ def get_header_str(obj_type):
|
|
62 |
else:
|
63 |
return " "
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
st.subheader("Click the buttons below to select conditions and to inspect resulting actions.")
|
66 |
|
67 |
cols = st.columns(max(MIN_COLS,len(st.session_state.col_obj_list)))
|
68 |
-
|
69 |
for i,col in enumerate(cols):
|
70 |
try:
|
71 |
if st.session_state.col_obj_list[i] == None:
|
@@ -85,17 +110,40 @@ for i,col in enumerate(cols):
|
|
85 |
col.text(obj_str)
|
86 |
if obj_desc != None:
|
87 |
col.markdown("*"+obj_desc+"*")
|
|
|
|
|
88 |
for j,sub in enumerate(sub_objs):
|
89 |
sub_str,sub_label,sub_desc = sub.to_string()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
if sub.obj_type == ObjType.OP:
|
91 |
subsub = list(sub.get_child_objects(compact=True))[0]
|
92 |
_,group_string,_ = subsub.to_string()
|
93 |
group_string = "\n * "+str(group_string).replace("AND", "\n * ")
|
94 |
col.markdown(group_string)
|
95 |
-
if col.button(
|
96 |
add_col(i,sub)
|
97 |
elif sub.obj_type == ObjType.ACT_GROUP:
|
98 |
col.markdown("*Output Details:* ")
|
99 |
col.markdown("\n * "+str(sub_str).replace(") AND", ")\n * "))
|
100 |
-
elif col.button(
|
101 |
add_col(i,sub)
|
|
|
21 |
parser.parse_file(tokens)
|
22 |
return parser.get_context_root()
|
23 |
|
24 |
+
## DEFINE THE FILE UPLOADER ELEMENT
|
25 |
+
|
26 |
if "col_obj_list" not in st.session_state:
|
27 |
st.session_state["col_obj_list"] = None
|
28 |
|
|
|
39 |
else:
|
40 |
st.session_state["col_obj_list"] = None
|
41 |
|
|
|
|
|
|
|
|
|
42 |
if st.session_state.col_obj_list is None:
|
43 |
st.stop()
|
44 |
|
45 |
+
|
46 |
+
## DEFINE THE CONTENT FILTERS
|
47 |
+
@st.cache(show_spinner=False, hash_funcs={SMEM_Obj: id})
|
48 |
+
def get_filter_features_dict(root_obj):
|
49 |
+
return root_obj.get_referenced_features()
|
50 |
+
|
51 |
+
# Get the content to filter on
|
52 |
+
features_dict = get_filter_features_dict(st.session_state.col_obj_list[0])
|
53 |
+
filters_expander = st.expander(label="Filters")
|
54 |
+
filters_cols = filters_expander.columns(len(features_dict))
|
55 |
+
filters_dict = {}
|
56 |
+
for key, col in zip(features_dict, filters_cols):
|
57 |
+
filters_dict[key] = col.multiselect(label=key, options=["(none)"]+sorted(features_dict[key]))
|
58 |
+
|
59 |
+
|
60 |
+
## DEFINE THE KNOWLEDGE INSPECTOR COLUMNS
|
61 |
+
|
62 |
def add_col(index, obj):
|
63 |
st.session_state.col_obj_list = st.session_state.col_obj_list[:index+1]
|
64 |
st.session_state.col_obj_list.append(obj)
|
|
|
77 |
else:
|
78 |
return " "
|
79 |
|
80 |
+
def get_tested_wmes_from_obj_str(obj_str):
|
81 |
+
attr_list = []
|
82 |
+
val_list = []
|
83 |
+
clauses = str(obj_str).split(" AND ")
|
84 |
+
for clause in clauses:
|
85 |
+
attr,val = clause.replace("(","").replace(")","").split(" is ", maxsplit=1)
|
86 |
+
attr_list += [attr]
|
87 |
+
val_list += [val]
|
88 |
+
return attr_list, val_list
|
89 |
+
|
90 |
st.subheader("Click the buttons below to select conditions and to inspect resulting actions.")
|
91 |
|
92 |
cols = st.columns(max(MIN_COLS,len(st.session_state.col_obj_list)))
|
93 |
+
# Iteratively build the columns of navigable knowlege elements
|
94 |
for i,col in enumerate(cols):
|
95 |
try:
|
96 |
if st.session_state.col_obj_list[i] == None:
|
|
|
110 |
col.text(obj_str)
|
111 |
if obj_desc != None:
|
112 |
col.markdown("*"+obj_desc+"*")
|
113 |
+
|
114 |
+
# Print the child objects of this object as the items in this column
|
115 |
for j,sub in enumerate(sub_objs):
|
116 |
sub_str,sub_label,sub_desc = sub.to_string()
|
117 |
+
if sub_desc != None:
|
118 |
+
button_text = sub_desc
|
119 |
+
else:
|
120 |
+
button_text = sub_label
|
121 |
+
# Check filters
|
122 |
+
if sub.obj_type == ObjType.COND_PRIM or sub.obj_type == ObjType.COND_CONJ:
|
123 |
+
# Get the feature and value for this sub obj
|
124 |
+
keep = True
|
125 |
+
attr_list, val_list = get_tested_wmes_from_obj_str(sub_desc)
|
126 |
+
# Check each filter key for a match
|
127 |
+
for attr in filters_dict:
|
128 |
+
if attr not in attr_list:
|
129 |
+
# Filter doesn't apply for this object
|
130 |
+
continue
|
131 |
+
if val_list[attr_list.index(attr)] not in filters_dict[attr] and len(filters_dict[attr]) > 0:
|
132 |
+
# Value not present
|
133 |
+
keep = False
|
134 |
+
break
|
135 |
+
if not keep:
|
136 |
+
continue
|
137 |
+
|
138 |
if sub.obj_type == ObjType.OP:
|
139 |
subsub = list(sub.get_child_objects(compact=True))[0]
|
140 |
_,group_string,_ = subsub.to_string()
|
141 |
group_string = "\n * "+str(group_string).replace("AND", "\n * ")
|
142 |
col.markdown(group_string)
|
143 |
+
if col.button(button_text, key="button"+str(i)+"-"+str(j)):
|
144 |
add_col(i,sub)
|
145 |
elif sub.obj_type == ObjType.ACT_GROUP:
|
146 |
col.markdown("*Output Details:* ")
|
147 |
col.markdown("\n * "+str(sub_str).replace(") AND", ")\n * "))
|
148 |
+
elif col.button(button_text, key="button"+str(i)+"-"+str(j)):
|
149 |
add_col(i,sub)
|
smem_obj.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
from enum import Enum
|
2 |
|
3 |
class SMEM_Obj():
|
@@ -16,6 +17,8 @@ class SMEM_Obj():
|
|
16 |
self.wme_list.append((attr,val))
|
17 |
|
18 |
def get_class(self):
|
|
|
|
|
19 |
for (attr,val) in self.wme_list:
|
20 |
if attr == "^class":
|
21 |
self.class_str = val
|
@@ -32,6 +35,31 @@ class SMEM_Obj():
|
|
32 |
break
|
33 |
return self.description
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
def get_compact_printable_object(self):
|
36 |
""" Return this object if printable in compact mode, else return the set of next printable descendants.
|
37 |
"""
|
@@ -162,17 +190,24 @@ class SMEM_Obj():
|
|
162 |
retval_desc = val
|
163 |
# if attr == "^supplies-condition":
|
164 |
# child_conjs.append(val)
|
165 |
-
|
|
|
|
|
|
|
166 |
for i,cond in enumerate(parent_conds):
|
167 |
if i > 0:
|
168 |
retval_long += " \nAND "
|
169 |
retval_short += " AND "
|
|
|
|
|
170 |
if cond.obj_type == ObjType.COND_CONJ:
|
171 |
-
long, short,
|
172 |
else:
|
173 |
-
long, short,
|
174 |
retval_long += long
|
175 |
retval_short += short
|
|
|
|
|
176 |
return retval_long, retval_short, retval_desc
|
177 |
|
178 |
def get_op_string(self):
|
|
|
1 |
+
from collections import defaultdict
|
2 |
from enum import Enum
|
3 |
|
4 |
class SMEM_Obj():
|
|
|
17 |
self.wme_list.append((attr,val))
|
18 |
|
19 |
def get_class(self):
|
20 |
+
if self.class_str != None:
|
21 |
+
return self.class_str
|
22 |
for (attr,val) in self.wme_list:
|
23 |
if attr == "^class":
|
24 |
self.class_str = val
|
|
|
35 |
break
|
36 |
return self.description
|
37 |
|
38 |
+
def get_referenced_features(self, dict_of_values=None):
|
39 |
+
# Collect a map of feature fields to possible values, as referenced by descendants from this object
|
40 |
+
if not dict_of_values:
|
41 |
+
dict_of_values = defaultdict(set)
|
42 |
+
children = self.get_child_objects(compact=False)
|
43 |
+
for child in children:
|
44 |
+
_, short_label, desc = child.to_string()
|
45 |
+
# Trim the label based on the object type
|
46 |
+
if child.obj_type == ObjType.COND_PRIM:
|
47 |
+
if desc:
|
48 |
+
str_to_use = desc
|
49 |
+
else:
|
50 |
+
str_to_use = short_label
|
51 |
+
ind = str_to_use.index(" is ")
|
52 |
+
feature, value = str_to_use.replace("(","").replace(")","").split(" is ",maxsplit=1)
|
53 |
+
dict_of_values[feature].add(value)
|
54 |
+
# Merge this dict of sets with results from each branch of children
|
55 |
+
child_dict = child.get_referenced_features(dict_of_values)
|
56 |
+
for key, val in child_dict.items():
|
57 |
+
if key in dict_of_values:
|
58 |
+
dict_of_values[key].update(val)
|
59 |
+
else:
|
60 |
+
dict_of_values[key] = val
|
61 |
+
return dict_of_values
|
62 |
+
|
63 |
def get_compact_printable_object(self):
|
64 |
""" Return this object if printable in compact mode, else return the set of next printable descendants.
|
65 |
"""
|
|
|
190 |
retval_desc = val
|
191 |
# if attr == "^supplies-condition":
|
192 |
# child_conjs.append(val)
|
193 |
+
compile_component_descs = (retval_desc == None)
|
194 |
+
if compile_component_descs:
|
195 |
+
retval_desc = ""
|
196 |
+
|
197 |
for i,cond in enumerate(parent_conds):
|
198 |
if i > 0:
|
199 |
retval_long += " \nAND "
|
200 |
retval_short += " AND "
|
201 |
+
if compile_component_descs:
|
202 |
+
retval_desc += " AND "
|
203 |
if cond.obj_type == ObjType.COND_CONJ:
|
204 |
+
long, short, desc = cond.get_cond_string()
|
205 |
else:
|
206 |
+
long, short, desc = cond.get_prim_cond_string(negate=is_negation)
|
207 |
retval_long += long
|
208 |
retval_short += short
|
209 |
+
if compile_component_descs:
|
210 |
+
retval_desc += "("+desc+")"
|
211 |
return retval_long, retval_short, retval_desc
|
212 |
|
213 |
def get_op_string(self):
|