-
Notifications
You must be signed in to change notification settings - Fork 0
/
functional.pl
49 lines (38 loc) · 1.48 KB
/
functional.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
% :- module(functional, [term_expansion/2, '<-'/2, '<<'/2]).
% assignment from expression
:- op(700, xfy, <-).
<-(X, Y) :- fexpCompute(Y, X).
% assignment from single-argument fact clauses
:-op(700, xfy, <<).
<<(X,Y) :- call(Y, X).
% this macro translates -> function notation into normal clauses
:- multifile(term_expansion).
:- dynamic(term_expansion).
term_expansion( X -> Body , Clause ) :-
X =.. [Func | Args],
append( [Func | Args], [Ret], ClauseL ),
ClauseF =.. ClauseL,
putReturn(Body, Ret, NewBody),
Clause = :-(ClauseF, NewBody).
% (internal) substitutes last statement in a clause with an assignment
putReturn( Body, Ret, ','(H, NewBody) ) :-
Body = ','(H, T),
putReturn(T, Ret, NewBody).
putReturn(Stmt, Ret, Ret <- Stmt).
% fexpCompute( Expression, Value )
% computes value for a given term represented expression
% we cut after each match because next ones produce either garbage or errors
% built in types are already computed
fexpCompute( Exp, Exp ) :- (integer(Exp) ; float(Exp); atom(Exp)), !.
% need to manualy map the list, since listmap behaves weirdly
fexpCompute([], []) :- !.
fexpCompute([InH | InT], [OutH | OutT]) :- fexpCompute(InH, OutH), fexpCompute(InT, OutT), !.
% function application
fexpCompute( Exp, Val ) :-
Exp =.. [Func | Args],
current_predicate(Func, _),
maplist(fexpCompute, Args, ArgVals ),
append(ArgVals, [Val], FArgs),
apply(Func, FArgs), !.
% anything else is either an arithmetic expression or garbage
fexpCompute(Exp, Val) :- Val is Exp, !.