170 lines
3.4 KiB
Prolog
170 lines
3.4 KiB
Prolog
/*************************************************************************
|
|
* *
|
|
* YAP Prolog *
|
|
* *
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
* *
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* File: arithpreds.yap *
|
|
* Last rev: *
|
|
* mods: *
|
|
* comments: arithmetical predicates *
|
|
* *
|
|
*************************************************************************/
|
|
|
|
%% @{
|
|
|
|
/**
|
|
@file arithpreds.yap
|
|
|
|
@addtogroup arithmetic_preds
|
|
|
|
|
|
*/
|
|
|
|
:- system_module(arithmetic_predicates, [
|
|
plus/3,
|
|
succ/2], []).
|
|
|
|
:- use_system_module( '$_errors', ['$do_error'/2]).
|
|
|
|
|
|
/** @pred succ(? _Int1_:int, ? _Int2_:int) is det
|
|
*
|
|
|
|
True if _Int2_ = _Int1_ + 1 and _Int1_ \>= 0. At least
|
|
one of the arguments must be instantiated to a natural number. This
|
|
predicate raises the domain-error not_less_than_zero if called with
|
|
a negative integer. E.g. `succ(X, 0)` fails silently and `succ(X, -1)`
|
|
raises a domain-error. The behaviour to deal with natural numbers
|
|
only was defined by Richard O'Keefe to support the common
|
|
count-down-to-zero in a natural way.
|
|
|
|
*/
|
|
|
|
% M and N nonnegative integers, N is the successor of M
|
|
succ(M,N) :-
|
|
(
|
|
var(M)
|
|
->
|
|
(
|
|
integer(N),
|
|
N > 0
|
|
->
|
|
'$plus'(N,-1,M)
|
|
;
|
|
'$succ_error'(M,N)
|
|
)
|
|
;
|
|
integer(M),
|
|
M >= 0
|
|
->
|
|
(
|
|
var(N)
|
|
->
|
|
'$plus'(M,1,N)
|
|
;
|
|
integer(N),
|
|
N > 0
|
|
->
|
|
'$plus'(M,1,N)
|
|
;
|
|
'$succ_error'(M,N)
|
|
)
|
|
;
|
|
'$succ_error'(M,N)
|
|
).
|
|
|
|
'$succ_error'(M,N) :-
|
|
var(M),
|
|
var(N), !,
|
|
'$do_error'(instantiation_error,succ(M,N)).
|
|
'$succ_error'(M,N) :-
|
|
nonvar(M),
|
|
\+ integer(M),
|
|
'$do_error'(type_error(integer, M),succ(M,N)).
|
|
'$succ_error'(M,N) :-
|
|
nonvar(M),
|
|
M < 0,
|
|
'$do_error'(domain_error(not_less_than_zero, M),succ(M,N)).
|
|
'$succ_error'(M,N) :-
|
|
nonvar(N),
|
|
\+ integer(N),
|
|
'$do_error'(type_error(integer, N),succ(M,N)).
|
|
'$succ_error'(M,N) :-
|
|
nonvar(N),
|
|
N < 0,
|
|
'$do_error'(domain_error(not_less_than_zero, N),succ(M,N)).
|
|
|
|
/** @pred plus(? _Int1_:int, ? _Int2_:int, ? _Int3_:int) is det
|
|
|
|
True if _Int3_ = _Int1_ + _Int2_. At least two of the
|
|
three arguments must be instantiated to integers.
|
|
|
|
@}
|
|
|
|
*/
|
|
|
|
plus(X, Y, Z) :-
|
|
(
|
|
var(X)
|
|
->
|
|
(
|
|
integer(Y), integer(Z)
|
|
->
|
|
'$minus'(Z,Y,X)
|
|
;
|
|
'$plus_error'(X,Y,Z)
|
|
)
|
|
;
|
|
integer(X)
|
|
->
|
|
(
|
|
var(Y)
|
|
->
|
|
(
|
|
integer(Z)
|
|
->
|
|
'$minus'(Z,X,Y)
|
|
;
|
|
'$plus_error'(X,Y,Z)
|
|
)
|
|
;
|
|
integer(Y)
|
|
->
|
|
(
|
|
integer(Z)
|
|
->
|
|
'$minus'(Z,Y,X)
|
|
;
|
|
var(Z)
|
|
->
|
|
'$plus'(X,Y,Z)
|
|
;
|
|
'$plus_error'(X,Y,Z)
|
|
)
|
|
;
|
|
'$plus_error'(X,Y,Z)
|
|
)
|
|
;
|
|
'$plus_error'(X,Y,Z)
|
|
).
|
|
|
|
'$plus_error'(X,Y,Z) :-
|
|
nonvar(X),
|
|
\+ integer(X),
|
|
'$do_error'(type_error(integer, X),plus(X,Y,Z)).
|
|
'$plus_error'(X,Y,Z) :-
|
|
nonvar(Y),
|
|
\+ integer(Y),
|
|
'$do_error'(type_error(integer, Y),plus(X,Y,Z)).
|
|
'$plus_error'(X,Y,Z) :-
|
|
nonvar(Z),
|
|
\+ integer(Z),
|
|
'$do_error'(type_error(integer, Z),plus(X,Y,Z)).
|
|
'$plus_error'(X,Y,Z) :-
|
|
'$do_error'(instantiation_error,plus(X,Y,Z)).
|