OSDN Git Service

Experiments with partial reduction are very promising.
authorSimon Forman <sforman@hushmail.com>
Sun, 26 Jan 2020 21:21:47 +0000 (13:21 -0800)
committerSimon Forman <sforman@hushmail.com>
Sun, 26 Jan 2020 21:21:47 +0000 (13:21 -0800)
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

index afe8f08..f3a9a71 100644 (file)
@@ -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))
 ]).