summaryrefslogtreecommitdiff
path: root/prolog/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'prolog/util.py')
-rw-r--r--prolog/util.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/prolog/util.py b/prolog/util.py
index 4826f86..438c068 100644
--- a/prolog/util.py
+++ b/prolog/util.py
@@ -1,5 +1,6 @@
#!/usr/bin/python3
+import itertools
import math
import re
@@ -104,3 +105,41 @@ def rename_vars(tokens, names={}):
next_id += 1
tokens[i] = ('VARIABLE', 'A' + str(names[cur_name]))
return names
+
+# transformation = before → after; applied on line which is part of rule
+# return mapping from formal vars in before+after to actual vars in rule
+# line and rule should of course not be normalized
+def map_vars(before, after, line, rule):
+ mapping = {}
+ new_index = 0
+ for i in range(len(before)):
+ if line[i][0] == 'VARIABLE':
+ formal_name = before[i][1]
+ if line[i][1] != '_':
+ actual_name = line[i][1]
+ else:
+ actual_name = 'New'+str(new_index)
+ new_index += 1
+ mapping[formal_name] = actual_name
+
+ remaining_formal = set([t[1] for t in after if t[0] == 'VARIABLE' and t[1] not in mapping.keys()])
+ remaining_actual = set([t[1] for t in rule if t[0] == 'VARIABLE' and t[1] != '_' and t[1] not in mapping.values()])
+
+ #for i in range(0, len(remaining_formal)-len(remaining_actual)+2):
+ for var in remaining_formal:
+ remaining_actual.add('New'+str(new_index))
+ new_index += 1
+
+ # cthulhu-inspired horrors continue...
+ # get all possible mappings of remaining transform var. names to actual names
+ def match(a, b):
+ for bc in itertools.combinations(b, min(len(a), len(b))):
+ for bp in itertools.permutations(bc):
+ for ac in itertools.combinations(a, len(bc)):
+ yield {ac[i]: bp[i] for i in range(len(bc))}
+
+ for more_mapping in match(remaining_formal, remaining_actual):
+ # copy base mapping dict and add remaining vars
+ mapping_all = {k: v for k, v in mapping.items()}
+ mapping_all.update(more_mapping)
+ yield mapping_all