Fortunately, Axiom is rather easy to debug. Most of the source is very transparent, so once you have localized the bug there are mostly design issues to overcome. However, to find out which function is bugged, there are some helpful tools.
These consist of:
Let's use the following might-be-bug as a running example:
axiom
variables((x^2+2*x)::UP(x, INT))
Type: List SingletonAsOrderedSet
?
Certainly, this is not what one would expect. So, let's find out more about variables!
One way to find all files where variables is instantiated is grep "variables.*==" *. It is not totally reliable, but I found it quite useful and it is quickly typed. Another possibility, within Axiom, is to use
axiom
)di op variables
There are 5 exposed functions called variables :
[1] D -> List Symbol from D if D has FS D2 and D2 has ORDSET
[2] D -> List D4 from D
if D has POLYCAT(D2,D3,D4) and D2 has RING and D3 has
OAMONS and D4 has ORDSET
[3] D -> List D4 from D
if D has PSCAT(D2,D3,D4) and D2 has RING and D3 has OAMON
and D4 has ORDSET
[4] D -> List D4 from D
if D has PSETCAT(D2,D3,D4,D5) and D2 has RING and D3 has
OAMONS and D4 has ORDSET and D5 has RPOLCAT(D2,D3,D4)
[5] Fraction Polynomial D3 -> List Symbol from RationalFunction D3
if D3 has INTDOM
There are 4 unexposed functions called variables :
[1] SparseUnivariatePolynomial D6 -> List D4
from FactoringUtilities(D3,D4,D5,D6)
if D6 has POLYCAT(D5,D3,D4) and D3 has OAMONS and D4 has
ORDSET and D5 has RING
[2] FortranExpression(D2,D3,D4) -> List Symbol
from FortranExpression(D2,D3,D4)
if D2: LIST SYMBOL and D3: LIST SYMBOL and D4 has FMTC
[3] Pattern D2 -> List Pattern D2 from Pattern D2 if D2 has SETCAT
[4] D2 -> List D4 from PolynomialCategoryQuotientFunctions(D3,D4,D5,
D6,D2)
if D3 has OAMONS and D4 has ORDSET and D5 has RING and D6
has POLYCAT(D5,D3,D4) and D2 has Field with
coerce : D6 -> %
numer : % -> D6
denom : % -> D6
This is a list of all [exposed]? and [unexposed]? operations called variables, together with their [modelines]?. Note that the information that
)di op (and all the other tools, like asq) give about sourcefiles is currently wrong! I use grep ")abb.* UP " * to find the correct sourcefile.
In some cases the list of operations is very long. For example, )di op coerce lists 168 exposed and 50 unexposed items. Fortunately there is another tool:
axiom
)set message bottom on
variables(x::UP(x, INT))
Function Selection for variables
Arguments: UP(x,INT)
[1] signature: UP(x,INT) -> LIST SAOS
implemented: slot (List (SingletonAsOrderedSet))$ from UP(x,INT)
Type: List SingletonAsOrderedSet
?
Now we know that variables does not come from some package, but rather from UP itself. You might want to compare with
axiom
)set message bottom on
variables(x::FRAC POLY INT)
Function Selection for variables
Arguments: FRAC POLY INT
-> no appropriate variables found in Fraction Polynomial Integer
-> no appropriate variables found in Fraction Polynomial Integer
Modemaps from Associated Packages
no modemaps
Remaining General Modemaps
[1] Fraction Polynomial D3 -> List Symbol from RationalFunction D3
if D3 has INTDOM
[2] D -> List D4 from D
if D has PSETCAT(D2,D3,D4,D5) and D2 has RING and D3 has
OAMONS and D4 has ORDSET and D5 has RPOLCAT(D2,D3,D4)
[3] D -> List D4 from D
if D has PSCAT(D2,D3,D4) and D2 has RING and D3 has OAMON
and D4 has ORDSET
[4] D -> List D4 from D
if D has POLYCAT(D2,D3,D4) and D2 has RING and D3 has
OAMONS and D4 has ORDSET
[5] D -> List Symbol from D if D has FS D2 and D2 has ORDSET
[1] signature: FRAC POLY INT -> LIST SYMBOL
implemented: slot (List (Symbol))(Fraction (Polynomial (Integer))) from RF INT
[2] signature: EXPR INT -> LIST SYMBOL
implemented: slot (List (Symbol))$ from EXPR INT
[3] signature: POLY INT -> LIST SYMBOL
implemented: slot (List (Symbol))$ from POLY INT
Type: List Symbol
Here, variables comes from RF. Another way to watch Axiom looking for functions is )lisp (setq |$monitorNewWorld| t), but I don't understand its output too well. More possibilities are discussed in the file DeveloperNotes.dvi in axiom/mnt/linux/doc/.
Given that variables comes from UP, we still don't know where it is actually coded. In fact, there is no code for variables in UP. So, where does Axiom look next? We can find out about this using
asq -cc UP
which tells us, that the constructorcategory of UP is UPOLYC. Et voilĂ :
)abbrev category UPOLYC UnivariatePolynomialCategory
...
UnivariatePolynomialCategory(R:Ring): Category ==
add
...
variables(p) ==
zero? p or zero?(degree p) => []
[create()]
It also helps to look at the modeline of variables, which we can find out using ')sh UP':
)sh UP
UnivariatePolynomial(x: Symbol,R: Ring) is a domain constructor
Abbreviation for UnivariatePolynomial is UP
This constructor is exposed in this frame.
Issue )edit /home/rubey/axiom/mnt/linux/../../src/algebra/UP.spad to see algebra source code for UP
------------------------------- Operations --------------------------------
...
variables : % -> List SingletonAsOrderedSet
...
SingletonAsOrderedSet? is a domain which consists of the single element "?"! Hence, we have reduced the problem of fixing the bug to a
design issue.