Hello,

There are many easy examples of this when you use the Axiom interpreter.
Perhaps the following is related:

Trying to implement free products of monoids
FreeProductMonoid(M1:Monoid,M2:Monoid)
(see attachment, not very elegant, but I don't know how to avoid "mixed lists" otherwise). I am stuck at the following problem: There are two converters

coerce:M1 -> %
coerce:M2 -> %

but somehow always the first converter is called,
in the order where they are found in the source file,
leading to strange results:


(1) -> Z2:=CyclicGroup(2,'a)

   (1)  CyclicGroup(2,a)
                                                       Type: Domain
(2) -> Z3:=CyclicGroup(3,'b)

   (2)  CyclicGroup(3,b)
                                                       Type: Domain
(3) -> G:=FreeProductMonoid(Z2,Z3)

   (3)  FreeProductMonoid(CyclicGroup(2,a),CyclicGroup(3,b))
                                                       Type: Domain
(4) -> a1:=a::Z2

   (4)  a
                                                       Type: CyclicGroup(2,a)
(5) -> b1:=b::Z3

   (5)  b
                                                       Type: CyclicGroup(3,b)
(6) -> a2:=a1::G

   (6)  a
                   Type: FreeProductMonoid(CyclicGroup(2,a),CyclicGroup(3,b))
(7) -> b2:=b1::G

   (7)  a
                   Type: FreeProductMonoid(CyclicGroup(2,a),CyclicGroup(3,b))

(8) -> b2a:= (b1^2) ::G

         2
   (8)  a
                   Type: FreeProductMonoid(CyclicGroup(2,a),CyclicGroup(3,b))


(9) -> b2a * 1::G

   (9)  1

(10) -> b::Z2

   >> System error:
   wrong symbol


Especially (8) is pretty strange. (9) shows that indeed b made it into M1 and is the identity element. (10) shows that coercion in CyclicGroup filters out the wrong symbols as it should. What am I missing? Somehow the interpreter is confused by two almost equal signatures (both M1 and M2 are Monoids). Is this forbidden?
Renaming the converters to coerce1 and coerce2 makes it work.

regards
Franz
#include "axiom"


define FreeProductCategory(M1:Monoid, M2:Monoid):Category == with {

        coerce:M1 -> %;
        coerce:M2 -> %;
        
        length:% -> Integer;

}
FreeProductMonoid(M1: Monoid,M2: Monoid): 
Join(FreeProductCategory(M1,M2),Monoid)  == add {
        +++ 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]
        
        Rep == Record(factors1:List M1, factors2:List M2);
        
        1:% == {
                import from Rep,M1,M2;
                per [ [EMAIL PROTECTED],[EMAIL PROTECTED];
        }

        one?(x:%):Boolean == {
                import from M1,M2,Rep;
                one? first ((rep x) factors1) and one? first ((rep x) factors2);
        }
        
        coerce(x:M1):% == { 
                import from List M1,List M2,Rep;
                per [[x],[EMAIL PROTECTED];
        }

        coerce(y:M2):% == {
                import from List M1,List M2,Rep;
                per [EMAIL PROTECTED],[y]];
        }

        _=(x:%,y:%):Boolean == rep x = rep y;

        coerce(w:%):OutputForm ==  {
                import from Integer;
                one? w => outputForm([EMAIL PROTECTED]); 
                import from List OutputForm,List List OutputForm;
                import from OutputForm;
                import from Symbol;

                infix("*"::Symbol::OutputForm, reduce(concat,[  (if one? a then 
[b::OutputForm] else if one? b then [a::OutputForm] else [a::OutputForm, 
b::OutputForm]) for a:M1 in (rep w) factors1 for b:M2 in (rep w) factors2 ]));
        }

        reduceword!:Rep -> Rep;

        reduceword!(x:Rep):Rep == {
                x1:List M1 := x factors1;
                x2:List M2 := x factors2;
                import from NonNegativeInteger,List M1, List M2;
                -- length one is in reduced form already
                if(#x1 = 1) then x;
                while (#x2 > 1) repeat {
                        while(#x2 > 1 and (one? second x1 or one? first x2)) 
repeat {
                                setfirst!(x1, first x1 * second x1);
                                setrest!(x1,rest rest x1);
                                setfirst!(x2, first x2  * second x2);
                                setrest!(x2,rest rest x2);
                                -- if there is change, we need to go back
                                if(one? first x1 or one? first x2) then {
                                        reduceword!(x);
                                }
                        }
                        --next letter
                        x1:= rest x1;
                        x2:= rest x2;
                }
                x;
        }

        _*(x:%,y:%):% == {
                w1:List M1 := concat((rep x) factors1, (rep y) factors1);
                w2:List M2 := concat((rep x) factors2, (rep y) factors2);
                res:Rep:=[w1,w2];
                reduceword! res;
                per res;
        }

        length(w:%):Integer == {
                import from Rep, List M1, List M2, NonNegativeInteger;
                n:Integer := (# ((rep w) factors1))::Integer + (# ((rep w) 
factors2))::Integer;
                if(one? first ((rep w) factors1)) then n:=n-1;
                if(one? last ((rep w) factors2)) then n:=n-1;
                n;
        }        
}

#include "axiom"

CyclicGroup(n:PositiveInteger,g:Symbol): Group with {
        1: %;
        
        coerce : % -> OutputForm;
        
        one?: % -> Boolean;
        
        coerce:Symbol -> %;

        genrtr: %;

} == add {
        Rep == Integer;

        import from Integer;
        1:% == per 0;

        genrtr: % == per ([EMAIL PROTECTED]);
        
        coerce(x:%):OutputForm ==  {
                zero? rep x => outputForm([EMAIL PROTECTED]); 
                z where {import from Fraction Polynomial Integer; import from 
Polynomial Integer;
                        z:OutputForm := ((g::Polynomial Integer)::Fraction 
Polynomial Integer^(rep x))::OutputForm;
                }
        };


        coerce(x:Symbol):% ==  {
                x ~= g => error "wrong symbol";
                per ([EMAIL PROTECTED]);
        }
        
        
        (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