map combo

This commit is contained in:
Simon Forman 2019-08-10 20:42:48 -07:00
parent c8c1df8d88
commit 3af9e7e174
2 changed files with 31 additions and 2 deletions

View File

@ -3,4 +3,5 @@ GPLC_OPTIONS="--min-size"
thun: thun.pl
gplc $(GPLC_OPTIONS) -o thun thun.pl
defs.pl: meta-defs.pl defs.txt
gprolog --consult-file meta-defs.pl defs.txt

View File

@ -161,10 +161,38 @@ combo(genrec, [R1, R0, Then, If|S],
Quoted = [If, Then, R0, R1, genrec],
append(R0, [Quoted|R1], Else).
/*
This is a crude but servicable implementation of the map combinator.
Obviously it would be nice to take advantage of the implied parallelism.
Instead the quoted program, stack, and terms in the input list are
transformed to simple Joy expressions that run the quoted program on
prepared copies of the stack that each have one of the input terms on
top. These expressions are collected in a list and the whole thing is
evaluated (with infra) on an empty list, which becomes the output list.
The chief advantage of doing it this way (as opposed to using Prolog's
map) is that the whole state remains in the pending expression, so
there's nothing stashed in Prolog's call stack. This preserves the nice
property that you can interrupt the Joy evaluation and save or transmit
the stack+expression knowing that you have all the state.
*/
combo(map, [_, []|S], [[]|S], E, E ) :- !.
combo(map, [P, List|S], [Mapped, []|S], E, [infra|E]) :-
prepare_mapping(P, S, List, Mapped).
% Set up a program for each term in ListIn
%
% [term S] [P] infrst
%
% prepare_mapping(P, S, ListIn, ListOut).
prepare_mapping(P, S, In, Out) :- prepare_mapping(P, S, In, [], Out).
prepare_mapping( _, _, [], Out, Out) :- !.
prepare_mapping( P, S, [T|In], Acc, Out) :-
prepare_mapping(P, S, In, [[T|S], P, infrst|Acc], Out).