-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapper.py
121 lines (105 loc) · 4.83 KB
/
mapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""Rules to construct mappings between parts of a structure.
'Mappings', aka 'abstractions' or 'joins', are new structures which contain the
shared facts of two or more other sub-structures.
TODO(masotoud): Right now we build mappings up fact-by-fact. Instead, once we
build an initial mapping, we can find new 'instances' by turning that mapping
into a production rule.
"""
from ts_utils import RegisterRule, RegisterPrototype
def MapperCodelet(ts, name=":Mapper"):
"""Adds rules for the Mapper codelet to @ts.
"""
with ts.scope(name) as scope:
NoSlip(ts, scope)
HelperRules(ts, scope)
return scope
def NoSlip(ts, scope):
"""Prototypes extending a mapping without 'real slips.'
Basically, these rules handle mappings where the relations line up, such as
abc -> bcd, lmn -> mno and more complicated ones like abcefg -> fgh, xyzabc
-> bcd.
It *cannot* handle 'deeper' mappings, where the important relations
actually change. Eg. abc -> bcd, nml -> mlk (here, successor is 'really
slipping' with predecessor). Such mappings could be handled with a similar
rule, but they're a lot harder to deal with because then the mapping chosen
is more ambiguous.
"""
with ts.scope(":NoSlipRules"):
ts[":MA"].map({ts[":A"]: ts[":C"]})
ts[":MB"].map({ts[":B"]: ts[":C"]})
ts[":IsAbstractionA"].map({ts[":MAlphaA"]: scope[":Abstraction"]})
ts[":IsAbstractionB"].map({ts[":MAlphaB"]: scope[":Abstraction"]})
ts[":MAlphaA"].map({ts[":A"]: ts[":AlphaAB"]})
ts[":MAlphaB1"].map({ts[":B"]: ts[":AlphaAB"]})
ts[":MAlphaA"].map({ts[":MA"]: ts[":AlphaMAB"]})
ts[":MAlphaB2"].map({ts[":MB1"]: ts[":AlphaMAB"]})
ts[":NewAlphaMAB"].map({ts[":AlphaAB"]: ts[":C"]})
RegisterPrototype(ts, dict({
":HotBegin": {ts["/MUST_MAP"]: ts[":A, :B, :C, :MA, :MB"]},
":NewConcrete": {ts["/INSERT"]: ts[":AlphaAB, :NewAlphaMAB"]},
":NewMap": {ts["/INSERT"]: ts[":AlphaMAB, :NewAlphaMAB"]},
":NewFact": {ts["/INSERT"]: [ts[":NewAlphaMAB"]]},
":IntoExisting": {
ts["/INSERT"]:
ts[":IsAbstractionB, :MAlphaB, :MAlphaB1, :MAlphaB2"],
},
":ExistingConcrete": {ts["/INSERT"]: [ts[":MAlphaB1"]]},
":ExistingMap": {ts["/INSERT"]: [ts[":MAlphaB2"]]},
":Concretize?Concrete": {
ts["/INSERT"]: [ts[":B"], ts[":MAlphaB1"]],
},
":Concretize?Map": {
ts["/TRY_MAP"]: [ts[":MB"]],
ts["/INSERT"]: [ts[":MB"], ts[":MB1"], ts[":MAlphaB2"]],
},
":ConcretizeMap": {
ts["/INSERT"]: [ts[":MB"], ts[":MB1"], ts[":MAlphaB2"]],
},
":Concretize?Fact": {
ts["/INSERT"]: [ts[":MB"]],
},
}), equal=[
set({ts[":NewAlphaMAB"], ts[":AlphaMAB"]}),
set({ts[":MAlphaB1"], ts[":MAlphaB2"], ts[":MAlphaB"]}),
set({ts[":MB"], ts[":MB1"]}),
], maybe_equal=[
set({ts[":A"], ts[":B"]}),
set({ts[":MA"], ts[":MB"]}),
])
def HelperRules(ts, scope):
"""Helper patterns used by the analogy-making heuristics.
See analogy_utils.py for more details on where these patterns are used.
"""
with ts.scope(":NotFunction"):
with ts.scope(":MustMap"):
ts[":IsAbstractionA"].map({ts[":MAlphaA"]: scope[":Abstraction"]})
ts[":MAlphaA"].map({ts[":A"]: ts[":AlphaA1"]})
ts[":MAlphaA"].map({ts[":A"]: ts[":AlphaA2"]})
RegisterRule(ts)
with ts.scope(":NotInjective"):
with ts.scope(":MustMap"):
ts[":IsAbstractionA"].map({ts[":MAlphaA"]: scope[":Abstraction"]})
ts[":MAlphaA"].map({
ts[":A1"]: ts[":AlphaA"],
ts[":A2"]: ts[":AlphaA"],
})
RegisterRule(ts)
with ts.scope(":MissingFacts"):
with ts.scope(":MustMap"):
ts[":MA"].map({ts[":A"]: ts[":C"]})
ts[":IsAbstractionA"].map({ts[":MAlphaA"]: scope[":Abstraction"]})
# TODO: maybe this should be in NoMap?
ts[":MAlphaA"].map({ts[":A"]: ts[":AlphaAB"]})
ts[":MAlphaA"].map({ts[":MA"]: ts[":AlphaMAB"]})
with ts.scope(":NoMap"):
ts[":AlphaMAB"].map({ts[":AlphaAB"]: ts[":C"]})
RegisterRule(ts, auto_assert_equal=True)
with ts.scope(":UnlowerableFacts"):
with ts.scope(":MustMap"):
ts[":AlphaMAB"].map({ts[":AlphaAB"]: ts[":C"]})
ts[":IsAbstractionA"].map({ts[":MAlphaA"]: scope[":Abstraction"]})
ts[":MAlphaA"].map({ts[":A"]: ts[":AlphaAB"]})
ts[":MAlphaA"].map({ts[":MA"]: ts[":AlphaMAB"]})
with ts.scope(":NoMap"):
ts[":MA"].map({ts[":A"]: ts[":C"]})
RegisterRule(ts, auto_assert_equal=True)