В my previous answer на недавний вопрос "Prolog binary search tree test - unwanted parents' parent node comparison", я предложил смешивание lazy_chain/2
, который использует prolog-coroutining ...При смешивании Пролог coroutining (заморозить/2, когда/2) и DCG
:- use_module (library(clpfd)). lazy_chain(Zs, R_2) :- ( var (R_2) ->instantiation_error (R_2) ; clpfd:chain_relation(R_2) ->freeze (Zs, lazy_chain_aux(Zs,R_2)) ; otherwise ->domain_error (chain_relation, R_2) ). lazy_chain_aux([], _). lazy_chain_aux([Z0|Zs], R_2) :- freeze(Zs, lazy_chain_aux_(Zs,R_2,Z0)). lazy_chain_aux_([], _, _). lazy_chain_aux_([Z1|Zs], R_2, Z0) :- call (R_2, Z0, Z1), freeze(Zs, lazy_chain_aux_(Zs,R_2,Z1)).
... вместе с dcgin_order//1
...
in_order(nil) --> []. in_order(node(X,L,R)) --> in_order(L), [X], in_order(R).
... как так:
?- lazy_chain(Zs, #<), phrase (in_order(node(1,nil,nil)), Zs). Zs = [1,23].
Есть ли простой способ «надавить» lazy_chain
на phrase/3
, чтобы его область действия ограничивалась частью последовательности, описанной in_order//1
?
Прямо сейчас, я получаю ...
?- lazy_chain(Zs, #<), phrase (in_order(node(1,nil,nil)), Zs0,Zs). Zs0 = [1|Zs], freeze(Zs, lazy_chain_aux(Zs,#<)).
... который (конечно же) может потерпеть неудачу при дальнейшей конкретизации Zs
:
?- lazy_chain(Zs, #<), phrase(in_order(node(1,nil,nil)), Zs0,Zs), Zs = [3,2,1]. false.
Как я могу работать вокруг этого и сдерживало lazy_chain
со стороны list-difference?
Почему 'в противном случае'? – false