From 76de590d272afa32ae63fb48afba58bb8674803d Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sun, 26 Jan 2020 13:21:47 -0800 Subject: [PATCH] Experiments with partial reduction are very promising. Functions become clauses like these: thun(symbol(rolldown), [], [C, A, B|D], [A, B, C|D]). thun(symbol(rolldown), [A|B], [E, C, D|F], G) :- thun(A, B, [C, D, E|F], G). thun(symbol(dupd), [], [A, B|C], [A, B, B|C]). thun(symbol(dupd), [A|B], [C, D|E], F) :- thun(A, B, [C, D, D|E], F). thun(symbol(over), [], [B, A|C], [A, B, A|C]).7 thun(symbol(over), [A|B], [D, C|E], F) :- thun(A, B, [C, D, C|E], F). Definitions become thun(symbol(of), A, D, E) :- append([symbol(swap), symbol(at)], A, [B|C]), thun(B, C, D, E). thun(symbol(pam), A, D, E) :- append([list([symbol(i)]), symbol(map)], A, [B|C]), thun(B, C, D, E). thun(symbol(popd), A, D, E) :- append([list([symbol(pop)]), symbol(dip)], A, [B|C]), thun(B, C, D, E). These are tail-recursive and allow for better indexing so I would expect them to be more efficient than the originals. Notice the difference between the original thun/4 rule for definitions and this other one that actually works. thun(symbol(Def), E, Si, So) :- def(Def, Body), append(Body, E, E o), thun(Eo, Si, So). thun(symbol(Def), E, Si, So) :- def(Def, Body), append(Body, E, [T|Eo]), thun(T, Eo, Si, So) The latter reduces to: thun(symbol(A), C, F, G) :- def(A, B), append(B, C, [D|E]), thun(D, E, F, G). We want something like... thun(symbol(B), [], A, D) :- def(B, [H|C]), thun(H, C, A, D). thun(symbol(A), [H|E0], Si, So) :- def(A, [DH|DE]), append(DE, [H|E0], E), thun(DH, E, Si, So). But it's good enough. The earlier version doesn't transform into correct code: thun(symbol(B), D, A, A) :- def(B, C), append(C, D, []). thun(symbol(A), C, F, G) :- def(A, B), append(B, C, [D|E]), thun(D, E, F, G). It would probably be good to investigate what goes wrong there.) It doesn't seem to work right for thun/4 combinator rules either. Dunno what's up there. --- thun/thun.pl | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/thun/thun.pl b/thun/thun.pl index afe8f08..f3a9a71 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -121,16 +121,18 @@ thun(bool(C), [A|B], D, E) :- thun(A, B, [bool(C)|D], E). thun(list(A), [], B, [list(A)|B]). thun(list(C), [A|B], D, E) :- thun(A, B, [list(C)|D], E). -% What is wrong here? -% thun(symbol(B), D, A, A) :- def(B, C), append(C, D, []). -% thun(symbol(A), C, F, G) :- def(A, B), append(B, C, [D|E]), thun(D, E, F, G). +% def/2 works but... +thun(symbol(A), C, F, G) :- + def(A, B), + append(B, C, [D|E]), + thun(D, E, F, G). % We want something like... -thun(symbol(B), [], A, D) :- def(B, [H|C]), thun(H, C, A, D). -thun(symbol(A), [H|E0], Si, So) :- - def(A, [DH|DE]), - append(DE, [H|E0], E), - thun(DH, E, Si, So). +% thun(symbol(B), [], A, D) :- def(B, [H|C]), thun(H, C, A, D). +% thun(symbol(A), [H|E0], Si, So) :- +% def(A, [DH|DE]), +% append(DE, [H|E0], E), +% thun(DH, E, Si, So). % And func/3 works too, thun(symbol(A), [], B, C) :- func(A, B, C). @@ -433,13 +435,13 @@ should_fold(z, a). % Just a "No Op" appease the linter. should_unfold(thun(_, _, _)). % should_unfold(func(_, _, _)). -% should_unfold(def(_, _)). +should_unfold(def(_, _)). thunder([ % Source code for thun/4. (thun( int(I), E, Si, So) :- thun(E, [ int(I)|Si], So)), (thun(bool(B), E, Si, So) :- thun(E, [bool(B)|Si], So)), (thun(list(L), E, Si, So) :- thun(E, [list(L)|Si], So)), - (thun(symbol(Def), E, Si, So) :- def(Def, Body), append(Body, E, Eo), thun(Eo, Si, So)), + (thun(symbol(Def), E, Si, So) :- def(Def, Body), append(Body, E, [T|Eo]), thun(T, Eo, Si, So)), (thun(symbol(Func), E, Si, So) :- func(Func, Si, S), thun(E, S, So)), (thun(symbol(Combo), E, Si, So) :- combo(Combo, Si, S, E, Eo), thun(Eo, S, So)) ]).