# Arithmetic

**Author(s):**Daniel Cabeza, Manuel Hermenegildo.

Arithmetic is performed by built-in predicates which take as arguments arithmetic expressions (see `arithexpression/1`) and evaluate them. Terms representing arithmetic expressions can be created dynamically, but at the time of evaluation, each variable in an arithmetic expression must be bound to a non-variable expression (the term must be ground). For example, given the code in the first line a possible shell interaction follows:

evaluate(Expression, Answer) :- Answer is Expression. ?- _X=24*9, evaluate(_X+6, Ans). Ans = 222 ? yes

## Usage and interface

**Library usage:**

These predicates are builtin in Ciao, so nothing special has to be done to use them.**Exports:***Predicates:*`is/2`,`</2`,`=</2`,`>/2`,`>=/2`,`=:=/2`,`=\=/2`.*Regular Types:*`arithexpression/1`,`intexpression/1`.*Multifiles:*`$internal_error_where_term/4`.

**Imports:***System library modules:*`native_props`.*Packages:*`prelude`,`nonpure`,`condcomp`,`assertions`,`nortchecks`,`nativeprops`,`isomodes`.

## Documentation on exports

`Val is Exp`

The arithmetic expression Exp is evaluated and the result is unified with Val

**(Trust) Usage 1:**`A is B`

*The following properties should hold at call time:*

(term_typing:var/1)A is a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(term_typing:var/1)A is a free variable.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold upon exit:*

(basic_props:num/1)A is a number.

(arithmetic:arithexpression/1)B is an arithmetic expression.

(native_props:size/2)int(B) is the size of argument A, for any approximation.*The following properties hold globally:*

(native_props:not_fails/1)All the calls of the form A is B do not fail.

(basic_props:eval/1)A is B is evaluable at compile-time.

**(Trust) Usage 2:**`A is B`

*The following properties should hold at call time:*

(term_typing:var/1)A is a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(term_typing:var/1)A is a free variable.

(arithmetic:intexpression/1)B is an integer expression.*The following properties hold upon exit:*

(basic_props:int/1)A is an integer.

(arithmetic:intexpression/1)B is an integer expression.

(native_props:size/2)int(B) is the size of argument A, for any approximation.*The following properties hold globally:*

(native_props:not_fails/1)All the calls of the form A is B do not fail.

(basic_props:eval/1)A is B is evaluable at compile-time.

**(Trust) Usage 3:**`A is B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(basic_props:num/1)A is a number.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

**(Trust) Usage 4:**`A is B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(basic_props:int/1)A is an integer.

(arithmetic:intexpression/1)B is an integer expression.*The following properties hold globally:*

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

**General properties:**

**Test:**`X is Y`

is/2, sqrt test

*If the following properties hold at call time:*

(term_basic:= /2)term_basic:Y=sqrt(4)*then the following properties should hold upon exit:*

(term_basic:= /2)term_basic:X=2.0

**Trust:**`A is B`

*The following properties hold globally:*

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Val is Exp is side-effect free.

(basic_props:bind_ins/1)Val is Exp is binding insensitive.

(native_props:is_det/1)All calls of the form Val is Exp are deterministic.

(native_props:relations/2)Goal Val is Exp produces inf solutions.

`Exp1<Exp2`

The numeric value of Exp1 is less than the numeric value of Exp2 when both are evaluated as arithmetic expressions.

**(Trust) Usage:**`A<B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(arithmetic:arithexpression/1)A is an arithmetic expression.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(basic_props:eval/1)A<B is evaluable at compile-time.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Exp1<Exp2 is side-effect free.

(basic_props:bind_ins/1)Exp1<Exp2 is binding insensitive.

(native_props:is_det/1)All calls of the form Exp1<Exp2 are deterministic.

(native_props:relations/2)Goal Exp1<Exp2 produces inf solutions.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

`Exp1=<Exp2`

The numeric value of Exp1 is less than or equal to the numeric value of Exp2 when both are evaluated as arithmetic expressions.

**(Trust) Usage:**`A=<B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(arithmetic:arithexpression/1)A is an arithmetic expression.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(basic_props:eval/1)A=<B is evaluable at compile-time.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Exp1=<Exp2 is side-effect free.

(basic_props:bind_ins/1)Exp1=<Exp2 is binding insensitive.

(native_props:is_det/1)All calls of the form Exp1=<Exp2 are deterministic.

(native_props:relations/2)Goal Exp1=<Exp2 produces inf solutions.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

`Exp1>Exp2`

The numeric value of Exp1 is greater than the numeric value of Exp2 when both are evaluated as arithmetic expressions.

**(Trust) Usage:**`A>B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(arithmetic:arithexpression/1)A is an arithmetic expression.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(basic_props:eval/1)A>B is evaluable at compile-time.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Exp1>Exp2 is side-effect free.

(basic_props:bind_ins/1)Exp1>Exp2 is binding insensitive.

(native_props:is_det/1)All calls of the form Exp1>Exp2 are deterministic.

(native_props:relations/2)Goal Exp1>Exp2 produces inf solutions.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

`Exp1>=Exp2`

The numeric value of Exp1 is greater than or equal to the numeric value of Exp2 when both are evaluated as arithmetic expressions.

**(Trust) Usage:**`A>=B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(arithmetic:arithexpression/1)A is an arithmetic expression.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(basic_props:eval/1)A>=B is evaluable at compile-time.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Exp1>=Exp2 is side-effect free.

(basic_props:bind_ins/1)Exp1>=Exp2 is binding insensitive.

