2015-03-26 3 views
4

Я пытаюсь создать правила Prolog для перечисления «бинарных деревьев» в форме списка в Prolog. Я новичок в Prolog.Перечисление двоичных деревьев в Prolog

Дерево с 0 узлов является пустым списком:

[] 

Дерево с 1 узла:

[[],[]] 

Дерево с 2 узлами имеет 2 возможности:

[[],[[],[]]] 

[[[],[]],[]] 

и так далее.

Вот мои правила:

bintree(0,[]). 
bintree(1,[[],[]]). 
bintree(N,[Lc,Rc]) :- 
    N > 1, 
    bintree(N1,Lc), 
    bintree(N2,Rc), 
    N1 >= 0, 
    N2 >= 0, 
    N3 is N1+N2+1, 
    N==N3. 

запросов на 0 и 1, очевидно, работают. Для N = 2 он печатает одну из возможностей, но дает ошибку после ввода точки с запятой, чтобы получить другую возможность. Запросы для N> 2 напрямую дают ошибку. Ошибка всегда одинакова:

ERROR: >/2: Arguments are not sufficiently instantiated 

Я прочитал об этой ошибке на некоторых веб-сайтах, но я не могу понять, что является причиной этой ошибки здесь.

Спасибо за вашу помощь заранее.

+1

просто удалить 'N> 1' – CapelliC

+0

Нет, что делает его идти в бесконечный цикл. – 1026501

+0

Чтобы использовать компаратор выражений в Prolog, все выражения должны быть полностью инстанцированы (значения известны). У вас есть ошибка, потому что 'N' не имеет значения, когда вы пытались« N> 1 ». Какой запрос вы пытаетесь удовлетворить? Это не совсем ясно в вашем вопросе. – lurker

ответ

3

Использование библиотеки CLPFD поможет дать чистое решение для создания размеров. Тогда вам не нужен шаткий (;)) integer/1 предикат, который может быть проблематичным:

:- use_module(library(clpfd)). 

bintree(0,[]). 
bintree(1,[[],[]]). 
bintree(N, [L, R]) :- 
    N #> 1, 
    N #= N1 + N2 + 1, 
    N1 #>= 0, N2 #>= 0, 
    bintree(N1, L), bintree(N2, R). 

Или проще (благодаря предложению @ повторить в):

bintree(0,[]). 
bintree(N, [L, R]) :- 
    N #> 0, 
    N #= N1 + N2 + 1, 
    N1 #>= 0, N2 #>= 0, 
    bintree(N1, L), bintree(N2, R). 

?- bintree(4, L). 
L = [[], [[], [[], [[], []]]]] ; 
L = [[], [[], [[[], []], []]]] ; 
L = [[], [[[], []], [[], []]]] ; 
L = [[], [[[], [[], []]], []]] ; 
L = [[], [[[[], []], []], []]] ; 
L = [[[], []], [[], [[], []]]] ; 
L = [[[], []], [[[], []], []]] ; 
L = [[[], [[], []]], [[], []]] ; 
L = [[[], [[], [[], []]]], []] ; 
L = [[[], [[[], []], []]], []] ; 
L = [[[[], []], []], [[], []]] ; 
L = [[[[], []], [[], []]], []] ; 
L = [[[[], [[], []]], []], []] ; 
L = [[[[[], []], []], []], []] ; 
false. 

?- 

CLPFD хороший, декларативный способ выражения числовых ограничений.

+0

Спасибо. Можно ли использовать только чистый пролог без этой библиотеки? – 1026501

+0

Эта библиотека * is * чистый. Попробуйте, например, GNU Prolog или B Prolog, где вам не нужно импортировать какую-либо библиотеку для использования такой элементарной функции, как ограничения конечного домена. Отличное решение, +1! – mat

0

Я знаю, что я разместил этот вопрос год назад, но мне удалось решить его позже, не используя библиотеки. Вот мое решение:

%binary tree generator 
bintree(0,[]). %0 nodes - empty list 
bintree(1,[[],[]]). %1 node - list containing 2 empty lists 
bintree(N,[Cl,Cr]) :- 
    N>=2, %check only if at least 2 nodes 
    between(0,N,Nl), %let Nl be in [0,N] 
    between(0,N,Nr), %similarly for Nr 
    Ns is Nl+Nr+1, %total no. of nodes should add up correctly 
    N==Ns, %so check for that 
    bintree(Nl,Cl), %children should also be valid binary trees 
    bintree(Nr,Cr). 
+1

Это очень плохой «генератор». Например, попробуйте самый общий запрос: '? - bintree (N, Tree). Он дает два решения, а затем говорит:« ОШИБКА: Аргументы недостаточно созданы ». Я настоятельно рекомендую использовать ограничения CLP (FD) ** ** для определения целых чисел, как в программе lurker. Это сделает ваше решение более общим, полезным во всех направлениях, как мы ожидаем от отношения. В вашем решении как формулировка («проверка»), так и поведение очень важны *, и ваш код работает только в очень ограниченном наборе режимов использования. В качестве другого примера попробуйте '? - bintree (N, [_, _]).' И сравните их! – mat

+1

@mat спасибо за информацию и советы. – 1026501

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