% Also has code from: % File : APPLIC.PL % Author : Lawrence Byrd + Richard A. O'Keefe % Updated: 4 August 1984 and Ken Johnson 11-8-87 % Purpose: Various "function" application routines based on apply/2. % Needs : append/3 from listut.pl % File : apply_macros.yap % Author : E. Alphonse from code by Joachim Schimpf, Jan Wielemaker, Vitor Santos Costa % Purpose: Macros to apply a predicate to all elements % of a list or to all sub-terms of a term. :- module(mapargs,[ mapargs/2, % :Goal, +S mapargs/3, % :Goal, +S, -S mapargs/4, % :Goal, +S, -S1, -S2 mapargs/5, % :Goal, +S, -S1, -S2, -S3 mapargs/6, % :Goal, +S, -S1, -S2, -S3, -S4 sumargs/4, foldargs/4, % :Pred, +S, ?V0, ?V foldargs/5, % :Pred, +S, ?S1, ?V0, ?V foldargs/6, % :Pred, +S, ?S1, ?S2, ?V0, ?V foldargs/7 % :Pred, +S, ?S1, ?S2, ?S3, ?V0, ?V ]). :- use_module(library(maputils)). :- use_module(library(lists), [append/3]). :- meta_predicate mapargs(1,+), mapargs_args(1,+,+), mapargs(2,+,-), mapargs_args(2,+,-,+), mapargs(3,+,-,-), mapargs_args(2,+,-,-,+), mapargs(4,+,-,-,-), mapargs_args(2,+,-,-,-,+), mapargs(5,+,-,-,-,-), mapargs_args(2,+,-,-,-,-,+), sumargs(3,+,+,-), sumargs_args(3,+,+,-,+), foldargs(3, +, +, -), foldargs(4, +, ?, +, -), foldargs(5, +, ?, ?, +, -), foldargs(6, +, ?, ?, ?, +, -). mapargs(Pred, TermIn) :- functor(TermIn, _F, N), mapargs_args(Pred, TermIn, 0, N). mapargs_args(Pred, TermIn, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, TermIn, InArg), call(Pred, InArg), mapargs_args(Pred, TermIn, I1, N) ). mapargs(Pred, TermIn, TermOut) :- functor(TermIn, F, N), functor(TermOut, F, N), mapargs_args(Pred, TermIn, TermOut, 0, N). mapargs_args(Pred, TermIn, TermOut, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, TermIn, InArg), arg(I1, TermOut, OutArg), call(Pred, InArg, OutArg), mapargs_args(Pred, TermIn, TermOut, I1, N) ). mapargs(Pred, TermIn, TermOut1, TermOut2) :- functor(TermIn, F, N), functor(TermOut1, F, N), functor(TermOut2, F, N), mapargs_args(Pred, TermIn, TermOut1, TermOut2, 0, N). mapargs_args(Pred, TermIn, TermOut1, TermOut2, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, TermIn, InArg), arg(I1, TermOut1, OutArg1), arg(I1, TermOut2, OutArg2), call(Pred, InArg, OutArg1, OutArg2), mapargs_args(Pred, TermIn, TermOut1, TermOut2, I1, N) ). mapargs(Pred, TermIn, TermOut1, TermOut2, TermOut3) :- functor(TermIn, F, N), functor(TermOut1, F, N), functor(TermOut2, F, N), mapargs_args(Pred, TermIn, TermOut1, TermOut2, TermOut3, 0, N). mapargs_args(Pred, TermIn, TermOut1, TermOut2, TermOut3, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, TermIn, InArg), arg(I1, TermOut1, OutArg1), arg(I1, TermOut2, OutArg2), arg(I1, TermOut3, OutArg3), call(Pred, InArg, OutArg1, OutArg2, OutArg3), mapargs_args(Pred, TermIn, TermOut1, TermOut2, TermOut3, I1, N) ). mapargs(Pred, TermIn, TermOut1, TermOut2, TermOut3, TermOut4) :- functor(TermIn, F, N), functor(TermOut1, F, N), functor(TermOut2, F, N), functor(TermOut3, F, N), functor(TermOut4, F, N), mapargs_args(Pred, TermIn, TermOut1, TermOut2, TermOut3, TermOut4, 0, N). mapargs_args(Pred, TermIn, TermOut1, TermOut2, TermOut3, TermOut4, I, N) :- ( I == 0 -> true ; I1 is I+1, arg(I1, TermIn, InArg), arg(I1, TermOut1, OutArg1), arg(I1, TermOut2, OutArg2), arg(I1, TermOut3, OutArg3), arg(I1, TermOut4, OutArg4), call(Pred, InArg, OutArg1, OutArg2, OutArg3, OutArg4), mapargs_args(Pred, TermIn, TermOut1, TermOut2, TermOut3, TermOut4, I1, N) ). sumargs(Pred, Term, A0, A1) :- functor(Term, _, N), sumargs(Pred, Term, A0, A1, N). sumargs_args(_, _, A0, A1, 0) :- !, A0 = A1. sumargs_args(Pred, Term, A1, A3, N) :- arg(N, Term, Arg), N1 is N - 1, call(Pred, Arg, A1, A2), sumargs_args(Pred, Term, A2, A3, N1). foldargs(Goal, S, V0, V) :- functor(S, _, Ar), foldargs_(Goal, S, V0, V, 0, Ar). foldargs_(Goal, S, V0, V, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, S, A), call(Goal, A, V0, V1), foldargs_(Goal, S, V1, V, I, N) ). foldargs(Goal, S, O1, V0, V) :- functor(S, N, Ar), functor(O1, N, Ar), foldargs_(Goal, S, O1, V0, V, 0, Ar). foldargs_(Goal, S, O1, V0, V, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, S, A), arg(I1, O1, A1), call(Goal, A, A1, V0, V1), foldargs_(Goal, S, O1, V1, V, I, N) ). foldargs(Goal, S, O1, O2, V0, V) :- functor(S, N, Ar), functor(O1, N, Ar), functor(O2, N, Ar), foldargs_(Goal, S, O1, O2, V0, V, 0, Ar). foldargs_(Goal, S, O1, O2, V0, V, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, S, A), arg(I1, O1, A1), arg(I1, O2, A2), call(Goal, A, A1, A2, V0, V1), foldargs_(Goal, S, O1, O2, V1, V, I, N) ). foldargs(Goal, S, O1, O2, O3, V0, V) :- functor(S, N, Ar), functor(O1, N, Ar), functor(O2, N, Ar), functor(O3, N, Ar), foldargs_(Goal, S, O1, O2, O3, V0, V, 0, Ar). foldargs_(Goal, S, O1, O2, O3, V0, V, I, N) :- ( I == N -> true ; I1 is I+1, arg(I1, S, A), arg(I1, O1, A1), arg(I1, O2, A2), arg(I1, O3, A3), call(Goal, A, A1, A2, A3, V0, V1), foldargs_(Goal, S, O1, O2, O3, V1, V, I, N) ). goal_expansion(mapargs(Meta, In), (functor(In, _Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(mapargs, 1, Proto, GoalName), append(MetaVars, [In, 0, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, I, Ar], RecursionHead), append_args(Pred, [AIn], Apply), append_args(HeadPrefix, [In, I1, Ar], RecursiveCall), compile_aux([ (RecursionHead :- I == 0 -> true ; I1 is I+1, arg(I1, In, AIn), Apply, RecursiveCall ) ], Mod). goal_expansion(mapargs(Meta, In, Out), (functor(In, Name, Ar), functor(Out, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(mapargs, 2, Proto, GoalName), append(MetaVars, [In, Out, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out, I], RecursionHead), append_args(Pred, [AIn, AOut], Apply), append_args(HeadPrefix, [In, Out, I1], RecursiveCall), compile_aux([ (RecursionHead :- I == 0 -> true ; arg(I, In, AIn), arg(I, Out, AOut), Apply, I1 is I-1, RecursiveCall ) ], Mod). goal_expansion(mapargs(Meta, In, Out1, Out2), (functor(In, Name, Ar), functor(Out1, Name, Ar), functor(Out2, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(mapargs, 3, Proto, GoalName), append(MetaVars, [In, Out1, Out2, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out1, Out2, I], RecursionHead), append_args(Pred, [AIn, AOut1, AOut2], Apply), append_args(HeadPrefix, [In, Out1, Out2, I1], RecursiveCall), compile_aux([ (RecursionHead :- I == 0 -> true ; arg(I, In, AIn), arg(I, Out1, AOut1), arg(I, Out2, AOut2), Apply, I1 is I-1, RecursiveCall ) ], Mod). goal_expansion(mapargs(Meta, In, Out1, Out2, Out3), (functor(In, Name, Ar), functor(Out1, Name, Ar), functor(Out3, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(mapargs, 4, Proto, GoalName), append(MetaVars, [In, Out1, Out2, Out3, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out1, Out2, Out3, I], RecursionHead), append_args(Pred, [AIn, AOut1, AOut2, AOut3], Apply), append_args(HeadPrefix, [In, Out1, Out2, Out3, I1], RecursiveCall), compile_aux([ (RecursionHead :- I == 0 -> true ; arg(I, In, AIn), arg(I, Out1, AOut1), arg(I, Out2, AOut2), arg(I, Out3, AOut3), Apply, I1 is I-1, RecursiveCall ) ], Mod). goal_expansion(mapargs(Meta, In, Out1, Out2, Out3, Out4), (functor(In, Name, Ar), functor(Out1, Name, Ar), functor(Out3, Name, Ar), functor(Out4, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(mapargs, 4, Proto, GoalName), append(MetaVars, [In, Out1, Out2, Out3, Out4, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out1, Out2, Out3, Out4, I], RecursionHead), append_args(Pred, [AIn, AOut1, AOut2, AOut3, AOut4], Apply), append_args(HeadPrefix, [In, Out1, Out2, Out3, Out4, I1], RecursiveCall), compile_aux([ (RecursionHead :- I == 0 -> true ; arg(I, In, AIn), arg(I, Out1, AOut1), arg(I, Out2, AOut2), arg(I, Out3, AOut3), arg(I, Out4, AOut4), Apply, I1 is I-1, RecursiveCall ) ], Mod). goal_expansion(sumargs(Meta, Term, AccIn, AccOut), Mod:Goal) :- goal_expansion_allowed, prolog_load_context(module, Mod), Goal = ( Term =.. [_|TermArgs], sumlist(Meta, TermArgs, AccIn, AccOut) ). goal_expansion(foldargs(Meta, In, Acc0, AccF), (functor(In, _Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(foldargs, 1, Proto, GoalName), append(MetaVars, [In, Acc0, AccF, 0, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, VAcc0, VAccF, I, Ar], RecursionHead), append_args(Pred, [AIn, VAcc0, VAccI], Apply), append_args(HeadPrefix, [In, VAccI, VAccF, I1, Ar], RecursiveCall), compile_aux([ (RecursionHead :- I == Ar -> VAcc0 = VAccF ; I1 is I+1, arg(I1, In, AIn), Apply, RecursiveCall ) ], Mod). goal_expansion(foldargs(Meta, In, Out1, Acc0, AccF), (functor(In, Name, Ar), functor(Out1, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(foldargs, 2, Proto, GoalName), append(MetaVars, [In, Out1, Acc0, AccF, 0, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out1, VAcc0, VAccF, I, Ar], RecursionHead), append_args(Pred, [AIn, AOut1, VAcc0, VAccI], Apply), append_args(HeadPrefix, [In, Out1, VAccI, VAccF, I1, Ar], RecursiveCall), compile_aux([ (RecursionHead :- I == Ar -> VAcc0 = VAccF ; I1 is I+1, arg(I1, In, AIn), arg(I1, Out1, AOut1), Apply, RecursiveCall ) ], Mod). goal_expansion(foldargs(Meta, In, Out1, Out2, Acc0, AccF), (functor(In, Name, Ar), functor(Out1, Name, Ar), functor(Out2, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(foldargs, 3, Proto, GoalName), append(MetaVars, [In, Out1, Out2, Acc0, AccF, 0, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out1, Out2, VAcc0, VAccF, I, Ar], RecursionHead), append_args(Pred, [AIn, AOut1, AOut2, VAcc0, VAccI], Apply), append_args(HeadPrefix, [In, Out1, Out2, VAccI, VAccF, I1, Ar], RecursiveCall), compile_aux([ (RecursionHead :- I == Ar -> VAcc0 = VAccF ; I1 is I+1, arg(I1, In, AIn), arg(I1, Out1, AOut1), arg(I1, Out2, AOut2), Apply, RecursiveCall ) ], Mod). goal_expansion(foldargs(Meta, In, Out1, Out2, Out3, Acc0, AccF), (functor(In, Name, Ar), functor(Out1, Name, Ar), functor(Out2, Name, Ar), functor(Out3, Name, Ar), Mod:Goal)) :- goal_expansion_allowed, callable(Meta), prolog_load_context(module, Mod), aux_preds(Meta, MetaVars, Pred, PredVars, Proto), !, % the new goal pred_name(foldargs, 4, Proto, GoalName), append(MetaVars, [In, Out1, Out2, Out3, Acc0, AccF, 0, Ar], GoalArgs), Goal =.. [GoalName|GoalArgs], % the new predicate declaration HeadPrefix =.. [GoalName|PredVars], % the new predicate declaration append_args(HeadPrefix, [In, Out1, Out2, Out3, VAcc0, VAccF, I, Ar], RecursionHead), append_args(Pred, [AIn, AOut1, AOut2, AOut3, VAcc0, VAccI], Apply), append_args(HeadPrefix, [In, Out1, Out2, Out3, VAccI, VAccF, I1, Ar], RecursiveCall), compile_aux([ (RecursionHead :- I == Ar -> VAcc0 = VAccF ; I1 is I+1, arg(I1, In, AIn), arg(I1, Out1, AOut1), arg(I1, Out2, AOut2), arg(I1, Out3, AOut3), Apply, RecursiveCall ) ], Mod).