Search code examples
sortingprologcountingnon-deterministic

How count Dijkstra guards sort executions in Prolog


I do not find a Prolog cut in Dijsktras "if fi", since he says "otherwise an arbitrary guarded list with a true guard will be selected for execution.". So his construct, does not choose the first match, as a Prolog cut would do:

if Cond1 -> Action11, .., Action1n1
[] Cond2 -> Action21, .., Action2n2
...
[] Condm -> Actionm1, .., Actionmn2
if

Is there maybe a Prolog cut in the "do od" construct, which loops as long as at least one condition of a guarded list is true? Or maybe some other approach to realize it in Prolog, I assume a loop can be translated to a recursive call. So how would we do this sorting of q1,q2,q3,q4 in Prolog:

do q1 > q2 -> q1,q2 := q2,q1
[] q2 > q3 -> q2,q3 := q3,q2
[] q3 > q4 -> q3,q4 := q4,q3
od

How many non-deterministic execution paths aka Prolog solutions will the Prolog program have for input 7,11,5,3 that all provide the same answer?


Solution

  • I think you can do something like this:

    do([Q1,Q2,Q3,Q4], [swap(Q1,Q2)|P], S) :-
        Q1 > Q2,
        do([Q2,Q1,Q3,Q4], P, S).
    
    do([Q1,Q2,Q3,Q4], [swap(Q2,Q3)|P], S) :-
        Q2 > Q3,
        do([Q1,Q3,Q2,Q4], P, S).
    
    do([Q1,Q2,Q3,Q4], [swap(Q3,Q4)|P], S) :-
        Q3 > Q4,
        do([Q1,Q2,Q4,Q3], P, S).
    
    do([Q1,Q2,Q3,Q4], [], [Q1,Q2,Q3,Q4]) :- % termination state
        Q1 =< Q2,
        Q2 =< Q3,
        Q3 =< Q4.
    

    Execution:

    ?- do([7,11,5,3],P,S).
    P = [swap(11, 5), swap(7, 5), swap(11, 3), swap(7, 3), swap(5, 3)],
    S = [3, 5, 7, 11] ;
    P = [swap(11, 5), swap(11, 3), swap(7, 5), swap(7, 3), swap(5, 3)],
    S = [3, 5, 7, 11] ;
    P = [swap(11, 5), swap(11, 3), swap(5, 3), swap(7, 3), swap(7, 5)],
    S = [3, 5, 7, 11] ;
    P = [swap(5, 3), swap(11, 3), swap(7, 3), swap(11, 5), swap(7, 5)],
    S = [3, 5, 7, 11] ;
    P = [swap(5, 3), swap(11, 3), swap(11, 5), swap(7, 3), swap(7, 5)],
    S = [3, 5, 7, 11] ;
    false.