2013-02-22 3 views
1

Это мой код:Пролога - преобразование SUCC представления в десятичную

numeral(0). 
numeral(succ(X)) :- numeral(X). 

convertToD(A,0). 
convertToD(succ(S), Y) :- numeral(S), Y1 is Y-1, convertToD(S, Y1). 

Почему это дает мне такой вывод?

convertTo(succ(succ(0)), N). 
N = 0 ; 
ERROR: convertTo/2: Arguments are not sufficiently instantiated 
+0

Я отредактировал свой ответ, если это лучше сейчас. –

ответ

2

Ну, вы получаете больше, чем один ответ из-за этого:

convertToD(A,0). 

Что вы имеете в виду, чтобы иметь здесь convertToD(0, 0), потому что в противном случае вы говорите «convertToD правда между ничего и 0 ", когда вы имеете в виду" convertToD = 0 для 0. " Вот почему Prolog считает, что у вас много результатов.

Отдав ему некоторые мысли и заметив a question this question is a duplicate of, я вижу, что вы пытались выполнить со вторым предложением. То, что вы пытаетесь сделать, это эмулировать решение clpfd оттуда в обычном Прологе. С clpfd:

convertToD(succ(S), Y) :- numeral(S), Y0 #= Y-1, convertToD(S, Y0). 

Непосредственная копия, что в ванили Пролог получает нам свой код здесь, но то, что не происходит все волшебство clpfd приносит к столу. Без clpfd очень сложно создать предикат, который работает для любой комбинации экземпляров и никогда не будет петлями. Одна вещь, которая помогает, чтобы переместить арифметику последнего:

convertToD(succ(S), Y) :- numeral(S), convertToD(S, Y1), succ(Y1, Y). 

Это заставляет нас предиката со всеми желаемыми свойствами, за исключением того, что петли здесь:

?- convertToD(X, 3). 
X = s(s(s(0))) ; 
^CAction (h for help) ? abort 

Я перепутались с этим с when/2 и var/1/nonvar/1 и не смогли решить эту небольшую проблему.