Re: [swipl] Use arithmetic_function/1 inside a module

Wouter Beek <[email protected]> Sat, 5 Apr 2014 09:24:14 +0100
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <CAE1un7MdKXPxr+g_DaYSX9pPos6ovqyPV6At=GiMCbpD7JNinA@mail.gmail.com>
Hi Jochem,

Arithmetic functions do work in SWI-Prolog. I'll give an example
below. It is however not possible to export/import them as one would
with ordinary predicates or with operators.

This means that every use of an arithmetic function outside the module
that defines it in must be prefixed by that defining module's name. As
you can see in the example below this does not look very nice (I've
added some spaces to align the expressions a bit more), but it does
work.

Example of using artihmetic functions defined in module
`xsd_functions` within another module:
~~~{.pl}
  % Days.
  xsd_functions:(NumberOfDays     is NumberOfSeconds1 xsd_div 86400),

  % Hours.
  % h is (ss mod 86400) div 3600.
  xsd_functions:(X                is NumberOfSeconds1 xsd_mod 86400),
  xsd_functions:(NumberOfHours    is X                xsd_div 3600 ),

  % Minutes.
  % m is (ss mod 3600) div 60.
  xsd_functions:(Y                is NumberOfSeconds1 xsd_mod 3600 ),
  xsd_functions:(NumberOfMinutes  is Y                xsd_div 60   ),

  % Seconds.
  % s is ss mod 60.
  xsd_functions:(NumberOfSeconds2 is NumberOfSeconds1 xsd_mod 60   )
~~~

Example of a module defining arithmetic functions. Notice that the
operators can be exported in the normal way.
~~~{.pl}
:- module(
  xsd_functions,
  [
    op(400, yfx, xsd_div),
    op(400, yfx, xsd_mod)
  ]
).

/** <module> XSD functions

Functions used by XML Schema 2: Datatatypes

@see http://www.w3.org/TR/xmlschema11-2/#sec-numericalValues
*/

:- use_module(library(arithmetic)).

:- op(400, yfx, xsd_div).
:- arithmetic_function(xsd_div/2).

:- op(400, yfx, xsd_mod).
:- arithmetic_function(xsd_mod/2).

xsd_div(X, Y, Z):-
  Z is floor(X / Y).


xsd_mod(X, Y, Z):-
  Z is X - Y * (X xsd_div Y).
~~~

Thanks to Jan for helping me understand how this works in the first place!

Cheers!,
Wouter.