问题
how can I do the following.
I needed to define the predicate shownumber (X,N)
, which is true when the symbol X corresponds to the natural number N. For example, shownumber(s(zero),1)
is true. Okay, now I've got a predicate:
shownumber (zero, 0).
shownumber (s (N), X): - shownumber (N, Y), X is Y + 1.
Now I need to use the shownumber (X, Y)
predicate to define:
1) times (X, Y, Z)
which is true if X * Y = Z.
2) quotient (X, Y, Q)
which is true if X / Y = Q (in natural number arithmetic)
3) remainder (X, Y, R)
which is true if X divided by Y gives the remainder R.
The quotient (X, Y, Q)
and the remainder (X, Y, R)
must be defined for Y = zero.
How can I do that? Could you help me with this one?
回答1:
This code may help:
peano_redux.pl
It took me a long time to finish it and it still has bad corners. I tried to stay "close the Peano Axioms" but some shortcuts had to be taken - this is programming, not general theorem proving.
I also used the old-school & messy Peano notation s(s(s(s(z)))
instead the far cleaner and appropriate list-based notation: [s,s,s,s]
.
It would be extremely cool to be able to set up a constraint between two variables PN and NN, so that if NN is bound to a natural number, PN is automatically bound to the coressponding Peano Number, and vice-versa. That can probably be done with some effort using attributed variables, but I haven't thought about that.
Computation is expectedly very slow. It would be interesting to try tabling on the padd/pmult predicates.
The bidirectional transformation between Peano Numbers and Naturals exists in two version: One using CLP(FD) and one using basic Prolog. Comment out the version you don't want.
This is overall an interesting (but time-consuming exercise). It gives a lot of practice in debugging and thinking about control flow, and forces you to watch out for undesired unification, non-termination, early termination and special cases of bound/fresh variable configurations.
It also highlights the absolute need to write unit tests as you program, to give you a scaffolding for progress,
Seemingly innocuous rearrangements of code may cause a previously working Prolog program to fail or loop indefinitely for hard-to-explain reasons. Having test cases to get back on track avoids meaninglessly burning time on "fixing things until they work" and possibly "running tests by hand".
Unit tests are also of great use for communicating your problem's specification Programming courses should really orbit around that concept first - this isn't the 80s anymore.
Run all test cases by issuing command rtall
for great success:
?- 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.
Some references vaguely consulted:
- Natural number
- Peano axioms
- Proofs involving the addition of natural numbers
来源:https://stackoverflow.com/questions/62132704/times-quotient-and-remainder-predicates-in-prolog