(Let me sneak that in within the wave of midterm questions.)
A common definition for the sum of two natural numbers is nat_nat_sum/3
:
na
The obvious trick is to flip the arguments:
sum(0,N,N).
sum(N,0,N).
sum(s(A),B,s(C)):- sum(B,A,C) ; sum(A,B,C).
Ok, seems its over. The solution I was thinking of was:
nat_nat_sum2(0, N,N).
nat_nat_sum2(s(N), 0, s(N)).
nat_nat_sum2(s(N), s(M), s(s(O))) :-
nat_nat_sum2(N, M, O).
But as I realize, that's just the same as @mat's one which is almost the same as @WillNess'es.
Is this really the better nat_nat_sum/3
? The original's runtime is independent of B
(if we ignore one (1) occurs check for the moment).
There is another downside of my solution compared to @mat's solution which naturally extends to nat_nat_nat_sum/3
nat_nat_nat_sum(0, B, C, D) :-
nat_nat_sum(B, C, D).
nat_nat_nat_sum(s(A), B, C, s(D)) :-
nat_nat_nat_sum2(B, C, A, D).
Which gives
nat_nat_nat_sum(A,B,C,D)terminates_if b(A),b(B);b(A),b(C);b(B),b(C);b(D).
(provable in the unfolded version with cTI)
nat_nat_sum(0, B, B).
nat_nat_sum(s(A), B, s(C)) :-
nat_nat_sum(B, A, C).
?
Take the following two definitions:
Definition 1:
add(n,X,X).
add(s(X),Y,s(Z)) :- add(X,Y,Z).
Definition 2:
add(n,X,X).
add(s(X),Y,Z) :- add(X,s(Y),Z).
Definition 1 terminates for pattern add(-,-,+), whereas definition 2 does not terminate for pattern add(-,-,+). Look see:
Definition 1:
?- add(X,Y,s(s(s(n)))).
X = n,
Y = s(s(s(n))) ;
X = s(n),
Y = s(s(n)) ;
X = s(s(n)),
Y = s(n) ;
X = s(s(s(n))),
Y = n
?-
Definition 2:
?- add(X,Y,s(s(s(n)))).
X = n,
Y = s(s(s(n))) ;
X = s(n),
Y = s(s(n)) ;
X = s(s(n)),
Y = s(n) ;
X = s(s(s(n))),
Y = n ;
Error: Execution aborted since memory threshold exceeded.
add/3
add/3
?-
So I guess definition 1 is better than definition 2.
Bye