2015-05-01 3 views
0

Рассмотрим, что n = s (s (... s (0) ...)) (просто n = s^n (0)). Как написать программу, вычисляющую деление двух целых чисел? Я имею в виду s^(n // m) (это определение деления). Есть идеи? Например, если бы мы имели вопрос:Деление двух целых чисел альтернативным способом

?-divide(s(s(s(s(0)))),s(0),D). 

я написал следующий код:

nat(0). 
nat(s(X)) :- nat(X). 
divide(0,_,D) :- D is 0. 
divide(s(X),s(Y),D) :- divide(X,Y,D). 
+1

Что вы имеете в виду именно деление? Вы можете использовать умножение, см. Выше тег! – false

+0

Я имею в виду, что я хочу выполнить разделение 4 и 1, чтобы дать мне 4. @false –

+0

Это не интересный случай. Что относительно 'divide (s (s (s (s (0)))), s (s (0)), D)'? – false

ответ

1

Ваш предикат divide/3 ошибочно предполагает, что имеет место равенство, если х и у являются числами: (х-1)/(г-1) = х/у
встречный пример: (16-1)/(4-1) = 5 отличается от 16/4 = 4

Кажется, вы пытаетесь строить свой предикат на хорошо ноу капельном предикате:

add(0,Y,Y). 
add(s(X),Y,s(Z)) :- add(X,Y,Z). 

но деление мультипликативная не аддитивная операция. Возможный способ решения вашей проблемы - думать о делении как повторном вычитании (поскольку умножение является повторным добавлением). Поскольку ваш предикат находится на натуральных числах, он должен реализовать интегральное деление, как вы писали в вопросе.

+0

Я пробовал что-то вроде этого, но я не принимаю правильные результаты @migfilg nat (0). nat (s (X)): - nat (X). разделите (0, _, 0). divide (X, Y, D): - X @ = Y, D1 - A. divide2 (X, Y, A, D1): - A * X @

+0

Вы не должны использовать 'is/2' для унификации: используйте' =/2' или просто замените переменные на термины, которые они должны унифицировать (например, 'D' на' 0' в вашем 2-м пункте). Вам нужно разрезать почти все статьи. Что вы подразумеваете под 'AX' в' divide2/4'? Это 'A' times' X'? В его нынешнем виде это свободная переменная. Ваш последний раздел 'divide/3' вызывает' divide2' с 's (X)' и 's (Y)', почему? Напишите в статье шаги деления * 16/4 * с использованием повторных вычитаний и попытайтесь увидеть, как программа может это сделать. – migfilg

0
s(0). 
s(X):- X. 

plus(0, Y, Y). 
plus(s(X), Y, s(Z)):- plus(X , Y , Z). 

minus(A, B, C) :- plus(C, B, A). 

divide(_, 0, 0). 
divide(0, _ , 0). 
divide(X, s(0), X). 
divide(A, B, s(N)) :- minus(A, B, R), divide(R, B, N). 

Пример:

| ?- divide(s(s(s(0))), s(0), N). 

N = s(s(s(0))) ? 

yes 
| ?- divide(s(s(s(s(0)))), s(s(0)), N). 

N = s(s(0)) ? 

yes 

Это решение работает, очевидно, только для совершенных подразделений, как 4/2 или 6/3 и т.д. Так как мы можем только представлять натуральные числа, используя цифры Пеано.

0

Старый пост, но у меня есть такой же assignment.So ответ:

%nat:Is X natural?,nat2:Is X,Y naturals? 
nat(0). 
nat(s(X)) :- nat(X). 
nat2(0,s(Y)) :- nat(Y). 
nat2(s(X),s(Y)) :- nat2(X,Y). 

%Summary of X+Y=Z 
sum(X,0,X) :- nat(X). 
sum(X,s(Y),s(Z)) :- sum(X,Y,Z). 

%Minus of X-Y=Z is same as Y+Z=X 
minus(X,Y,Z) :- sum(Y,Z,X). 

%Multiplication of X*Y,add X+0(Z) Y times(recursive) 
mult(X,0,0). 
mult(X,s(Y),D):-mult(X,Y,Z), sum(X,Z,D). 

%Divide,check special occasions,add to W the s(0)(1) recursive. 
divide(X,Y,D) :- div(X,Y,D,_). 
div(s(X),0,undefined,_). 
div(0,s(Y),0,_). 
div(0,0,undefined,_). 
div(X,Y,0,X) :- X \== 0,Y \== 0,nat2(X,Y). 
div(X,Y,D,L) :- X \== 0,Y \== 0,minus(X,Y,Z),div(Z,Y,W,L),sum(W,s(0),D). 
Смежные вопросы