bryan-stearns commited on
Commit
2ca6dd2
1 Parent(s): fc8607f

Adding description labels and content filters

Browse files
Files changed (2) hide show
  1. Inspect_Logic.py +55 -7
  2. 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(sub_label, key="button"+str(i)+"-"+str(j)):
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(sub_label, key="button"+str(i)+"-"+str(j)):
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, _ = cond.get_cond_string()
172
  else:
173
- long, short, _ = cond.get_prim_cond_string(negate=is_negation)
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):