def parse_wm_printout(text): | |
""" Given a printout of soar's working memory, parses it into a dictionary of wmes, | |
Where the keys are identifiers, and the values are lists of wme triples rooted at that id | |
:param text: The output of a soar print command for working memory | |
:type text: str | |
:returns dict{ str, list[ (str, str, str) ] } | |
""" | |
### First: preprocess the output into a string of tokens | |
tokens = [] | |
quote = None | |
for word in text.split(): | |
# Handle quoted strings (Between | |) | |
if word[0] == '|': | |
quote = word | |
elif quote is not None: | |
quote += ' ' + word | |
if quote is not None: | |
if len(quote) > 1 and quote.endswith('|'): | |
tokens.append(quote) | |
quote = None | |
elif len(quote) > 1 and quote.endswith('|)'): | |
tokens.append(quote[:-1]) | |
quote = None | |
continue | |
# Ignore operator preferences | |
if word in [ '+', '>', '<', '!', '=' ]: | |
continue | |
# Ignore activation values [+23.000] | |
if word.startswith("[+") and (word.endswith("]") or word.endswith("])")): | |
continue | |
# Ignore singleton lti's (@12533) | |
if word.startswith("(@") and word.endswith(")"): | |
continue | |
# Strip opening parens but add $ to indicate identifier | |
if word.startswith("("): | |
word = '$' + word[1:] | |
# Don't care about closing parens | |
word = word.replace(")", "") | |
tokens.append(word) | |
wmes = dict() | |
cur_id = None | |
cur_att = None | |
cur_wmes = [] | |
i = 0 | |
for token in tokens: | |
if len(token) == 0: | |
continue | |
# Identifier | |
if token[0] == '$': | |
cur_id = token[1:] | |
cur_att = None | |
cur_wmes = [] | |
wmes[cur_id] = cur_wmes | |
# Attribute | |
elif token[0] == '^': | |
cur_att = token[1:] | |
# Value | |
elif cur_id is None: | |
print("ERROR: Value " + token + " encountered with no id") | |
elif cur_att is None: | |
print("ERROR: Value " + token + " encountered with no attribute") | |
else: | |
cur_wmes.append( (cur_id, cur_att, token) ) | |
return wmes | |