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

Reply via email to