So compare_with_stack/5 cannot be used for sort/2.
Edit 03.04.2023
But they are very few. They are much rarer than those for native compare/3 or
for compare_stack/3. When using 10’000’000 iterations I get:
Hope its not a bug in SWI-Prolog itself. But if it were a bug, since I can reproduce an example
on the top-level, it would be a bug not related to the failure driven loop.
Thanks you for Monkey test, which should have been done by me as you say.
Yes, that is sureyly a bug, hopefully, a careless bug.
I changed meaning of order in the compare history, older is smaller, then the bug case fixed.
But not sure for other cases.
I really appreciate if you would kindly do the Monkey test for me.
Below is the only predicate that I changed due to the bug found by Monkey test (Monkey is great !). I thought one could not make error on such a simple one, but I made error. This time I change so that for example, [a, b, c, d] means chronological ordering d<c<b<a.
force_order_in_arity_grouping(C, X, Y, G, G0):-
( memberchk(X, G)->
( memberchk(Y, G) ->
( precede(X, Y, G) -> C = (>)
; C = (<)
),
G0 = G
; C = (<),
G0 = [Y|G]
)
; memberchk(Y, G)->
C = (>),
G0 = [X|G]
; C = (>),
G0 = [X, Y|G]
).
I have reproduced the similar result, which is still strange to me. I have to ask the Monkey seriously, and review also “incomparability” concept for cyclic terms, which is most fundamental for compare_with_stack. So far, I have no doubt for that.
I met a strange error message below, which was issued by clpfd order.
My compare_with_stack never passes ‘incomparable’ to the standard compare/3.
To conentrate on compare_with_stack, is it possible to separate clpfd off. clpfd seems called
from Monkey.
% ?- between(1,1000000,_), random_cyclic(T1), ground(T1), random_cyclic(T2), ground(T2),
% random_cyclic(T3), ground(T3), compare_with_stack(Ct,T1,T2),
% compare_with_stack(Ct,T2,T3), compare_with_stack(C,T1,T3),C\=Ct.
%@ ERROR: Domain error: `order' expected, found `incomparable'
%@ ERROR: In:
%@ ERROR: [13] compare(incomparable,s(s(...,...),1),1)
%@ ERROR: [10] '<meta-call>'('<garbage_collected>') <foreign>
%@ ERROR: [9] toplevel_call('<garbage_collected>') at /Users/cantor/lib/swipl/boot/toplevel.pl:1173
%@ ERROR:
%@ ERROR: Note: some frames are missing due to last-call optimization.
%@ ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
% ?- listing(order).
%@ clpfd:order(up).
%@ clpfd:order(down).
%@ clpfd:order(random_value(Seed)) :-
%@ must_be(integer, Seed),
%@ set_random(seed(Seed)).
%@
%@ true.
I am struggling with the puzzle. However, so far I have found no bug in the compare_with_stack/5.
So I put back the order in the history as before, that is, a list as history [a,b,c,d] of
cyclic terms appearing as incomparable terms, represents the current linear (forced) order a<b<c<d.
As for your “violation” example, it seems normal as I expected:
History is growing
[] -> [T1, T2] -> [T3, T1, T2]
Note that the order grows T1< T2 ===> T3 < T1<T2
I found nothing wrong of the code. However, Monkey generates non zero violation counts cases.
Sorry, but they are just reverse order to each other.
Take, for example, a list [a,b,c] as a<b, a<c, b<c. It is obviously transitive.
As you informed us that @< is no more total ordering on rational trees
by introducing the Carllson’s pair x=f(y,0), y=f(x, 1).
My idea is to keep a list of such cyclic terms by “chronologicall order” only which has been
decided to be incomparable with some other cyclic terms. The cyclic term x is not
put in the list as far as x is compared only with finite terms.
I don’t think by any means it is smart to bring such compare-history, buit it is only one of ways of keeping @< as a locally total linear ordering.
EDIT. 2023/04/05
I used a wrong predicate for Monkey tes. Sorry for that. This time it is done with corret one.
compare_with_stack/3,5 has passed Monkey test on transitivity, which I take as symptone that
it now works as I intended. The standard @< got violation count 158.
I am sad to report that increasing stress for Monkey test, it returns violation on semi_lex_compare on transitivity. Although I am still fairy sure on the semi_lex_compare transitivity , I have to re-re-rereview that simple codes. Please let me take time to enjoy the puzzle.
Although I know nothing compare/3 of other Prolog’s, let me summarize what I have thought and done about comparing cyclic terms, most of which have been posted somewhere related threads.
First, I reviewed fixed-point based construction on the following things from scratch.
H: Herebrand Universe (the standard ground terms.)
@< : The sandard lexcical order on H, which is linear and total on H.
R: Rational Terms
@@<<: lexical order, which is transitive and total on R.
However @@<< is NOT ANTI-SYMMETRIC.x\=y, x @@<< y, and y@@<< x are possible together. A counter example is the Matts Carllsons pair x=s(y,0), y=s(x,1).
These results are easy by really simple fixpint argument of monotone increasing
operations on sets theoretical encoding for H and R. These encoding are easy but tedious to write down so that I preferred to write some prolog codes, which is for escaping from such boring jobs.
In fact, in spite of these theoretical but easy consideration, I wrote a several compare/3 friends on the rational trees with stack, heap or arity-path-trees, though two of them I did not post.
And the Monkey test correctly destroyed all my trials showing counter examples. I should thank J. Burse for his great Monky test, which now takes me to think that the experiment shows that my theoretical consideration is sadly correct.
However, I think another @@<< like compare/3 might be possible which is free from the anti-symmetricity with some sophistcated monotone operations usable for prolog cyclic terms, though I have no idea about it at all for now.
This summary might explain why SWI-Prolog document carefully(?) does not mention to compareing rational trees, because theoretically it is impossible in the sense of the fixpoint I used.