% module: lambda.pl % date: July 8, 2004 % author: Douglas M. Auclair (DMA) % copyright (c) 2005, Cotillion Group, Inc. All rights reserved. % synopsis: standard functional programming utilities :- module(lambda, [apply/3, test/2]). % apology: Of course, the lambda calculus as defined by Church, % Curry, etc. has a lambda term take ONLY one argument: a % variable to be bound to a value used in the term's % definition. % % But, then again, the lambda calculus, qua lambda calculus, % has only terms and application: no numbers, no (short-cut) % operators (like addition, etc.), as all these things can % be represented by lambda terms (e.g. the Church numerals); % we won't be this strict here! % modified: August 22, 2005, DMA % changed: Adjusted the exported predicates to be only apply/3 and % test/2, as these are the only ones used elsewhere % modified: February 17, 2005, DMA % changed: Added the complement clause to the test/2 predicate. % modified: July 26, 2004, DMA % changed: Added comments throughout; added apology. apply(lambda(X, Function), Arg, Answer) :- % Apply the argument to the lambda-term findall(Y, (X = Arg, Y = Function), [Answer]). % we use findall/3 to bind X only long enough to compute the result % of the lambda. % ------------------------------------------------------- % Test takes a typed lambda term (a higher-order predicate) % and applies the argument, but in this case, instead of % expecting a "return" value to use further, the result % is the execution of the /Prolog/ true/0 or fail/0. An % example of use for this higher-order predicate is % list_utils:filter/4. % % test/2 has an interesting implementation, simply % because we don't wish to bind the variable beyond the % test we must use negation to bind the scope of the % variable binding lexically (how Schemish!), then % negate again to obtain the appropriate response. % ------------------------------------------------------- test(predicate(X, Goal), Arg) :- \+ (X = Arg, \+ Goal). test(complement(X, Goal), Arg) :- \+ (X = Arg, Goal).