(native_props:is_det/1)All calls of the form Exp1>=Exp2 are deterministic.

(native_props:relations/2)Goal Exp1>=Exp2 produces inf solutions.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

`Exp1=:=Exp2`

The numeric values of Exp1 and Exp2 are equal when both are evaluated as arithmetic expressions.

**(Trust) Usage:**`A=:=B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(arithmetic:arithexpression/1)A is an arithmetic expression.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(basic_props:eval/1)A=:=B is evaluable at compile-time.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Exp1=:=Exp2 is side-effect free.

(basic_props:bind_ins/1)Exp1=:=Exp2 is binding insensitive.

(native_props:is_det/1)All calls of the form Exp1=:=Exp2 are deterministic.

(native_props:relations/2)Goal Exp1=:=Exp2 produces inf solutions.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

`Exp1=\=Exp2`

The numeric values of Exp1 and Exp2 are not equal when both are evaluated as arithmetic expressions.

**(Trust) Usage:**`A=\=B`

*The following properties should hold at call time:*

(term_typing:nonvar/1)A is currently a term which is not a free variable.

(term_typing:nonvar/1)B is currently a term which is not a free variable.

(arithmetic:arithexpression/1)A is an arithmetic expression.

(arithmetic:arithexpression/1)B is an arithmetic expression.*The following properties hold globally:*

(basic_props:eval/1)A=\=B is evaluable at compile-time.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that A is bound to, for any type of approximation.

(native_props:size_metric/3)int is the measure used to determine the size of the terms that B is bound to, for any type of approximation.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:native/1)This predicate is understood natively by CiaoPP.

(basic_props:sideff/2)Exp1=\=Exp2 is side-effect free.

(basic_props:bind_ins/1)Exp1=\=Exp2 is binding insensitive.

(native_props:is_det/1)All calls of the form Exp1=\=Exp2 are deterministic.

(native_props:relations/2)Goal Exp1=\=Exp2 produces inf solutions.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

`int/1`) or a float (

`flt/1`). The evaluable functors allowed in an arithmetic expression are listed below, together with an indication of the functions they represent. All evaluable functors defined in ISO-Prolog are implemented, as well as some other useful or traditional. Unless stated otherwise, an expression evaluates to a float if any of its arguments is a float, otherwise to an integer.

`- /1`: sign reversal. ISO`+ /1`: identity.`-- /1`: decrement by one.`++ /1`: increment by one.`+ /2`: addition. ISO`- /2`: subtraction. ISO`* /2`: multiplication. ISO`// /2`: integer division. Float arguments are truncated to integers, result always integer. ISO`/ /2`: division. Result always float. ISO`rem/2`: integer remainder. The result is always an integer, its sign is the sign of the first argument. ISO`mod/2`: modulo. The result is always a positive integer. ISO`abs/1`: absolute value. ISO`sign/1`: sign of. ISO`float_integer_part/1`: float integer part. Result always float. ISO`float_fractional_part/1`: float fractional part. Result always float. ISO`truncate/1`: The result is the integer equal to the integer part of the argument. ISO`integer/1`: same as`truncate/1`.`float/1`: conversion to float. ISO`floor/1`: largest integer not greater than. ISO`round/1`: integer nearest to. ISO`ceiling/1`: smallest integer not smaller than. ISO`** /2`: exponentiation. Result always float. ISO`>> /2`: integer bitwise right shift. ISO`<< /2`: integer bitwise left shift. ISO`/\ /2`: integer bitwise and. ISO`\/ /2`: integer bitwise or. ISO`\ /1`: integer bitwise complement. ISO`# /2`: integer bitwise exclusive or (xor).`exp/1`: exponential (*e*to the power of). Result always float. ISO`log/1`: natural logarithm (base*e*). Result always float. ISO`sqrt/1`: square root. Result always float. ISO`sin/1`: sine. Result always float. ISO`cos/1`: cosine. Result always float. ISO`atan/1`: arc tangent. Result always float. ISO`gcd/2`: Greatest common divisor. Arguments must evaluate to integers, result always integer.

In addition to these functors, a list of just a number evaluates to this number. Since a quoted string is just a list of integers, this allows a quoted character to be used in place of its ASCII code; e.g. `"A"` behaves within arithmetic expressions as the integer 65. Note that this is not ISO-compliant, and that can be achieved by using the ISO notation `0'A`.

Arithmetic expressions, as described above, are just data structures. If you want one evaluated you must pass it as an argument to one of the arithmetic predicates defined in this library.

**Usage:**`arithexpression(E)`

E is an arithmetic expression.

**General properties:**

**Trust:**

*The following properties hold globally:*

(basic_props:sideff/2)arithexpression(Arg1) is side-effect free.

**Trust:**

*If the following properties hold at call time:*

(term_typing:nonvar/1)Arg1 is currently a term which is not a free variable.*then the following properties hold globally:*

(native_props:is_det/1)All calls of the form arithexpression(Arg1) are deterministic.

(native_props:test_type/2)Indicates the type of test that a predicate performs. Required by the nonfailure analyisis.

**Usage:**`intexpression(E)`

E is an integer expression.

**General properties:**

**True:**

*The following properties hold globally:*

(basic_props:sideff/2)intexpression(Arg1) is side-effect free.

## Documentation on multifiles

*multifile*.

## Known bugs and planned improvements

- Run-time checks have been reported not to work with this code. That means that either the assertions here, or the code that implements the run-time checks are erroneous.
- We could improve the precision if we had (arithexpression,+intexpression) but we need a relational domain. -- EMM, JFMC