В моем предыдущем ответе на недавний вопрос "Тест двоичного дерева поиска Prolog — сравнение родительских узлов нежелательных родителей", я предложил смешать lazy_chain/2
, который использует prolog-coroutining ...
:- 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)).
... вместе с dcg in_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
частью список различий?