Предикаты Times, Quotient и Remainder в Прологе
Как я могу сделать следующее.
Мне нужно было определить предикат shownumber (X,N)
, что верно, когда символ X соответствует натуральному числу N. Например, shownumber(s(zero),1)
правда. Хорошо, теперь у меня есть предикат:
shownumber(zero, 0).
shownumber (s (N), X): - shownumber (N, Y), X is Y + 1.
Теперь мне нужно использовать shownumber (X, Y)
предикат для определения:
1) times (X, Y, Z)
что верно, если X * Y = Z.
2) quotient (X, Y, Q)
что верно, если X / Y = Q (в арифметике натуральных чисел)
3) remainder (X, Y, R)
что верно, если X, деленное на Y, дает остаток R.
В quotient (X, Y, Q)
и remainder (X, Y, R)
должен быть определен для Y = ноль.
Как я могу это сделать? Не могли бы вы мне помочь с этим?
1 ответ
Этот код может помочь:
Мне потребовалось много времени, чтобы закончить его, и у него все еще есть плохие повороты. Я попытался остаться "закрыть Пеано Аксиомы", но некоторые ярлыки должны были быть приняты - это является программирование, а не общая теоремы доказывания.
Я также использовал олдскульную и беспорядочную нотацию Пеано. s(s(s(s(z)))
вместо этого гораздо более чистая и подходящая нотация на основе списка: [s,s,s,s]
.
Было бы очень здорово иметь возможность установить ограничение между двумя переменными PN и NN, чтобы, если NN привязано к натуральному числу, PN автоматически привязывалось к основному числу Пеано, и наоборот. Вероятно, это можно сделать с некоторыми усилиями, используя переменные с атрибутами, но я об этом не думал.
Вычисления ожидаются очень медленно. Было бы интересно попробовать внести в таблицу предикаты padd/pmult.
Двунаправленное преобразование между числами Пеано и Naturals существует в двух версиях: одна с использованием CLP(FD), а другая с использованием базового языка Prolog. Закомментируйте версию, которую вы не хотите.
В целом это интересное (но трудоемкое) упражнение. Это дает много практики в отладке и обдумывании потока управления и заставляет вас следить за нежелательной унификацией, незавершением, ранним завершением и особыми случаями связанных / свежих конфигураций переменных.
Он также подчеркивает абсолютную необходимость писать модульные тесты по мере программирования, чтобы дать вам основу для прогресса.
На первый взгляд безобидные изменения кода могут привести к сбою ранее работающей программы Prolog или к бесконечному циклу по труднообъяснимым причинам. Наличие тестовых примеров для возвращения в нужное русло позволяет избежать бессмысленной траты времени на "исправление вещей до тех пор, пока они не заработают" и, возможно, "запуск тестов вручную".
Модульные тесты также очень полезны для передачи спецификации вашей проблемы. Курсы программирования должны сначала вращаться вокруг этой концепции - это уже не 80-е.
Запустите все тестовые примеры, введя команду rtall
для большого успеха:
?- rt_all.
Correct to: "rtall"? yes
% PL-Unit: pm ................... done
% All 19 tests passed
% PL-Unit: pnat ......... done
% All 9 tests passed
% PL-Unit: pequal .... done
% All 4 tests passed
% PL-Unit: padd ................................. done
% All 33 tests passed
% PL-Unit: pless ................. done
% All 17 tests passed
% PL-Unit: pmult .......................
% 1,649 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 8951351 Lips)
.
% 3,097 inferences, 0.000 CPU in 0.000 seconds (98% CPU, 10109979 Lips)
.
% 5,813 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 11183341 Lips)
.
% 2,598 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 9577492 Lips)
.
% 768 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 8491724 Lips)
.
% 1,847 inferences, 0.000 CPU in 0.000 seconds (96% CPU, 9731501 Lips)
.
% 8,453,914 inferences, 0.668 CPU in 0.674 seconds (99% CPU, 12651865 Lips)
.
% 4,273 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 10987655 Lips)
.
% 8,389 inferences, 0.001 CPU in 0.001 seconds (99% CPU, 11702424 Lips)
.
% 12,506 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 11900038 Lips)
.
% 45,453 inferences, 0.004 CPU in 0.004 seconds (100% CPU, 11844692 Lips)
. done
% All 34 tests passed
% PL-Unit: pqr ................Found: 16*13+8=216
Found: 37*12+8=452
Found: 7*53+1=372
Found: 28*7+13=209
Found: 33*14+6=468
Found: 23*5+19=134
Found: 21*3+3=66
Found: 31*8+1=249
Found: 14*20+9=289
Found: 5*2+4=14
Found: 4*9+0=36
Found: 30*3+6=96
Found: 40*11+16=456
Found: 11*4+8=52
Found: 10*12+3=123
Found: 18*20+0=360
Found: 5*61+2=307
Found: 46*2+0=92
Found: 1*215+0=215
Found: 47*7+30=359
. done
% All 17 tests passed
true.
Некоторые ссылки смутно консультировались: