diff options
-rw-r--r-- | prolog/util.py | 39 |
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 |