|
35 | 35 | ),
|
36 | 36 | write('.').
|
37 | 37 |
|
| 38 | +trace(on). |
| 39 | + |
| 40 | +writeln(X) :- |
| 41 | + trace(on), write(X), nl. |
| 42 | +x(G_0) :- |
| 43 | + catch(loader:G_0, E, (loader:writeln(exception:E:G_0),throw(E))). |
| 44 | +w(G_0) :- |
| 45 | + writeln(call:G_0), x(G_0), writeln(exit:G_0). |
| 46 | +w(_) :- |
| 47 | + writeln(done). |
| 48 | + |
| 49 | +%% arithmetic_relation_expanded(?Term, ListDifference). |
| 50 | +% |
| 51 | +% Recursively traverse Term and assemble a list of replacements that make a |
| 52 | +% valid aruthmetic relation. |
| 53 | +% |
| 54 | +% Hand-expanded DCG, because library(dcgs) isn't available during goal expansion. |
| 55 | +arithmetic_relation_expanded(T, L1-L2) :- |
| 56 | + maplist(loader:elaborate(F/2), [T,R], [Ts,Rs]), |
| 57 | + memberchk(F, [is,>,<,>=,=<,=:=,=\=]), |
| 58 | + next(ok(Ts,Rs), L1-[R|L2]). |
| 59 | + |
| 60 | +%% next(+Marker, ListDifference). |
| 61 | +% |
| 62 | +% Describes needed replacements according to `Marker`. |
| 63 | +next(nok(T,R), [T=R|L]-L). |
| 64 | +next(ok([],[]), L-L). |
| 65 | +next(ok([T0|Ts],[R0|Rs]), L1-L3) :- |
| 66 | + arithmetic_function_expanded(T0, R0, L1-L2), next(ok(Ts,Rs), L2-L3). |
| 67 | + |
| 68 | +%% arithmetic_function_expanded(?Term, -ExpandedTerm, ListDifference). |
| 69 | +arithmetic_function_expanded(T, R, LD) :- |
| 70 | + check(T, R, C), next(C, LD). |
| 71 | + |
| 72 | +%% check(?Term, -ExpandedTerm, -Marker). |
| 73 | +% |
| 74 | +% `Marker` describes what is `Term` in regards to arithmetical function, it is |
| 75 | +% `ok/2` if `Term` is Ok to be a part of arithmetical function and it is `nok/2` |
| 76 | +% if it isn't. |
| 77 | +% |
| 78 | +% NOTE: Order of `check/3` clauses is important for correctness. |
| 79 | +check(T, T, ok([],[])) :- (var(T); number(T)), !. |
| 80 | +check(T, R, ok(Ts,Rs)) :- |
| 81 | + maplist(loader:elaborate(F/A), [T,R], [Ts,Rs]), |
| 82 | + arithmetic_functions(A, Fs), |
| 83 | + member(F, Fs), !. |
| 84 | +check(T, R, nok(T,R)) :- !. |
| 85 | + |
| 86 | +elaborate(Functor/Arity, Term, Args) :- |
| 87 | + functor(Term, Functor, Arity), |
| 88 | + Term =.. [Functor|Args]. |
| 89 | + |
| 90 | +arithmetic_functions(0, [e,pi,epsilon]). |
| 91 | +arithmetic_functions(1, [+,-,\,sqrt,exp,log,sin,cos,tan,asin,acos,atan,sign,abs,round,ceiling,floor,truncate,float,float_integer_part,float_fractional_part]). |
| 92 | +arithmetic_functions(2, [+,-,/,*,**,^,/\,\/,xor,div,//,rdiv,<<,>>,mod,rem,max,min,gcd,atan2]). |
38 | 93 |
|
39 | 94 | :- non_counted_backtracking '$print_message_and_fail'/1.
|
40 | 95 |
|
|
43 | 98 | nl,
|
44 | 99 | '$fail'.
|
45 | 100 |
|
| 101 | + |
46 | 102 | expand_term(Term, ExpandedTerm) :-
|
47 | 103 | ( '$predicate_defined'(user, term_expansion, 2),
|
48 | 104 | catch(user:term_expansion(Term, ExpandedTerm0),
|
|
69 | 125 | term_expansion_list(Terms, ExpandedTerms0Tail, ExpandedTermsTail)
|
70 | 126 | ).
|
71 | 127 |
|
72 |
| - |
73 | 128 | :- non_counted_backtracking goal_expansion/3.
|
74 | 129 |
|
75 |
| -goal_expansion(G, user, (Y = Rhs, X is Y)) :- |
| 130 | +goal_expansion(G, _, Gx) :- |
76 | 131 | % Additional rule just to replace invalid arithmetic expression with
|
77 | 132 | % runtime exception
|
78 | 133 | nonvar(G),
|
79 |
| - G = (X is Rhs), |
80 |
| - nonvar(Rhs), |
81 |
| - (Rhs == []; Rhs = [_|_]). |
| 134 | + arithmetic_relation_expanded(G, Gx-[]). |
82 | 135 | goal_expansion(Goal, Module, ExpandedGoal) :-
|
83 | 136 | ( atom(Module),
|
84 | 137 | '$predicate_defined'(Module, goal_expansion, 2),
|
|
0 commit comments