This is an experiment to see what the differences are
between defining NonNegativeInteger? (NNI) as a SubDomain?
of Integer, versus defining it simply based on Integer
itself.
The surprizing conclusion is that the latter definition of
NNI produces nearly identical code as the first definition
except for the now required definitions of coerce:%->Integer
and convert:Integer->%
, but without the extra CategoryFrame
datastructure. This would seem to confirm that the SubDomain?
construct does not have any great advantages over the more
direct definition.
First, NNI the usual way:
spad
)abbrev domain NNI NonNegativeInteger
++ Description: \spadtype{NonNegativeInteger} provides functions for non
++ negative integers.
NonNegativeInteger: Join(OrderedAbelianMonoidSup,Monoid) with
_quo : (%,%) -> %
++ a quo b returns the quotient of \spad{a} and b, forgetting
++ the remainder.
_rem : (%,%) -> %
++ a rem b returns the remainder of \spad{a} and b.
gcd : (%,%) -> %
++ gcd(a,b) computes the greatest common divisor of two
++ non negative integers \spad{a} and b.
divide: (%,%) -> Record(quotient:%,remainder:%)
++ divide(a,b) returns a record containing both
++ remainder and quotient.
_exquo: (%,%) -> Union(%,"failed")
++ exquo(a,b) returns the quotient of \spad{a} and b, or "failed"
++ if b is zero or \spad{a} rem b is zero.
shift: (%, Integer) -> %
++ shift(a,i) shift \spad{a} by i bits.
random : % -> %
++ random(n) returns a random integer from 0 to \spad{n-1}.
commutative("*")
++ commutative("*") means multiplication is commutative : \spad{x*y = y*x}.
== SubDomain(Integer,#1 >= 0) add
x,y:%
sup(x,y) == MAX(x,y)$Lisp
shift(x:%, n:Integer):% == ASH(x,n)$Lisp
subtractIfCan(x, y) ==
c:Integer := (x pretend Integer) - (y pretend Integer)
c < 0 => "failed"
c pretend %
spad
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/3031109299430777991-25px001.spad using
old system compiler.
NNI abbreviates domain NonNegativeInteger
------------------------------------------------------------------------
initializing NRLIB NNI for NonNegativeInteger
compiling into NRLIB NNI
compiling exported sup : ($,$) -> $
NNI;sup;3$;1 is replaced by MAX
;;; *** |NNI;sup;3$;1| REDEFINED
Time: 0.06 SEC.
compiling exported shift : ($,Integer) -> $
NNI;shift;$I$;2 is replaced by ASH
;;; *** |NNI;shift;$I$;2| REDEFINED
Time: 0 SEC.
compiling exported subtractIfCan : ($,$) -> Union($,failed)
;;; *** |NNI;subtractIfCan;2$U;3| REDEFINED
Time: 0 SEC.
(time taken in buildFunctor: 0)
;;; *** |NonNegativeInteger| REDEFINED
;;; *** |NonNegativeInteger| REDEFINED
Time: 0 SEC.
Cumulative Statistics for Constructor NonNegativeInteger
Time: 0.06 seconds
--------------non extending category----------------------
.. NonNegativeInteger of cat
(|Join| (|OrderedAbelianMonoidSup|) (|Monoid|)
(CATEGORY |domain| (SIGNATURE |quo| ($ $ $))
(SIGNATURE |rem| ($ $ $)) (SIGNATURE |gcd| ($ $ $))
(SIGNATURE |divide|
((|Record| (|:| |quotient| $) (|:| |remainder| $)) $ $))
(SIGNATURE |exquo| ((|Union| $ "failed") $ $))
(SIGNATURE |shift| ($ $ (|Integer|)))
(SIGNATURE |random| ($ $)) (ATTRIBUTE (|commutative| "*")))) has no
(|IntegerNumberSystem|) finalizing NRLIB NNI
Processing NonNegativeInteger for Browser database:
--------(quo (% % %))---------
--------(rem (% % %))---------
--------(gcd (% % %))---------
--------(divide ((Record (: quotient %) (: remainder %)) % %))---------
--------(exquo ((Union % failed) % %))---------
--------(shift (% % (Integer)))---------
--------(random (% %))---------
--------(commutative (attribute *))---------
--------constructor---------
------------------------------------------------------------------------
NonNegativeInteger is now explicitly exposed in frame initial
NonNegativeInteger will be automatically loaded when needed from
/var/zope2/var/LatexWiki/NNI.NRLIB/code
Type: NonNegativeInteger
?
Type: NonNegativeInteger
?
axiom
z1:NNI:=(x1 + y1)$NNI
Type: NonNegativeInteger
?
Type: Integer
axiom
subtractIfCan(y1,x1)$NNI
Type: Union(NonNegativeInteger
?,...)
axiom
Compiling function G1451 with type Integer -> Boolean
Type: NonNegativeInteger
?
axiom
((-1)::INT)::NNI
Cannot convert from type Integer to NonNegativeInteger for value
- 1
Now write NNI without using SubDomain?:
spad
)abbrev domain NNI2 NonNegativeInteger2
++ Description: \spadtype{NonNegativeInteger} provides functions for non
++ negative integers.
NonNegativeInteger2: Join(OrderedAbelianMonoidSup,Monoid,CoercibleTo(Integer)) with
_quo : (%,%) -> %
++ a quo b returns the quotient of \spad{a} and b, forgetting
++ the remainder.
_rem : (%,%) -> %
++ a rem b returns the remainder of \spad{a} and b.
gcd : (%,%) -> %
++ gcd(a,b) computes the greatest common divisor of two
++ non negative integers \spad{a} and b.
divide: (%,%) -> Record(quotient:%,remainder:%)
++ divide(a,b) returns a record containing both
++ remainder and quotient.
_exquo: (%,%) -> Union(%,"failed")
++ exquo(a,b) returns the quotient of \spad{a} and b, or "failed"
++ if b is zero or \spad{a} rem b is zero.
shift: (%, Integer) -> %
++ shift(a,i) shift \spad{a} by i bits.
random : % -> %
++ random(n) returns a random integer from 0 to \spad{n-1}.
commutative("*")
++ commutative("*") means multiplication is commutative : \spad{x*y = y*x}.
convert: Integer -> %
== Integer add
sup(x:%,y:%) == MAX(x,y)$Lisp
shift(x:%, n:Integer):% == ASH(x,n)$Lisp
subtractIfCan(x, y) ==
c:Integer := (x pretend Integer) - (y pretend Integer)
c < 0 => "failed"
c pretend %
coerce(x:%):Integer == x pretend Integer
convert(x:Integer):% ==
x >= 0 => x pretend %
error(["Cannot convert from type Integer to NonNegativeInteger for value",
string(x)$String])
spad
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/2236461010280263224-25px003.spad using
old system compiler.
NNI2 abbreviates domain NonNegativeInteger2
------------------------------------------------------------------------
initializing NRLIB NNI2 for NonNegativeInteger2
compiling into NRLIB NNI2
compiling exported sup : ($,$) -> $
NNI2;sup;3$;1 is replaced by MAX
Time: 0 SEC.
compiling exported shift : ($,Integer) -> $
NNI2;shift;$I$;2 is replaced by ASH
Time: 0.07 SEC.
compiling exported subtractIfCan : ($,$) -> Union($,failed)
Time: 0 SEC.
compiling exported coerce : $ -> Integer
NNI2;coerce;$I;4 is replaced by x
Time: 0 SEC.
compiling exported convert : Integer -> $
Time: 0.01 SEC.
(time taken in buildFunctor: 0)
;;; *** |NonNegativeInteger2| REDEFINED
;;; *** |NonNegativeInteger2| REDEFINED
Time: 0 SEC.
Cumulative Statistics for Constructor NonNegativeInteger2
Time: 0.08 seconds
--------------non extending category----------------------
.. NonNegativeInteger2 of cat
(|Join| (|OrderedAbelianMonoidSup|) (|Monoid|)
(|CoercibleTo| (|Integer|))
(CATEGORY |domain| (SIGNATURE |quo| ($ $ $))
(SIGNATURE |rem| ($ $ $)) (SIGNATURE |gcd| ($ $ $))
(SIGNATURE |divide|
((|Record| (|:| |quotient| $) (|:| |remainder| $)) $ $))
(SIGNATURE |exquo| ((|Union| $ "failed") $ $))
(SIGNATURE |shift| ($ $ (|Integer|)))
(SIGNATURE |random| ($ $)) (ATTRIBUTE (|commutative| "*"))
(SIGNATURE |convert| ($ (|Integer|))))) has no
(|IntegerNumberSystem|) finalizing NRLIB NNI2
Processing NonNegativeInteger2 for Browser database:
--------(quo (% % %))---------
--------(rem (% % %))---------
--------(gcd (% % %))---------
--------(divide ((Record (: quotient %) (: remainder %)) % %))---------
--------(exquo ((Union % failed) % %))---------
--------(shift (% % (Integer)))---------
--------(random (% %))---------
--------(commutative (attribute *))---------
--->-->NonNegativeInteger2((convert (% (Integer)))): Not documented!!!!
--------constructor---------
------------------------------------------------------------------------
NonNegativeInteger2 is now explicitly exposed in frame initial
NonNegativeInteger2 will be automatically loaded when needed from
/var/zope2/var/LatexWiki/NNI2.NRLIB/code
The behaviour is identical to NNI
Type: NonNegativeInteger2
?
Type: NonNegativeInteger2
?
axiom
z2:NNI2:=(x2+y2)$NNI2
Type: NonNegativeInteger2
?
Type: Integer
axiom
subtractIfCan(y2,x2)$NNI2
Type: Union(NonNegativeInteger2
?,...)
Type: NonNegativeInteger2
?
axiom
((-1)::INT)::NNI2
>> Error detected within library code:
Cannot convert from type Integer to NonNegativeInteger for value
"-1"
The generated lisp code for NNI is:
axiom
)lisp (system "pretty < /var/zope/var/LatexWiki/NNI.NRLIB/NNI.lsp | tee /tmp/NNI.lsp")
Value = 0
Compared NNI (-) to NNI2 (+):
axiom
)lisp (system "pretty < /var/zope/var/LatexWiki/NNI2.NRLIB/NNI2.lsp | diff -au /tmp/NNI.lsp -")
Value = 0
SubDomain? written in Aldor:
aldor
#include "axiom.as"
SubSetDom(X:Type, E:X->Boolean):
with {
convert: X -> %;
coerce: % -> X;
} == X add {
coerce(x:%):X == x pretend X;
convert(x:X):% == {
E(x) => x pretend %;
error("Cannot convert");
}
}
aldor
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/3345325303575885968-25px007.as using
AXIOM-XL compiler and options
-O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom -Y $AXIOM/algebra
Use the system command )set compiler args to change these
options.
#1 (Warning) Deprecated message prefix: use `ALDOR_' instead of `_AXL'
Compiling Lisp source code from file
./3345325303575885968-25px007.lsp
Issuing )library command for 3345325303575885968-25px007
Reading /var/zope2/var/LatexWiki/3345325303575885968-25px007.asy
SubSetDom is now explicitly exposed in frame initial
SubSetDom will be automatically loaded when needed from
/var/zope2/var/LatexWiki/3345325303575885968-25px007
axiom
)sh SubSetDom
SubSetDom(X: Type,E: (X -> Boolean)) is a domain constructor
Abbreviation for SubSetDom is SUBSETD
This constructor is exposed in this frame.
Issue )edit 3345325303575885968-25px007.as to see algebra source code for SUBSETD
------------------------------- Operations --------------------------------
coerce : % -> X convert : X -> %
)set functions compile on
Test the new subdomain.
Type: Void
Type: Void
axiom
Compiling function E with type Integer -> Boolean
Type: Boolean
axiom
)sh SubSetDom(Integer, E)
>> System error:
The function MAP is undefined.
Now define NNI the using the new SubSetDom?:
For some unknown reason this fails:
aldor
#include "axiom.as"
#pile
NNI3: Join(OrderedAbelianMonoidSup,Monoid, CoercibleTo(Integer))
with
convert: Integer -> %
== SubSetDom(Integer, (z:Integer):Boolean +-> (z >= 0)) add
sup(x:%,y:%):% ==
x>y => x
y
subtractIfCan(x:%, y:%):Union(ok:%,failed:'failed') ==
c:Integer == (x pretend Integer) - (y pretend Integer)
c < 0 => return [failed]
[c pretend %]
aldor
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/3694095911335604383-25px010.as using
AXIOM-XL compiler and options
-O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom -Y $AXIOM/algebra
Use the system command )set compiler args to change these
options.
#1 (Warning) Deprecated message prefix: use `ALDOR_' instead of `_AXL'
"/var/zope2/var/LatexWiki/3694095911335604383-25px010.as", line 6:
== SubSetDom(Integer, (z:Integer):Boolean +-> (z >= 0)) add
......^....................................................^
[L6 C7] #2 (Error) There are no suitable meanings for the operator `SubSetDom'.
[L6 C60] #3 (Error) The domain is missing some exports.
Missing =: (%, %) -> Boolean
Missing coerce: % -> OutputForm
Missing <: (%, %) -> Boolean
Missing +: (%, %) -> %
Missing 0: %
Missing subtractIfCan: (%, %) -> Union(value1: %, failed: Enumeration(failed: Type))
Missing *: (%, %) -> %
Missing 1: %
Missing coerce: % -> Integer
Missing convert: Integer -> %
The )library system command was not called after compilation.
But this works:
aldor
#include "axiom.as"
#pile
NNI4: Join(OrderedAbelianMonoidSup,Monoid, CoercibleTo(Integer))
with
convert: Integer -> %
-- == SubSetDom(Integer, (z:Integer):Boolean +-> (z >= 0)) add
== Integer add
coerce(x:%):Integer == x pretend Integer;
convert(x:Integer):% ==
x>=0 => return x pretend %
error "Cannot convert"
sup(x:%,y:%):% ==
x>y => x
y
subtractIfCan(x:%, y:%):Union(ok:%,failed:'failed') ==
c:Integer == (x pretend Integer) - (y pretend Integer)
c < 0 => return [failed]
[c pretend %]
aldor
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/84397582143168417-25px011.as using
AXIOM-XL compiler and options
-O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom -Y $AXIOM/algebra
Use the system command )set compiler args to change these
options.
#1 (Warning) Deprecated message prefix: use `ALDOR_' instead of `_AXL'
Compiling Lisp source code from file ./84397582143168417-25px011.lsp
Issuing )library command for 84397582143168417-25px011
Reading /var/zope2/var/LatexWiki/84397582143168417-25px011.asy
NNI4 is now explicitly exposed in frame initial
NNI4 will be automatically loaded when needed from
/var/zope2/var/LatexWiki/84397582143168417-25px011
axiom
)set message bottomup on
x4:NNI4:=1$NNI4
Type: NNI4
axiom
y4:NNI4:=2$NNI4
Function Selection for *
Arguments: (PI,NNI4)
Target type: NNI4
-> no appropriate * found in PositiveInteger
-> no appropriate * found in Integer
[1] signature: (PI,NNI4) -> NNI4
implemented: slot $(PositiveInteger)$ from NNI4
Type: NNI4
axiom
z4:NNI4:=(x4 + y4)$NNI4
Function Selection for +
Arguments: (NNI4,NNI4)
Target type: NNI4
From: NNI4
[1] signature: (NNI4,NNI4) -> NNI4
implemented: slot $$$ from NNI4
Type: NNI4
Type: Integer
axiom
subtractIfCan(y4,x4)$NNI4
Function Selection for subtractIfCan
Arguments: (NNI4,NNI4)
Target type: Union(value1: NNI4,failed: Enumeration failed)
From: NNI4
[1] signature: (NNI4,NNI4) -> Union(value1: NNI4,failed: Enumeration failed)
implemented: slot (Union (: value1 $) (: failed (Enumeration failed)))$$ from NNI4
Type: Union(value1: NNI4,...)
Type: NNI4
axiom
((-1)::INT)::NNI4
>> System error:
Cannot convert
aldor
#pile
#include "axiom"
--)abbrev package TEST test
NNI ==> NonNegativeInteger2
test(): with
main: ()-> NNI
== add
n1:NNI:=1
n2:NNI:=2
main():NNI == n1-n2
aldor
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/5451681632571730514-25px013.as using
AXIOM-XL compiler and options
-O -Fasy -Fao -Flsp -laxiom -Mno-AXL_W_WillObsolete -DAxiom -Y $AXIOM/algebra
Use the system command )set compiler args to change these
options.
#1 (Warning) Deprecated message prefix: use `ALDOR_' instead of `_AXL'
"/var/zope2/var/LatexWiki/5451681632571730514-25px013.as", line 4:
NNI ==> NonNegativeInteger2
........^
[L4 C9] #2 (Error) (After Macro Expansion) No meaning for identifier `NonNegativeInteger2'.
Expanded expression was: NonNegativeInteger2
"/var/zope2/var/LatexWiki/5451681632571730514-25px013.as", line 8:
n1:NNI:=1
............^
[L8 C13] #7 (Error) No meaning for identifier `1'.
"/var/zope2/var/LatexWiki/5451681632571730514-25px013.as", line 9:
n2:NNI:=2
............^
[L9 C13] #8 (Error) There is no suitable interpretation for the expression 2
The context requires an expression of type NonNegativeInteger2.
The possible types of the right hand side (`2') are:
-- Literal
"/var/zope2/var/LatexWiki/5451681632571730514-25px013.as", line 10:
main():NNI == n1-n2
....................^
[L10 C21] #9 (Error) There are no suitable meanings for the operator `-'.
The )library system command was not called after compilation.
axiom
)show TEST
The )show system command is used to display information about types
or partial types. For example, )show Integer will show
information about Integer .
TEST is not the name of a known type constructor. If you want to
see information about any operations named TEST , issue
)display operations TEST
axiom
main()
Function Selection for main
Arguments: ()
-> no function main found for arguments ()
There are no library operations named main
Use HyperDoc Browse or issue
)what op main
to learn if there is any operation containing " main " in its
name.
Cannot find a no-argument definition or library operation named main
.