rfi-p> exec opstup relfun rfi-p> % RelFun Operations on N-Tuples of Numeric and Symbolic Elements rfi-p> % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rfi-p> % Harold Boley 12-Nov-98 rfi-p> rfi-p> rfi-p> miser-level 0 rfi-p> destroy rfi-p> rfi-p> rfi-p> % (Nested) N-Tuples Can be Constructed by tup Calls Over Element Calls rfi-p> rfi-p> tup(+(3.5, 4.75), -(3.5, 4.75), *(3.5, 4.75), /(3.5, 4.75)) % prefix all [8.25, -1.25, 16.625, 0.7368421] rfi-p> tup(+(3.5, 4.75), tup(-(3.5, 4.75), *(3.5, 4.75), /(3.5, 4.75))) % nest [8.25, [-1.25, 16.625, 0.7368421]] rfi-p> tup(+(3.5, 4.75) | tup(-(3.5, 4.75), *(3.5, 4.75), /(3.5, 4.75))) % flat [8.25, -1.25, 16.625, 0.7368421] rfi-p> rfi-p> pause() % 1 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Defining Scalar Product ... rfi-p> rfi-p> % ... as "%"-Commented, "="-Infixed Mathematical Equations rfi-p> rfi-p> % smultup(r,[]) = [] for N=0 rfi-p> % smultup(r,[a1, a2, ..., aN]) = [r*a1, r*a2, ..., r*aN] for N>0 rfi-p> rfi-p> % ... as "az"-Asserted, "!&"-Infixed RelFun Equations rfi-p> rfi-p> az smultup(R,[]) !& []. % recursive call rfi-p> az smultup(R,[A1 | A2toN]) !& tup(*(R,A1) | smultup(R,A2toN)). rfi-p> rfi-p> % Calling Scalar Product rfi-p> rfi-p> smultup(3, []) [] rfi-p> smultup(3.5, [1.12, 4.75, 0.81]) [3.92, 16.625, 2.835] rfi-p> rfi-p> pause() % 2 relfun rfi-p> bye true rfi-p> rfi-p> trace smultup % recurse down to the empty tuple [] rfi-p> smultup(-1, [3.14, -2.48, 7.02]) >2 smultup(-1, [3.14, -2.48, 7.02]) :- & >2 smultup(-1, [-2.48, 7.02]) :- & >2 smultup(-1, [7.02]) :- & >1 smultup(-1, []) :- & <1 smultup(-1, []) :-& [] <2 smultup(-1, [7.02]) :-& [-7.02] <2 smultup(-1, [-2.48, 7.02]) :-& [2.48, -7.02] <2 smultup(-1, [3.14, -2.48, 7.02]) :-& [-3.14, 2.48, -7.02] [-3.14, 2.48, -7.02] rfi-p> notrace smultup % and induce up to the result 3-tuple rfi-p> rfi-p> pause() % 3 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Defining Sum rfi-p> rfi-p> % addtup([],[]) = [] for N=0 rfi-p> % addtup([a1, a2, ..., aN], [b1, b2, ..., bN]) = rfi-p> % [a1+b1, a2+b2, ..., aN+bN] for N>0 rfi-p> rfi-p> az addtup([],[]) !& []. rfi-p> az addtup([A1 | A2toN], [B1 | B2toN]) !& tup(+(A1,B1) | addtup(A2toN,B2toN)). rfi-p> rfi-p> % Calling Sum rfi-p> rfi-p> addtup([], []) [] rfi-p> addtup([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) [4.26, 2.27, 7.83] rfi-p> rfi-p> pause() % 4 relfun rfi-p> bye true rfi-p> rfi-p> trace addtup rfi-p> addtup([3.14, -2.48], [1.12, 4.75, 0.81]) % unknown for different Ns >2 addtup([3.14, -2.48], [1.12, 4.75, 0.81]) :- & >2 addtup([-2.48], [4.75, 0.81]) :- & ~> addtup([], [0.81]) ~!2 addtup([-2.48], [4.75, 0.81]) ~!2 addtup([3.14, -2.48], [1.12, 4.75, 0.81]) unknown rfi-p> notrace addtup rfi-p> rfi-p> pause() % 5 relfun rfi-p> bye true rfi-p> rfi-p> % Calling Difference (as Sum with Scalar Product) rfi-p> rfi-p> addtup([3.14, -2.48, 7.02], smultup(-1, [1.12, 4.75, 0.81])) [2.02, -7.23, 6.21] rfi-p> addtup([3.14, -2.48, 7.02], smultup(-1, [3.14, -2.48, 7.02])) [0.0, 0.0, 0.0] rfi-p> rfi-p> pause() % 6 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Defining (Higher-Order) Combination Function for Binary F Parameter rfi-p> rfi-p> % combtup[F]([],[]) = [] for N=0 rfi-p> % combtup[F]([a1, a2, ..., aN], [b1, b2, ..., bN]) = rfi-p> % [F(a1,b1), F(a2,b2), ..., F(aN,bN)] for N>0 rfi-p> rfi-p> az combtup[F]([],[]) !& []. rfi-p> az combtup[F]([A1 | A2toN], [B1 | B2toN]) !& tup(F(A1,B1) | combtup[F](A2toN,B2toN)). rfi-p> rfi-p> % Calling (Higher-Order) Combination Function with Special F Parameters rfi-p> rfi-p> combtup[+]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % see above [4.26, 2.27, 7.83] rfi-p> combtup[-]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % see above [2.02, -7.23, 6.21] rfi-p> combtup[*]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % new numeric use [3.5168002, -11.78, 5.6862] rfi-p> combtup[/]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % new numeric use [2.8035715, -0.5221053, 8.666667] rfi-p> rfi-p> pause() % 7 relfun rfi-p> bye true rfi-p> rfi-p> combtup[<]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % numeric boolean [false, true, false] rfi-p> combtup[>=]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % numeric boolean [true, false, true] rfi-p> rfi-p> combtup[string<]([a, b, c, d], [alpha, beta, gamma, delta]) % symbolic [1, 1, 0, 1] rfi-p> combtup[string>=]([a, b, c, d], [alpha, beta, gamma, delta]) % boolean [false, false, false, false] rfi-p> rfi-p> pause() % 8 relfun rfi-p> bye true rfi-p> rfi-p> combtup[tup]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % pair numbers [[3.14, 1.12], [-2.48, 4.75], [7.02, 0.81]] rfi-p> combtup[tup]([a, b, c], [alpha, beta, gamma]) % or symbols [[a, alpha], [b, beta], [c, gamma]] rfi-p> rfi-p> pause() % 9 relfun rfi-p> bye true rfi-p> rfi-p> az swap(A,B) !& [B,A]. % auxiliary definition can rfi-p> tup(swap(3.14, 1.12), swap(a, alpha)) % swap numbers and symbols [[1.12, 3.14], [alpha, a]] rfi-p> combtup[swap]([3.14, -2.48, 7.02], [1.12, 4.75, 0.81]) % swap numbers [[1.12, 3.14], [4.75, -2.48], [0.81, 7.02]] rfi-p> combtup[swap]([a, b, c], [alpha, beta, gamma]) % or symbols [[alpha, a], [beta, b], [gamma, c]] rfi-p> rfi-p> pause() % 10 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Defining/Calling (Higher-Order) Function Mapping Unary F Over Tuples rfi-p> rfi-p> az maptup[F]([]) !& []. rfi-p> az maptup[F]([A1 | A2toN]) !& tup(F(A1) | maptup[F](A2toN)). rfi-p> rfi-p> sqrt(4.75) 2.1794496 rfi-p> maptup[sqrt]([1.12, 4.75, 0.81]) % apply unary sqrt to all elements [1.0583005, 2.1794496, 0.9] rfi-p> rfi-p> pause() % 11 relfun rfi-p> bye true rfi-p> rfi-p> az mult[R](Ai) !& *(R,Ai). % mult[R] is unary version of binary "*" rfi-p> mult[3.5](4.75) 16.625 rfi-p> maptup[mult[3.5]]([1.12, 4.75, 0.81]) % higher-order-like scalar product [3.92, 16.625, 2.835] rfi-p> rfi-p> pause() % 12 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Defining and (Enumeration-)Calling Non-Deterministic Numeric Function rfi-p> rfi-p> az plusminus(N) :& N. % two right-hand sides, N and rfi-p> az plusminus(N) :& *(-1,N). % -N, for same left-hand side rfi-p> rfi-p> plusminus(3.14) 3.14 rfi-p> more % enumerate more returned values: second success -3.14 rfi-p> more % enumerate more returned values: unknown = failure unknown rfi-p> rfi-p> plusminus(-2.48) -2.48 rfi-p> more 2.48 rfi-p> rfi-p> pause() % 13 relfun rfi-p> bye true rfi-p> rfi-p> maptup[plusminus]([1.12, 4.75, 0.81]) [1.12, 4.75, 0.81] rfi-p> more [1.12, 4.75, -0.81] rfi-p> more % either request more interactively [1.12, -4.75, 0.81] rfi-p> more [1.12, -4.75, -0.81] rfi-p> more [-1.12, 4.75, 0.81] rfi-p> more [-1.12, 4.75, -0.81] rfi-p> more % or use tupof finite solution set: [-1.12, -4.75, 0.81] rfi-p> more [-1.12, -4.75, -0.81] rfi-p> tupof(maptup[plusminus]([1.12, 4.75, 0.81])) [[1.12, 4.75, 0.81], [1.12, 4.75, -0.81], [1.12, -4.75, 0.81], [1.12, -4.75, -0.81], [-1.12, 4.75, 0.81], [-1.12, 4.75, -0.81], [-1.12, -4.75, 0.81], [-1.12, -4.75, -0.81]] rfi-p> rfi-p> pause() % 14 relfun rfi-p> bye true rfi-p> rfi-p> tupof(plusminus(sqrt(4.75))) [2.1794496, -2.1794496] rfi-p> tupof(maptup[plusminus](maptup[sqrt]([1.12, 4.75, 0.81]))) % two passes [[1.0583005, 2.1794496, 0.9], [1.0583005, 2.1794496, -0.9], [1.0583005, -2.1794496, 0.9], [1.0583005, -2.1794496, -0.9], [-1.0583005, 2.1794496, 0.9], [-1.0583005, 2.1794496, -0.9], [-1.0583005, -2.1794496, 0.9], [-1.0583005, -2.1794496, -0.9]] rfi-p> rfi-p> pause() % 15 relfun rfi-p> bye true rfi-p> rfi-p> az compose[F,G](X) !& F(G(X)). rfi-p> tupof(compose[plusminus,sqrt](4.75)) [2.1794496, -2.1794496] rfi-p> tupof(maptup[compose[plusminus,sqrt]]([1.12, 4.75, 0.81])) % one pass [[1.0583005, 2.1794496, 0.9], [1.0583005, 2.1794496, -0.9], [1.0583005, -2.1794496, 0.9], [1.0583005, -2.1794496, -0.9], [-1.0583005, 2.1794496, 0.9], [-1.0583005, 2.1794496, -0.9], [-1.0583005, -2.1794496, 0.9], [-1.0583005, -2.1794496, -0.9]] rfi-p> rfi-p> pause() % 16 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Defining and (Enumeration-)Calling Non-Deterministic Symbolic Function rfi-p> rfi-p> az listswap(A,B) :& [A,B]. % just list arguments rfi-p> az listswap(A,B) :& [B,A]. % or swap them around rfi-p> rfi-p> tupof(listswap(a, alpha)) % length of solution tuple: 2 [[a, alpha], [alpha, a]] rfi-p> tupof(combtup[listswap]([a, b, c], [alpha, beta, gamma])) % len: 8 [[[a, alpha], [b, beta], [c, gamma]], [[a, alpha], [b, beta], [gamma, c]], [[a, alpha], [beta, b], [c, gamma]], [[a, alpha], [beta, b], [gamma, c]], [[alpha, a], [b, beta], [c, gamma]], [[alpha, a], [b, beta], [gamma, c]], [[alpha, a], [beta, b], [c, gamma]], [[alpha, a], [beta, b], [gamma, c]]] rfi-p> rfi-p> pause() % 17 relfun rfi-p> bye true rfi-p> rfi-p> rfi-p> % Calling Functions with Non-Ground (Free) Actual Arguments rfi-p> rfi-p> swap(X,Y) % non-ground call of deterministic definition [B*1, A*1] X = A*1 Y = B*1 rfi-p> more % "!&" cuts off more equations: 1 non-ground solution unknown rfi-p> rfi-p> listswap(X,Y) % non-ground call of non-deterministic definition [A*1, B*1] X = A*1 Y = B*1 rfi-p> more % ":&" permits second equation: 2 non-ground solutions [B*1, A*1] X = A*1 Y = B*1 rfi-p> more unknown rfi-p> rfi-p> pause() % 18 relfun rfi-p> nopausebye rfi-p> bye true rfi-p> rfi-p> rfi-p> % Application to Wholesale Dealers' Daily Fruit Orders rfi-p> rfi-p> % name year,month,day apples,bananas,oranges,peaches rfi-p> az order(clark,time[1998,11, 5]) :& [295.1, 283.4, 0.0, 64.3]. rfi-p> az order(clark,time[1998,11, 6]) :& [ 0.0, 118.5, 0.0, 36.7]. rfi-p> az order(dewey,time[1998,11, 9]) :& [253.2, 336.1, 195.6, 58.4]. rfi-p> rfi-p> order(N,T) % non-deterministic ":&"-definition permits such calls [295.1, 283.4, 0.0, 64.3] N = clark T = time[1998, 11, 5] rfi-p> more % to enumerate all unifying dealers' daily fruit orders [0.0, 118.5, 0.0, 36.7] N = clark T = time[1998, 11, 6] rfi-p> more % (or you could use a tupof) [253.2, 336.1, 195.6, 58.4] N = dewey T = time[1998, 11, 9] rfi-p> rfi-p> order(N,time[1998,11,D]) % all unify also with this call [295.1, 283.4, 0.0, 64.3] N = clark D = 5 rfi-p> more [0.0, 118.5, 0.0, 36.7] N = clark D = 6 rfi-p> more [253.2, 336.1, 195.6, 58.4] N = dewey D = 9 rfi-p> rfi-p> order(clark,time[1998,11,D]) % only Clark's orders unify now [295.1, 283.4, 0.0, 64.3] D = 5 rfi-p> more [0.0, 118.5, 0.0, 36.7] D = 6 rfi-p> more unknown rfi-p> rfi-p> pause() % 19 true rfi-p> rfi-p> smultup(0.9,order(dewey,time[1998,11,9])) % for Dewey's order next day [227.87999, 302.49, 176.04, 52.56] rfi-p> rfi-p> addtup(order(clark,time[1998,11,5]),order(clark,time[1998,11,6])) % etc. [295.1, 401.9, 0.0, 101.0] rfi-p> rfi-p> pause() % 20 true rfi-p> rfi-p> rfi-p> rfi-p> rfi-p> rfi-p> % Defining and (Enumeration-)Calling Determ. Element-Replacing Function rfi-p> rfi-p> az repall(Old,New,[]) !& []. % we are done rfi-p> az repall(Old,New,[Old|R]) !& tup(New|repall(Old,New,R)). % found 1 Old rfi-p> az repall(Old,New,[ H|R]) !& tup(H |repall(Old,New,R)). % search rest rfi-p> rfi-p> repall(oranges,lemons,[apples,bananas,oranges,peaches]) [apples, bananas, lemons, peaches] rfi-p> rfi-p> repall(0.0,1.0,order(clark,time[1998,11,6])) % nested call: deterministic [1.0, 118.5, 1.0, 36.7] rfi-p> tupof(repall(0.0,1.0,order(N,time[1998,11,D]))) % -"- : non-deterministic [[295.1, 283.4, 1.0, 64.3], [1.0, 118.5, 1.0, 36.7], [253.2, 336.1, 195.6, 58.4]]