Definition of a path/trail/walk

后端 未结 3 1250
你的背包
你的背包 2020-11-22 04:21

Many predicates define some kind of an acyclic path built from edges defined via a binary relation, quite similarly to defining transitive closure. A generic definition is t

3条回答
  •  耶瑟儿~
    2020-11-22 04:59

    How about defining path/4 like this?

    path(R_2, Xs, A,Z) :-                   % A path `Xs` from `A` to `Z` is ...
       walk(R_2, Xs, A,Z),                  % ... a walk `Xs` from `A` to `Z` ...
       all_dif(Xs).                         % ... with no duplicates in `Xs`.
    

    To aid universal termination, we swap the two goals in above conjunction ...

    path(R_2, Xs, A,Z) :-
       all_dif(Xs),                         % enforce disequality ASAP
       walk(R_2, Xs, A,Z).
    

    ... and use the following lazy implementation of all_dif/1:

    all_dif(Xs) :-                          % enforce pairwise term inequality
       freeze(Xs, all_dif_aux(Xs,[])).      % (may be delayed)
    
    all_dif_aux([], _).
    all_dif_aux([E|Es], Vs) :-               
       maplist(dif(E), Vs),                 % is never delayed
       freeze(Es, all_dif_aux(Es,[E|Vs])).  % (may be delayed)
    

    walk/4 is defined like path/4 and path/5 given by the OP:

    :- meta_predicate walk(2, ?, ?, ?).
    walk(R_2, [X0|Xs], X0,X) :-
       walk_from_to_step(Xs, X0,X, R_2).
    
    :- meta_predicate walk_from_to_step(?, ?, ?, 2).
    walk_from_to_step([], X,X, _).
    walk_from_to_step([X1|Xs], X0,X, R_2) :-
       call(R_2, X0,X1),
       walk_from_to_step(Xs, X1,X, R_2).
    

    IMO above path/4 is simpler and more approachable, particularly for novices. Would you concur?

提交回复
热议问题