Is there a Picat style (=>)/2 for if-then-else? Since this rule would bark,
when the comparator returns something outside of the 3 values
(<), (=) and (>), which is not extremly likely:
union3(<, H1, T1, H2, T2, Union) =>
Union = [H1|Union0],
union2(T1, H2, T2, Union0).
union3(=, H1, T1, _H2, T2, Union) =>
Union = [H1|Union0],
ord_union(T1, T2, Union0).
union3(>, H1, T1, H2, T2, Union) =>
Union = [H2|Union0],
union2(T2, H1, T1, Union0).
The semantic of a (=>)/2 if-then-else could be similar to a (=>)/2 rule.
If no condition succeeds, an error is thrown. I tested if-then-else without an
error branch, somehow a local if-then-else is ca. 10% faster, also shows
fewer inferences since I only used one predicate ord_union2/3:
?- time((test, fail; true)).
% 26,742,302 inferences, 0.516 CPU in 0.533 seconds
(97% CPU, 51863858 Lips)
true.
109 ?- time((test2, fail; true)).
% 16,780,318 inferences, 0.484 CPU in 0.478 seconds
(101% CPU, 34643237 Lips)
true.
Surprisingly Picat itself seems not to have an if-then-else with (=>)/2,
while its rather common in Haskell, for expressions, and generalizes
rules and local if-then-else somehow into one and the same pattern matching.
P.P.S.: Was using this, the if-then-else uses (->)/2, but an
if-then-else with (=>)/2 is also somehow conceivable.
ord_union2([], X, R) => R = X.
ord_union2(X, [], R) => R = X.
ord_union2([X|L], [Y|R], S) => compare(C, X, Y),
(C = (<) -> S = [X|T], ord_union2(L, [Y|R], T);
C = (=) -> S = [X|T], ord_union2(L, R, T);
C = (>) -> S = [Y|T], ord_union2([X|L], R, T)).
test2 :-
numlist(1,10, L),
numlist(1,10, R),
enum_subset(L, P),
enum_subset(R, Q),
ord_union2(P,Q,_).