about summary refs log tree commit diff stats
path: root/056shape_shifting_recipe.cc
diff options
context:
space:
mode:
Diffstat (limited to '056shape_shifting_recipe.cc')
-rw-r--r--056shape_shifting_recipe.cc61
1 files changed, 56 insertions, 5 deletions
diff --git a/056shape_shifting_recipe.cc b/056shape_shifting_recipe.cc
index 4ad687c5..1184a7b0 100644
--- a/056shape_shifting_recipe.cc
+++ b/056shape_shifting_recipe.cc
@@ -123,17 +123,23 @@ vector<recipe_ordinal> keep_max(const instruction&, const vector<recipe_ordinal>
 recipe_ordinal best_shape_shifting_variant(const instruction& inst, const vector<recipe_ordinal>& candidates) {
   assert(!candidates.empty());
   if (SIZE(candidates) == 1) return candidates.at(0);
+//?   cerr << "A picking shape-shifting variant:\n";
   vector<recipe_ordinal> result1 = keep_max(inst, candidates, number_of_concrete_type_names);
   assert(!result1.empty());
   if (SIZE(result1) == 1) return result1.at(0);
-  vector<recipe_ordinal> result2 = keep_max(inst, result1, shape_shifting_tiebreak_heuristic);
-  if (SIZE(result2) > 1) {
-    raise << "couldn't decide the best shape-shifting variant for instruction '" << to_original_string(inst) << "'\n";
+//?   cerr << "B picking shape-shifting variant:\n";
+  vector<recipe_ordinal> result2 = keep_max(inst, result1, arity_fit);
+  assert(!result2.empty());
+  if (SIZE(result2) == 1) return result2.at(0);
+//?   cerr << "C picking shape-shifting variant:\n";
+  vector<recipe_ordinal> result3 = keep_max(inst, result2, number_of_type_ingredients);
+  if (SIZE(result3) > 1) {
+    raise << "\nCouldn't decide the best shape-shifting variant for instruction '" << to_original_string(inst) << "'\n" << end();
     cerr << "This is a hole in Mu. Please copy the following candidates into an email to Kartik Agaram <mu@akkartik.com>\n";
     for (int i = 0;  i < SIZE(candidates);  ++i)
       cerr << "  " << header_label(get(Recipe, candidates.at(i))) << '\n';
   }
-  return result2.at(0);
+  return result3.at(0);
 }
 
 vector<recipe_ordinal> keep_max(const instruction& inst, const vector<recipe_ordinal>& in,
@@ -142,8 +148,10 @@ vector<recipe_ordinal> keep_max(const instruction& inst, const vector<recipe_ord
   vector<recipe_ordinal> out;
   out.push_back(in.at(0));
   int best_score = (*scorer)(inst, in.at(0));
+//?   cerr << best_score << " " << header_label(get(Recipe, in.at(0))) << '\n';
   for (int i = 1;  i < SIZE(in);  ++i) {
     int score = (*scorer)(inst, in.at(i));
+//?     cerr << score << " " << header_label(get(Recipe, in.at(i))) << '\n';
     if (score == best_score) {
       out.push_back(in.at(i));
     }
@@ -156,7 +164,7 @@ vector<recipe_ordinal> keep_max(const instruction& inst, const vector<recipe_ord
   return out;
 }
 
-int shape_shifting_tiebreak_heuristic(const instruction& inst, recipe_ordinal candidate) {
+int arity_fit(const instruction& inst, recipe_ordinal candidate) {
   const recipe& r = get(Recipe, candidate);
   return (SIZE(inst.products) - SIZE(r.products))
        + (SIZE(r.ingredients) - SIZE(inst.ingredients));
@@ -228,6 +236,24 @@ int number_of_concrete_type_names(const type_tree* type) {
        + number_of_concrete_type_names(type->right);
 }
 
+int number_of_type_ingredients(unused const instruction& inst, recipe_ordinal r) {
+  const recipe& caller = get(Recipe, r);
+  int result = 0;
+  for (int i = 0;  i < SIZE(caller.ingredients);  ++i)
+    result += number_of_type_ingredients(caller.ingredients.at(i).type);
+  for (int i = 0;  i < SIZE(caller.products);  ++i)
+    result += number_of_type_ingredients(caller.products.at(i).type);
+  return result;
+}
+
+int number_of_type_ingredients(const type_tree* type) {
+  if (!type) return 0;
+  if (type->atom)
+    return is_type_ingredient_name(type->name) ? 1 : 0;
+  return number_of_type_ingredients(type->left)
+       + number_of_type_ingredients(type->right);
+}
+
 recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst, const recipe& caller_recipe) {
   string new_name = next_unused_recipe_name(inst.name);
   assert(!contains_key(Recipe_ordinal, new_name));
@@ -1102,3 +1128,28 @@ def main [
   add 0, 0
 ]
 $error: 0
+
+:(scenario specialization_heuristic_test_1)
+# modeled on the 'buffer' container in text.mu
+container foo_buffer:_elem [
+  x:num
+]
+def main [
+  append 1:&:foo_buffer:char/raw, 2:text/raw
+]
+def append buf:&:foo_buffer:_elem, x:_elem -> buf:&:foo_buffer:_elem [
+  local-scope
+  load-ingredients
+  stash 34
+]
+def append buf:&:foo_buffer:char, x:_elem -> buf:&:foo_buffer:char [
+  local-scope
+  load-ingredients
+  stash 35
+]
+def append buf:&:foo_buffer:_elem, x:&:@:_elem -> buf:&:foo_buffer:_elem [
+  local-scope
+  load-ingredients
+  stash 36
+]
++app: 36
class='oid'>6754399 ^
6c9ce6a ^
1e63070 ^
6c9ce6a ^

cb14d4e ^
cb14d4e ^


cb14d4e ^
fdc444f ^
078ee3b ^
88d6d56 ^


6c9ce6a ^

cb14d4e ^
88d6d56 ^
cb14d4e ^
b64034d ^

fdc444f ^
9e478c1 ^
6c9ce6a ^





9e478c1 ^
fdc444f ^
18c8216 ^
b99691c ^
6c9ce6a ^


9e478c1 ^

fdc444f ^

6c9ce6a ^
9e478c1 ^
6dca06c ^
18c8216 ^


fdc444f ^
18c8216 ^

eeb6cb0 ^


18c8216 ^



18c8216 ^
61e44ee ^
4648948 ^
61e44ee ^


252af66 ^



299d5ee ^

61e44ee ^

9e478c1 ^
34857c3 ^
34857c3 ^
fdc444f ^
34857c3 ^
cb14d4e ^

cb14d4e ^


6c9ce6a ^
34857c3 ^
6c9ce6a ^
6754399 ^
6c9ce6a ^


6754399 ^
6c9ce6a ^


6754399 ^
6c9ce6a ^

1e63070 ^
6754399 ^

34857c3 ^

18c8216 ^
61c874b ^












69f17fe ^
61c874b ^

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173