diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2017-10-30 13:45:17 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2017-10-30 13:45:17 -0700 |
commit | aa68aeb34e2476af8bfea8ba11e08e3d5f1d19f1 (patch) | |
tree | 6d2e7b113e9862033ccbd08f297d383f62afb382 | |
parent | 7530c98b44c3d2228c9ec64b1839a1da6e1a9aaa (diff) | |
download | mu-aa68aeb34e2476af8bfea8ba11e08e3d5f1d19f1.tar.gz |
4098
Finally, make the seemingly-trivial change to buffer methods that I was envisioning 2 days ago. I still have zero confidence in our heuristic for picking the generic method to specialize for a call-site. Waiting for issues to reveal themselves.
-rw-r--r-- | 054static_dispatch.cc | 4 | ||||
-rw-r--r-- | 056shape_shifting_recipe.cc | 61 | ||||
-rw-r--r-- | 061text.mu | 6 |
3 files changed, 63 insertions, 8 deletions
diff --git a/054static_dispatch.cc b/054static_dispatch.cc index 702e5331..0af3ddeb 100644 --- a/054static_dispatch.cc +++ b/054static_dispatch.cc @@ -184,18 +184,22 @@ string best_variant(instruction& inst, const recipe& caller_recipe) { vector<recipe_ordinal> candidates; // Static Dispatch Phase 1 +//? cerr << inst.name << " phase 1\n"; candidates = strictly_matching_variants(inst, variants); if (!candidates.empty()) return best_variant(inst, candidates).name; // Static Dispatch Phase 2 +//? cerr << inst.name << " phase 2\n"; candidates = strictly_matching_variants_except_literal_against_address_or_boolean(inst, variants); if (!candidates.empty()) return best_variant(inst, candidates).name; +//? cerr << inst.name << " phase 3\n"; // Static Dispatch Phase 3 //: (shape-shifting recipes in a later layer) // End Static Dispatch Phase 3 // Static Dispatch Phase 4 +//? cerr << inst.name << " phase 4\n"; candidates = matching_variants(inst, variants); if (!candidates.empty()) return best_variant(inst, candidates).name; 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 diff --git a/061text.mu b/061text.mu index 9cb44c79..e5fd8cc0 100644 --- a/061text.mu +++ b/061text.mu @@ -220,7 +220,7 @@ def append buf:&:buffer:char, c:char -> buf:&:buffer:char [ *buf <- put *buf, length:offset, len ] -def append buf:&:buffer:char, t:text -> buf:&:buffer:char [ +def append buf:&:buffer:_elem, t:&:@:_elem -> buf:&:buffer:_elem [ local-scope load-ingredients len:num <- length *t @@ -228,8 +228,8 @@ def append buf:&:buffer:char, t:text -> buf:&:buffer:char [ { done?:bool <- greater-or-equal i, len break-if done? - c:char <- index *t, i - buf <- append buf, c + x:_elem <- index *t, i + buf <- append buf, x i <- add i, 1 loop } |