Please find attached a little modification of your code.
Unfortunately, I am still unable to use "embed1".
(4) -> Z2:=CyclicGroup(2,'a)
(4) CyclicGroup(2,a)
Type: Domain
(5) -> Z3:=CyclicGroup(3,'b)
(5) CyclicGroup(3,b)
Type: Domain
(6) -> G:=FreeProductMonoid(Z2,Z3)
(6) ->
(6) FreeProductMonoid(CyclicGroup(2,a),CyclicGroup(3,b))
Type: Domain
(7) -> a:Z2 := generator()
1
(7) a
Type: CyclicGroup(2,a)
(8) -> b:Z3 := generator()
1
(8) b
Type: CyclicGroup(3,b)
(9) -> ga:G := embed1 a
(9) -> ga:G := embed1(a)$G
(9) ->
>> System error:
The function NIL is undefined.
I currently have no idea why that is.
If you always ensure that M1 and M2 are different when
FreeProductMonoid(M1,M2) is called, then having just
coerce(m: M1): % == per [[m, 1]];
coerce(m: M2): % == per [[1, m]];
should be fine. But coercion in FreeProductMonoid(M,M) cannot work for
obvious reasons.
BTW, I would be really happy if the Aldor/SPAD compiler was able to warn
if there is a collaps in function signatures for equal parameter domains.
Franz, your original question was for a strange coercion. That "coerce"
should be removed completely from the code (I have done so). There was
only one value for which it would succeed.
Ralf
#include "axiom"
define FreeProductCategory(M1: Monoid, M2: Monoid):Category == with {
embed1: M1 -> %;
embed2: M2 -> %;
length:% -> Integer;
}
---rhx: "+++" Documentation must come before the identifier they refer to.
+++ FreeProductMonoid(M1,M2) ist the free product of the
+++ monoids M1 and M2
+++ where the neutral elements are identified
+++ Representation by two lists of factors:
+++ factors1 = [a1,a2,a3,...,am] and factors2 = [b1,b2,b3,...,bm]
+++ corresponds to the element a1*b1*a2*b2*a3*b3*...*am*bm
+++ a1 and bm are possibly the neutral element
+++ the neutral element is represented by [EMAIL PROTECTED] [EMAIL PROTECTED]
FreeProductMonoid(
M1: Monoid,
M2: Monoid
): Join(FreeProductCategory(M1, M2), Monoid) == add {
Pair == Record(m1: M1, m2: M2);
Rep == List Pair;
import from Pair, Rep;
m1(p: Pair): M1 == p.m1;
m2(p: Pair): M2 == p.m2;
1: % == per [];
one?(x: %): Boolean == empty? rep x;
embed1(m: M1): % == per [[m, 1]];
embed2(m: M2): % == per [[1, m]];
(x: %) = (y: %): Boolean == rep x = rep y;
local coerce(p: Pair): OutputForm == {
one? m1 p => (m2 p)::OutputForm;
one? m2 p => (m1 p)::OutputForm;
(m1 p)::OutputForm * (m2 p)::OutputForm;
}
coerce(x: %): OutputForm == {
one? x => outputForm(1$Integer);
import from Symbol, List OutputForm;
infix("*"::Symbol::OutputForm, [p::OutputForm for p in rep x]);
}
(x: %) * (y: %): % == {
one? x => y;
one? y => x;
xx := reverse rep x;
yy := rep y;
px := first xx;
py := first yy;
if one? m1 py then {
yy := cons([m1 px, m2 px * m2 py], rest yy);
xx := rest xx;
} else if one? m2 px then {
yy := cons([m1 px * m1 py, m2 py], rest yy);
xx := rest xx;
}
for p in xx repeat yy := cons(p, yy);
per yy;
}
length(x: %): Integer == {
one? x => 0;
xx: Rep := rep x;
--rhx: I have no idea how to convert NNI to INT.
n: Integer := (#xx)*(1$Integer);
if one? m1 first xx then n := n-1;
if one? m2 last xx then n := n-1;
n;
}
}
#include "axiom"
CyclicGroup(n: PositiveInteger, g: Symbol): Group with {
1: %;
coerce : % -> OutputForm;
one?: % -> Boolean;
-- genrtr: %;
--rhx: Never abbreviate!!! In Aldor you could use
generator: () -> %;
--rhx: but unfortunately AXIOM cannot work with it. :-(
-- gen: () -> %;
} == add {
Rep == Integer;
import from Integer;
1: % == per 0;
generator(): % == per 1;
coerce(x: %): OutputForm == {
one? x => (1$Integer)::OutputForm;
g :: OutputForm ** (rep x)::OutputForm;
};
(x:%) * (y:%): % == per addmod(rep x,rep y,n::Integer);
(x:%) = (y:%): Boolean == rep x = rep y;
one?(x: %): Boolean == zero? rep x;
inv(x: %): % == {
one? x => 1;
per(n::Integer - rep x)
}
}
_______________________________________________
Axiom-developer mailing list
Axiom-developer@nongnu.org
http://lists.nongnu.org/mailman/listinfo/axiom-developer