diff --git a/src/term/transform/float_combinators.rs b/src/term/transform/float_combinators.rs index 5595a1a17..8f723b696 100644 --- a/src/term/transform/float_combinators.rs +++ b/src/term/transform/float_combinators.rs @@ -14,10 +14,8 @@ impl Book { /// Precondition: Variables must have been sanitized. /// /// The floating algorithm follows these rules: - /// - Don't extract safe terms or terms that contains unscoped variables. - /// - Extract if it is a closed Application - /// - Extract if it is a supercombinator - /// - Float every element of a Superposition + /// - Recusively float every child term. + /// - Extract if it is a combinator and not is a safe term. pub fn float_combinators(&mut self) { let mut combinators = Combinators::new(); @@ -71,8 +69,8 @@ fn float_combinator( let comb_name = Name::new(format!("{}$C{}", def_name, *name_gen)); *name_gen += 1; - let comb_var = Term::Ref { nam: comb_name.clone() }; - let extracted_term = std::mem::replace(term, comb_var); + let comb_ref = Term::Ref { nam: comb_name.clone() }; + let extracted_term = std::mem::replace(term, comb_ref); let rules = vec![Rule { body: extracted_term, pats: Vec::new() }]; let rule = Definition { name: comb_name.clone(), rules, builtin }; @@ -136,17 +134,13 @@ impl Term { } fn is_combinator(&self) -> bool { - self.is_closed() - } - - pub fn is_closed(&self) -> bool { self.free_vars().is_empty() && !self.has_unscoped_diff() && !matches!(self, Term::Ref { .. }) } } impl Term { pub fn float_children_mut(&mut self) -> impl DoubleEndedIterator { - multi_iterator!(FloatIter { Zero, One, Two, Vec, Mat, App }); + multi_iterator!(FloatIter { Zero, Two, Vec, Mat, App }); match self { Term::App { fun, arg, .. } => { let mut args = vec![arg.as_mut()]; @@ -166,7 +160,7 @@ impl Term { | Term::Use { val: fst, nxt: snd, .. } | Term::Dup { val: fst, nxt: snd, .. } | Term::Opx { fst, snd, .. } => FloatIter::Two([fst.as_mut(), snd.as_mut()]), - Term::Lam { bod, .. } | Term::Chn { bod, .. } => FloatIter::One([bod.as_mut()]), + Term::Lam { bod, .. } | Term::Chn { bod, .. } => bod.float_children_mut(), Term::Var { .. } | Term::Lnk { .. } | Term::Num { .. } diff --git a/tests/snapshots/compile_file_o_all__list_merge_sort.hvm.snap b/tests/snapshots/compile_file_o_all__list_merge_sort.hvm.snap index e6537b16b..00e5a6845 100644 --- a/tests/snapshots/compile_file_o_all__list_merge_sort.hvm.snap +++ b/tests/snapshots/compile_file_o_all__list_merge_sort.hvm.snap @@ -12,11 +12,11 @@ input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.hvm @Merge$C1 = {4 a {4 b (c ({4 @Merge$C0 {4 (* @Cons) (c (a (b d)))}} d))}} -@MergePair$C0 = (a {4 {4 a {4 @Nil b}} {4 * b}}) +@MergePair$C0 = (* (a {4 {4 a {4 @Nil b}} {4 * b}})) @MergePair$C1 = {4 a {4 {4 @MergePair$C2 {4 (* @Nil) (b c)}} ({15 d b} ({4 @Merge$C1 {4 (* (e e)) (d (a f))}} {4 {4 f {4 c g}} {4 * g}}))}} -@MergePair$C2 = {4 a {4 {4 @MergePair$C1 {4 (* @MergePair$C0) (b (a c))}} (b c)}} +@MergePair$C2 = {4 a {4 {4 @MergePair$C1 {4 @MergePair$C0 (b (a c))}} (b c)}} @Nil = {4 * {4 a a}} diff --git a/tests/snapshots/desugar_file__combinators.hvm.snap b/tests/snapshots/desugar_file__combinators.hvm.snap index 22559c082..446098bb2 100644 --- a/tests/snapshots/desugar_file__combinators.hvm.snap +++ b/tests/snapshots/desugar_file__combinators.hvm.snap @@ -6,7 +6,7 @@ input_file: tests/golden_tests/desugar_file/combinators.hvm (bar) = λa λb (a bar b) -(List.ignore) = λa λ* #List (a #List λ* List.ignore$C0 0) +(List.ignore) = λa λ* #List (a List.ignore$C0 0) (baz) = {0 1 2 3 λa a foo} @@ -30,6 +30,6 @@ input_file: tests/golden_tests/desugar_file/combinators.hvm (B$C0) = let (c, d) = B; λe (c d e) -(List.ignore$C0) = #List λd (List.ignore d List.ignore) +(List.ignore$C0) = #List λ* #List λd (List.ignore d List.ignore) (list$C0) = (List.cons list List.nil) diff --git a/tests/snapshots/mutual_recursion__len.hvm.snap b/tests/snapshots/mutual_recursion__len.hvm.snap index ca3b7dace..80481c363 100644 --- a/tests/snapshots/mutual_recursion__len.hvm.snap +++ b/tests/snapshots/mutual_recursion__len.hvm.snap @@ -2,9 +2,9 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/mutual_recursion/len.hvm --- -@Len = ({2 {2 * @Len$C0} {2 #0 a}} a) +@Len = ({2 @Len$C0 {2 #0 a}} a) -@Len$C0 = {2 a b} +@Len$C0 = {2 * {2 a b}} & #1 ~ <+ c b> & @Len ~ (a c)