2016-05-15 3 views
2

Рассмотрим следующую простую программу:Переключение между ДИЗЪЮНКЦИИ в Прологе

h(n0). 
h(p(A,N)) :- (A=a, h(N)) ; (A=b , h(N)). 

Запрос:

1 ?- h(p(A,N)). 
A = a, 
N = n0 ; 
A = a, 
N = p(a, n0) ; 
A = a, 
N = p(a, p(a, n0)) ; 
A = a, 
N = p(a, p(a, p(a, n0))) ; 
A = a, 
N = p(a, p(a, p(a, p(a, n0)))) ; 

...

С первого расчленено [(A=a, h(N))] производит бесконечное количество ответов, что не могут отображать ответы, полученные второй дизъюнкцией [(A=b , h(N))].

Возникает вопрос:

Можно ли изменить код так, что на запрос, он чередуется между решениями от первого расчленено и второго?

ответ

4

Чтобы получить справедливый список результатов h/1, вы можете использовать вспомогательный предикат, например h2/2, который состоит из двух целей: 1) пары предикатов/1, которые описывают только структуру вашего решения без конкретных значений:

pairs(n0). 
pairs(p(A,N)) :- 
    pairs(N). 

и дает следующие ответы:

?- pairs(X). 
X = n0 ? ; 
X = p(_A,n0) ? ; 
X = p(_A,p(_B,n0)) ? ; 
X = p(_A,p(_B,p(_C,n0))) ? 
... 

2) Ваш предикат ч/1 в качестве второй цели, которая описывает то, что переменные _A, _B, _C,... на самом деле:

h2(X) :- 
    pairs(X), 
    h(X). 

Если вы запрашиваете этот предикат вы получите желаемые результаты:

?- h2(X). 
X = n0 ? ; 
X = p(a,n0) ? ; 
X = p(b,n0) ? ; 
X = p(a,p(a,n0)) ? ; 
X = p(a,p(b,n0)) ? ; 
X = p(b,p(a,n0)) ? ; 
X = p(b,p(b,n0)) ? ; 
X = p(a,p(a,p(a,n0))) ? ; 
... 

Примечание, как первые пары цель/2 производит ваша вложенная пара-структура одной пары одновременно. Затем вторая цель, ваш исходный предикат, создает все возможные комбинации a и b для этой самой пары. Тогда h/2 возвращается к следующей паре, создаваемой парами/2. И так далее.

Смежные вопросы