| | from collections import defaultdict |
| | from enum import Enum |
| |
|
| | class SMEM_Obj(): |
| | def __init__(self): |
| | self.processed = False |
| | self.obj_type = None |
| | self.id_var = None |
| | self.class_str = None |
| | self.wme_list = [] |
| | self.description = None |
| |
|
| | def set_id_var(self, var): |
| | self.id_var = var |
| | |
| | def add_wme(self, attr, val): |
| | self.wme_list.append((attr,val)) |
| |
|
| | def get_class(self): |
| | if self.class_str != None: |
| | return self.class_str |
| | for (attr,val) in self.wme_list: |
| | if attr == "^class": |
| | self.class_str = val |
| | break |
| | return self.class_str |
| |
|
| | def get_description(self): |
| | if self.description != None: |
| | return self.description |
| | |
| | for (attr,val) in self.wme_list: |
| | if attr == "^description": |
| | self.description = val |
| | break |
| | return self.description |
| |
|
| | def get_referenced_features(self, dict_of_values=None): |
| | |
| | if not dict_of_values: |
| | dict_of_values = defaultdict(set) |
| | children = self.get_child_objects(compact=False) |
| | for child in children: |
| | _, short_label, desc = child.to_string() |
| | |
| | if child.get_class() == "prim": |
| | if desc and desc != "()": |
| | str_to_use = desc |
| | try: |
| | ind = str_to_use.index(" is ") |
| | feature, value = str_to_use.replace("(","").replace(")","").split(" is ",maxsplit=1) |
| | dict_of_values[feature].add(value) |
| | except: |
| | print("ERROR: str_to_use missing 'is'. Value was: '"+str(str_to_use)+"'") |
| | else: |
| | str_to_use = short_label |
| | try: |
| | ind = str_to_use.index(" = ") |
| | feature, value = str_to_use.replace("(","").replace(")","").split(" = ",maxsplit=1) |
| | dict_of_values[feature].add(value) |
| | except: |
| | print("ERROR: str_to_use missing '='. Value was: '"+str(str_to_use)+"'") |
| |
|
| | |
| | child_dict = child.get_referenced_features(dict_of_values) |
| | for key, val in child_dict.items(): |
| | if key in dict_of_values: |
| | dict_of_values[key].update(val) |
| | else: |
| | dict_of_values[key] = val |
| | return dict_of_values |
| |
|
| | def get_compact_printable_object(self): |
| | """ Return this object if printable in compact mode, else return the set of next printable descendants. |
| | """ |
| | if self.obj_type == None: |
| | print("Warning: No obj_type for obj '"+self.id_var+"' in get_compact_printable_object().") |
| | return None |
| | retval = set() |
| | returnSelf = False |
| |
|
| | if self.obj_type == ObjType.COND_PRIM: |
| | for (attr,val) in self.wme_list: |
| | if attr == "^supplies-condition": |
| | val.obj_type = ObjType.COND_CONJ |
| | retval.update(val.get_compact_printable_object()) |
| | elif self.obj_type == ObjType.COND_CONJ: |
| | for (attr,val) in self.wme_list: |
| | if attr == "^satisfies-op": |
| | val.obj_type = ObjType.OP |
| | returnSelf = True |
| | break |
| | elif attr == "^activates-context": |
| | val.obj_type = ObjType.CONTEXT |
| | returnSelf = True |
| | break |
| | elif attr == "^supplies-condition": |
| | val.obj_type = ObjType.COND_CONJ |
| | retval.update(val.get_compact_printable_object()) |
| | elif self.obj_type == ObjType.CONTEXT: |
| | for (attr,val) in self.wme_list: |
| | if attr == "^primes-condition": |
| | val.obj_type = ObjType.COND_PRIM |
| | retval.update(val.get_compact_printable_object()) |
| | else: |
| | returnSelf = True |
| | |
| | if returnSelf: |
| | retval = set() |
| | retval.add(self) |
| | |
| | return retval |
| |
|
| | def get_child_objects(self, compact=True): |
| | """ If compact=True, skip condition prims and contexts, only get conjunctions and action groups |
| | """ |
| | if self.obj_type == None: |
| | print("Warning: No obj_type for obj '"+self.id_var+"'") |
| | return None |
| | retval = set() |
| | for (attr,val) in self.wme_list: |
| | if self.obj_type == ObjType.CONTEXT: |
| | if attr == "^primes-condition": |
| | val.obj_type = ObjType.COND_PRIM |
| | if compact: |
| | retval.update(val.get_compact_printable_object()) |
| | else: |
| | retval.add(val) |
| | elif self.obj_type == ObjType.COND_PRIM: |
| | if attr == "^supplies-condition": |
| | val.obj_type = ObjType.COND_CONJ |
| | if compact: |
| | retval.update(val.get_compact_printable_object()) |
| | else: |
| | retval.add(val) |
| | elif self.obj_type == ObjType.COND_CONJ: |
| | if attr == "^satisfies-op": |
| | val.obj_type = ObjType.OP |
| | retval.add(val) |
| | elif attr == "^activates-context": |
| | val.obj_type = ObjType.CONTEXT |
| | if compact: |
| | retval.update(val.get_compact_printable_object()) |
| | else: |
| | retval.add(val) |
| | elif attr == "^supplies-condition": |
| | val.obj_type = ObjType.COND_CONJ |
| | if compact: |
| | retval.update(val.get_compact_printable_object()) |
| | else: |
| | retval.add(val) |
| | elif self.obj_type == ObjType.OP: |
| | if attr == "^activates-action": |
| | val.obj_type = ObjType.ACT_GROUP |
| | retval.add(val) |
| | elif self.obj_type == ObjType.ACT_GROUP: |
| | if attr == "^action": |
| | val.obj_type = ObjType.ACT_PRIM |
| | retval.add(val) |
| | return retval |
| |
|
| | def get_prim_cond_string(self, negate=False): |
| | if len(self.wme_list) == 0: |
| | return "", "" |
| | if negate: |
| | if self.class_str == "prim-exists": |
| | op_join_str = " not provided" |
| | else: |
| | op_join_str = " is not " |
| | else: |
| | if self.class_str == "prim-exists": |
| | op_join_str = " provided" |
| | else: |
| | op_join_str = " is " |
| | if self.class_str == None: |
| | self.get_class() |
| | |
| | retval_long, retval_short, retval_desc = ["(", "(", None] |
| | if self.class_str == "prim" or self.class_str == "prim-exists": |
| | group_str, attr_str, val_str = ["","",""] |
| | for (attr,val) in self.wme_list: |
| | if attr == "^group": |
| | group_str = val |
| | elif attr == "^attribute": |
| | attr_str = val |
| | elif attr == "^value": |
| | val_str = val |
| | elif attr == "^description": |
| | self.description = val |
| | retval_desc = val |
| | retval_long += group_str+"."+attr_str+op_join_str+val_str |
| | retval_short += attr_str+op_join_str+val_str |
| | return retval_long+")", retval_short+")", retval_desc |
| |
|
| | def get_cond_string(self): |
| | retval_long, retval_short, retval_desc = ["","",None] |
| | |
| | parent_conds = [] |
| | |
| | is_negation = (self.get_class() == "negation") |
| | for (attr,val) in self.wme_list: |
| | if attr == "^receives-condition": |
| | parent_conds.append(val) |
| | if attr == "^description": |
| | self.description = val |
| | retval_desc = val |
| | |
| | |
| | compile_component_descs = (retval_desc == None) |
| | if compile_component_descs: |
| | retval_desc = "" |
| |
|
| | for i,cond in enumerate(parent_conds): |
| | if i > 0: |
| | retval_long += " \nAND " |
| | retval_short += " AND " |
| | if compile_component_descs: |
| | retval_desc += " AND " |
| | if cond.obj_type == ObjType.COND_CONJ: |
| | long, short, desc = cond.get_cond_string() |
| | else: |
| | long, short, desc = cond.get_prim_cond_string(negate=is_negation) |
| | retval_long += long |
| | retval_short += short |
| | if compile_component_descs: |
| | if desc: |
| | retval_desc += "("+desc+")" |
| | else: |
| | retval_desc = None |
| | compile_component_descs = False |
| | return retval_long, retval_short, retval_desc |
| | |
| | def get_op_string(self): |
| | retval_long, retval_short, retval_desc = ["", "", None] |
| | numeric_pref = None |
| | for (attr,val) in self.wme_list: |
| | if attr == "^name": |
| | retval_long = val |
| | retval_short = val |
| | elif attr == "^numeric-preference": |
| | try: |
| | numeric_pref = str(float(val)*100)+"%" |
| | except Exception as e: |
| | print("ERROR in get_op_string() converting numeric_pref to string: "+str(e)) |
| | numeric_pref = None |
| | elif attr == "^description": |
| | self.description = val |
| | retval_desc = val |
| | if numeric_pref: |
| | retval_long += "\nPercentage: "+numeric_pref |
| | |
| | return retval_long, retval_short, retval_desc |
| |
|
| | def get_prim_act_string(self): |
| | if len(self.wme_list) == 0: |
| | return "" |
| | if self.class_str == None: |
| | self.get_class() |
| | retval_long = "(" |
| | retval_short = "(" |
| | if self.class_str == "prim": |
| | type_str, attr_str, val_str = ["","",""] |
| | for (attr,val) in self.wme_list: |
| | if attr == "^type": |
| | type_str = val |
| | elif attr == "^attribute": |
| | attr_str = val |
| | elif attr == "^value": |
| | val_str = val |
| | retval_long += type_str+"."+attr_str+" = "+val_str |
| | retval_short += attr_str+" = "+val_str |
| | elif self.class_str == "prim-message": |
| | type_str, flag_str, msg_str = ["","",""] |
| | for (attr,val) in self.wme_list: |
| | if attr == "^type": |
| | type_str = val |
| | elif attr == "^flag": |
| | flag_str = val |
| | elif attr == "^message": |
| | msg_str = val |
| | retval_long += type_str+".flag = "+flag_str+" AND "+type_str+'.message = "'+msg_str+'"' |
| | retval_short += 'message: "'+msg_str+'"' |
| | return retval_long+")", retval_short+")" |
| | |
| | def get_act_group_string(self): |
| | retval_long, retval_short, retval_desc = ["", "", None] |
| | |
| | child_prims = [] |
| | for (attr,val) in self.wme_list: |
| | if attr == "^action": |
| | child_prims.append(val) |
| | elif attr == "^description": |
| | self.description = val |
| | retval_desc = val |
| | for i,prim in enumerate(child_prims): |
| | if i > 0: |
| | retval_long += " AND " |
| | retval_short += " AND " |
| | long, short = prim.get_prim_act_string() |
| | retval_long += long |
| | retval_short += short |
| | return retval_long, retval_short, retval_desc |
| |
|
| | def to_string(self): |
| | long = self.id_var |
| | short = self.id_var |
| | description = None |
| |
|
| | if self.obj_type == ObjType.CONTEXT: |
| | return "", "", self.get_description() |
| | if self.obj_type == ObjType.COND_PRIM: |
| | long, short, description = self.get_prim_cond_string() |
| | |
| | |
| | if self.obj_type == ObjType.COND_CONJ: |
| | long, short, description = self.get_cond_string() |
| | if self.obj_type == ObjType.OP: |
| | long, short, description = self.get_op_string() |
| | if self.obj_type == ObjType.ACT_GROUP: |
| | long, short, description = self.get_act_group_string() |
| | if self.obj_type == ObjType.ACT_PRIM: |
| | long, short = self.get_prim_act_string() |
| | return long, short, description |
| |
|
| | class ObjType(Enum): |
| | CONTEXT = 0 |
| | COND_PRIM = 1 |
| | COND_CONJ = 2 |
| | OP = 3 |
| | ACT_GROUP = 4 |
| | ACT_PRIM = 5 |
| |
|