34
35:- export(eepsilon/2). 36:- export(eepsilon/3). 37:- export(eval/3). 38:- export(cast/3). 39:- export(castable/2). 40:- export(compare/4). 41:- export(near_compare/4). 42
43:- use_module(library(solution_sequences)). 44
45:- public eval_1/4. 46
47:- multifile check_dupcode:ignore_dupcode/3. 48
50check_dupcode:ignore_dupcode(Head, Source, _) :-
51 '$current_source_module'(Source),
52 member(F/A, [eepsilon/2, eepsilon/3, eval/3, cast/3, castable/2, compare/4, near_compare/4,
53 compare/5, do_eval_cputime/2, do_eval_z/2, reserve_eps/1, near_compare_b/4]),
54 functor(Head, F, A),
55 neck.
56
57eval_1(Type, Arg, eval(Type, Arg, EA), EA).
58
59eval(_, Expr, _) :-
60 var(Expr),
61 !,
62 fail.
63eval(Type, Expr, C) :-
64 do_eval(Expr, Type, C),
65 !.
66eval(Type, Value, C) :-
67 cast(Type, Value, C),
68 !.
69eval(Type, Value, _) :-
70 throw(error(type_error(evaluable, Type:Value), _)).
71
72cast(Type, Value, C) :-
73 ( inner_cast(Type, Value, C)
74 ->true
75 ; integer(Value)
76 ->term_string(Value, String),
77 cast(Type, String, C)
78 ; rational(Value)
79 ->X is numerator(Value),
80 Y is denominator(Value),
81 do_eval(X/Y, Type, C)
82 ; ground(Value)
83 ->do_eval(Value, Type, C)
84 ).
85
86castable(Type, Value) :-
87 cd_prefix(Type, Pref, _),
88 atom_concat(is_, Pref, Func),
89 Body =.. [Func, Value],
90 necki,
91 Body.
92
93inner_cast(Type, Value, C) :-
94 cd_prefix(Type, Pref, EAL),
95 append([Value|EAL], [C], AL),
96 Body =.. [Pref|AL],
97 necki,
98 Body.
99
100do_eval_cputime(T, V) :-
101 X is cputime,
102 inner_cast(T, X, V).
103
104:- table
105 do_eval_z/2,
106 eepsilon/2. 107
108do_eval_z(Type, C) :- cast(Type, 0, C).
109
110eepsilon(T, E) :-
111 reserve_eps(N),
112 eval(T, N*epsilon, E).
113
114eepsilon(T, N, E) :-
115 eepsilon(T, R),
116 eval(T, R*N, E).
117
118compare(Type, Op, A, B) :-
119 eval(Type, A, X),
120 eval(Type, B, Y),
121 compare_b(Op, Type, X, Y).
122
123near_compare(Type, Op, A, B) :-
124 eval(Type, A, X),
125 eval(Type, B, Y),
126 near_compare_b(Type, Op, X, Y).
127
128near_compare_b(Type, Op, X, Y) :-
129 ( compare_b(=, Type, X, Y)
130 ->compare_eq(Op)
131 ; eepsilon(Type, max(abs(X), abs(Y)), E),
132 compare(Op, Type, X, Y, E)
133 ).
134
135compare(=, T, A, B, E) :- compare(T, =<, abs(A - B), E).
136compare(=<, T, A, B, E) :- compare(T, =<, A - B, E).
137compare(>=, T, A, B, E) :- compare(T, =<, B - A, E).
138compare(<, T, A, B, E) :- compare(T, >, B - A, E).
139compare(>, T, A, B, E) :- compare(T, >, A - B, E).
140compare(\=, T, A, B, E) :- compare(T, >, abs(A - B), E).
141
142compare_b(Op, Type, X, Y) :-
143 op_pred(Op, Pred),
144 Body =.. [Pred, Type, X, Y],
145 necki,
146 Body.
147
148Head :-
149 op_pred(_, Pred),
150 Head =.. [Pred, Type, X, Y],
151 cd_prefix(Type, Pref, _),
152 atomic_list_concat([Pref, '_', Pred], F),
153 Body =.. [F, X, Y],
154 necki,
155 Body.
156
157Head :-
158 distinct(Pred, expr_pred(_, Pred)),
159 Pred =.. [Name|AL],
160 Head =.. [Name, Type, C|AL],
161 cd_prefix(Type, Pref, EAL),
162 atomic_list_concat([Pref, '_', Name], BN),
163 append(EAL, [C|AL], BL),
164 Body =.. [BN|BL],
165 necki,
166 Body