You can subscribe to this list here.
2007 
_{Jan}

_{Feb}

_{Mar}

_{Apr}

_{May}

_{Jun}

_{Jul}

_{Aug}
(73) 
_{Sep}
(57) 
_{Oct}
(138) 
_{Nov}
(91) 
_{Dec}
(99) 

2008 
_{Jan}
(91) 
_{Feb}
(53) 
_{Mar}
(37) 
_{Apr}
(125) 
_{May}
(176) 
_{Jun}
(23) 
_{Jul}
(135) 
_{Aug}
(119) 
_{Sep}
(26) 
_{Oct}
(38) 
_{Nov}
(46) 
_{Dec}
(11) 
2009 
_{Jan}
(4) 
_{Feb}
(2) 
_{Mar}
(5) 
_{Apr}
(15) 
_{May}
(4) 
_{Jun}
(18) 
_{Jul}
(1) 
_{Aug}
(4) 
_{Sep}
(17) 
_{Oct}
(9) 
_{Nov}
(14) 
_{Dec}
(11) 
2010 
_{Jan}
(9) 
_{Feb}
(6) 
_{Mar}
(1) 
_{Apr}
(1) 
_{May}
(4) 
_{Jun}
(3) 
_{Jul}

_{Aug}
(10) 
_{Sep}
(7) 
_{Oct}
(7) 
_{Nov}
(36) 
_{Dec}
(23) 
2011 
_{Jan}
(2) 
_{Feb}
(1) 
_{Mar}
(1) 
_{Apr}
(11) 
_{May}
(5) 
_{Jun}
(17) 
_{Jul}
(2) 
_{Aug}
(26) 
_{Sep}
(14) 
_{Oct}
(51) 
_{Nov}
(39) 
_{Dec}
(7) 
2012 
_{Jan}
(24) 
_{Feb}
(7) 
_{Mar}
(9) 
_{Apr}
(2) 
_{May}
(9) 
_{Jun}
(7) 
_{Jul}
(3) 
_{Aug}
(1) 
_{Sep}
(8) 
_{Oct}
(12) 
_{Nov}
(1) 
_{Dec}

2013 
_{Jan}

_{Feb}

_{Mar}

_{Apr}
(35) 
_{May}
(28) 
_{Jun}
(14) 
_{Jul}
(10) 
_{Aug}
(3) 
_{Sep}
(6) 
_{Oct}

_{Nov}
(1) 
_{Dec}

2014 
_{Jan}

_{Feb}

_{Mar}

_{Apr}
(4) 
_{May}
(3) 
_{Jun}
(2) 
_{Jul}
(2) 
_{Aug}
(2) 
_{Sep}
(1) 
_{Oct}
(3) 
_{Nov}
(5) 
_{Dec}
(8) 
2015 
_{Jan}
(3) 
_{Feb}
(2) 
_{Mar}

_{Apr}

_{May}
(1) 
_{Jun}

_{Jul}

_{Aug}

_{Sep}

_{Oct}

_{Nov}

_{Dec}

S  M  T  W  T  F  S 







1

2

3

4

5

6

7

8

9

10
(2) 
11

12
(2) 
13
(5) 
14
(1) 
15
(2) 
16
(2) 
17
(2) 
18
(3) 
19
(3) 
20
(1) 
21

22
(3) 
23
(1) 
24
(20) 
25
(2) 
26

27
(2) 
28

29

30

31






From: Waldek Hebisch <hebisch@ma...>  20111027 16:51:07

Gabriel Dos Reis wrote: > > Waldek Hebisch <hebisch@...> writes: > >  I am not sure you can keep constructors calls completely uniform: >  we have 'construct', 'new' and a bunch of more specific constructors. >  Below is patch that I propose (only to Product, algebra will also >  need some adjustment). With the patch I can do: > > I like the general flavour of it. However I have one quibble. > >  >  (3) > Pr := Product(Integer, Polynomial(Integer)) >  >  (3) Product(Integer,Polynomial(Integer)) >  Type: Type >  (4) > [1, x] >  >  (4) [1,x] >  Type: List(Polynomial(Integer)) >  (5) > [1, x]$Pr >  >  (5) (1,x) >  Type: Product(Integer,Polynomial(Integer)) > > I think *one* kind of syntax should be sufficient. Either square > brackets or round brackets, but not both. The reason being that in > typical Spad code and scripts, we do not have much of type annotations > around to help quickly figure out what is meant. So, have only one way > of saying something is a tremendous help for code/script understanding. > I would vote for round brackets, but only marginally. On _input_ side there is only one syntax: square brackets. Given that round brackets are used to denote subexpressions and function calls I am affraid that giving them extra meaning would lead to confusion. Concerning output, I believe that that best is use the same form as for input. Round brackets in output come from original code, but it is easy to change them to square brackets. > >  (6) > p1 := [1, x]$Pr >  >  (6) (1,x) >  Type: Product(Integer,Polynomial(Integer)) >  (7) > p2 := [7, y]$Pr >  >  (7) (7,y) >  Type: Product(Integer,Polynomial(Integer)) >  (8) > p1 + p2 >  >  (8) (8,y + x) >  Type: Product(Integer,Polynomial(Integer)) >  (9) > p1*p2 >  >  (9) (7,x y) >  Type: Product(Integer,Polynomial(Integer)) >  >  Note that plain '[1, x]' produces a list  one needs '$Pr' to choose >  'construct' from the product. > > Unless you specifiy the target, not? E.g. > > a: Pr := [1,x] > > or > > [1,x]@Pr > >  Gaby Sure, both works. My point is that interpreter will not introduce product by itself, one must explicitly request it.  Waldek Hebisch hebisch@... 
From: Gabriel Dos Reis <gdr@cs...>  20111027 16:34:53

Waldek Hebisch <hebisch@...> writes:  I am not sure you can keep constructors calls completely uniform:  we have 'construct', 'new' and a bunch of more specific constructors.  Below is patch that I propose (only to Product, algebra will also  need some adjustment). With the patch I can do: I like the general flavour of it. However I have one quibble.   (3) > Pr := Product(Integer, Polynomial(Integer))   (3) Product(Integer,Polynomial(Integer))  Type: Type  (4) > [1, x]   (4) [1,x]  Type: List(Polynomial(Integer))  (5) > [1, x]$Pr   (5) (1,x)  Type: Product(Integer,Polynomial(Integer)) I think *one* kind of syntax should be sufficient. Either square brackets or round brackets, but not both. The reason being that in typical Spad code and scripts, we do not have much of type annotations around to help quickly figure out what is meant. So, have only one way of saying something is a tremendous help for code/script understanding. I would vote for round brackets, but only marginally.  (6) > p1 := [1, x]$Pr   (6) (1,x)  Type: Product(Integer,Polynomial(Integer))  (7) > p2 := [7, y]$Pr   (7) (7,y)  Type: Product(Integer,Polynomial(Integer))  (8) > p1 + p2   (8) (8,y + x)  Type: Product(Integer,Polynomial(Integer))  (9) > p1*p2   (9) (7,x y)  Type: Product(Integer,Polynomial(Integer))   Note that plain '[1, x]' produces a list  one needs '$Pr' to choose  'construct' from the product. Unless you specifiy the target, not? E.g. a: Pr := [1,x] or [1,x]@Pr  Gaby 
From: Bill Page <bill.page@ne...>  20111025 00:24:19

Gaby, Thank you for this work. The error message reminds me of a wish: I would really like it if the compiler could pretty print the code that it displays. Reading the lisp notation is still awkward for me years later and I know that it puts off some potential new users. Even if decompiling > (IF (= a 0) > b > (IF (= b 0) > a > (SEQ (:= b0 b) (:= u ((elt P monomial) 1 0)) (:= v 0) > (REPEAT (WHILE (~= (leadingCoefficient b) 0)) > ... results is something a little different than the original source, I think it is very desirable that it at least be readable SPAD code. I would be glad to try to help solve some problem cases in the algebra. If it would be useful just let me know. Regards, Bill Page. On Mon, Oct 24, 2011 at 8:09 PM, Gabriel Dos Reis <gdr@...> wrote: > Bill Page <bill.page@...> writes: > >  On Mon, Oct 24, 2011 at 7:36 PM, Gabriel Dos Reis wrote: >  > ... >  > Bill Page writes: >  >  So it is a coincidence that the compiler happens to choose 0@... or that >  >  the representation of all of these candidates is the same so that it >  >  does not matter? >  > >  > It is mostly concidence. The explanation is that the type of leftLcm is >  > >  > >  > (P,P) > P >  > >  > and before starting the compilation of a function body, the compiler >  > automatically imports the return type and domain of each parameter. >  > So the modemap of 0@... happens to be first on the list, and since the >  > compilers the first that makes tentative compilation OK, it picks it and >  > moves on. >  > >  >  So here it seems very clear that one should have written: >  >  v:P := 0 >  >  and the use of >  >  v := 0 >  >  should produce an error message. I retrospect I think I have probably >  been bitten by this bug a few times in the past. One just seems to get >  used to working around such limitations. But this seems like an >  improvement to me even if it does affect a lot of existing code that >  happens to work right now. A sensible error message would be welcome. >  Would this be hard to do? > > 1. The error message I have is: > > > compiling exported leftLcm : (P,P) > P > ****** comp fails at level 5 with expression: ****** > error in function leftLcm > > (IF (= a 0) > b > (IF (= b 0) > a > (SEQ (:= b0 b) (:= u ((elt P monomial) 1 0)) (:= v 0) > (REPEAT (WHILE (~= (leadingCoefficient b) 0)) > (SEQ (:= qr (leftDivide a b)) > (:= (%Comma a b) > (%Comma b (qr remainder))) > (exit 1 > (:= (%Comma u v) > (%Comma (+ (* u (qr quotient)) v) > u))))) > (exit 1 (* b0 u))))) > ****** level 5 ****** > $x:= (Zero) > $m:= $EmptyMode > $f:= > ((((u #) (b0 #) (b # #) (a # #) ...))) > > >> Apparent user error: > Ambiguous constant 0 in ? constext. Candidates are > 0: P > 0: F > 0: NonNegativeInteger > 0: Integer > > > > 2. In fact, I don't have to change that many existing codes. However, > for a few cases, it takes a while to figure out what the right answer > should be. Which convinces me that the tightening is the right thing to do. > So far, I've posted mostly the easier ones. > 
From: Gabriel Dos Reis <gdr@cs...>  20111025 00:09:19

Bill Page <bill.page@...> writes:  On Mon, Oct 24, 2011 at 7:36 PM, Gabriel Dos Reis wrote:  > ...  > Bill Page writes:  >  So it is a coincidence that the compiler happens to choose 0@... or that  >  the representation of all of these candidates is the same so that it  >  does not matter?  >  > It is mostly concidence. The explanation is that the type of leftLcm is  >  >  > (P,P) > P  >  > and before starting the compilation of a function body, the compiler  > automatically imports the return type and domain of each parameter.  > So the modemap of 0@... happens to be first on the list, and since the  > compilers the first that makes tentative compilation OK, it picks it and  > moves on.  >   So here it seems very clear that one should have written:   v:P := 0   and the use of   v := 0   should produce an error message. I retrospect I think I have probably  been bitten by this bug a few times in the past. One just seems to get  used to working around such limitations. But this seems like an  improvement to me even if it does affect a lot of existing code that  happens to work right now. A sensible error message would be welcome.  Would this be hard to do? 1. The error message I have is: compiling exported leftLcm : (P,P) > P ****** comp fails at level 5 with expression: ****** error in function leftLcm (IF (= a 0) b (IF (= b 0) a (SEQ (:= b0 b) (:= u ((elt P monomial) 1 0)) (:= v 0) (REPEAT (WHILE (~= (leadingCoefficient b) 0)) (SEQ (:= qr (leftDivide a b)) (:= (%Comma a b) (%Comma b (qr remainder))) (exit 1 (:= (%Comma u v) (%Comma (+ (* u (qr quotient)) v) u))))) (exit 1 (* b0 u))))) ****** level 5 ****** $x:= (Zero) $m:= $EmptyMode $f:= ((((u #) (b0 #) (b # #) (a # #) ...))) >> Apparent user error: Ambiguous constant 0 in ? constext. Candidates are 0: P 0: F 0: NonNegativeInteger 0: Integer 2. In fact, I don't have to change that many existing codes. However, for a few cases, it takes a while to figure out what the right answer should be. Which convinces me that the tightening is the right thing to do. So far, I've posted mostly the easier ones. 
From: Bill Page <bill.page@ne...>  20111024 23:57:50

On Mon, Oct 24, 2011 at 7:36 PM, Gabriel Dos Reis wrote: > ... > Bill Page writes: >  So it is a coincidence that the compiler happens to choose 0@... or that >  the representation of all of these candidates is the same so that it >  does not matter? > > It is mostly concidence. The explanation is that the type of leftLcm is > > > (P,P) > P > > and before starting the compilation of a function body, the compiler > automatically imports the return type and domain of each parameter. > So the modemap of 0@... happens to be first on the list, and since the > compilers the first that makes tentative compilation OK, it picks it and > moves on. > So here it seems very clear that one should have written: v:P := 0 and the use of v := 0 should produce an error message. I retrospect I think I have probably been bitten by this bug a few times in the past. One just seems to get used to working around such limitations. But this seems like an improvement to me even if it does affect a lot of existing code that happens to work right now. A sensible error message would be welcome. Would this be hard to do? Regards, Bill Page. 
From: Gabriel Dos Reis <gdr@cs...>  20111024 23:36:26

Bill Page <bill.page@...> writes:  On Mon, Oct 24, 2011 at 6:49 PM, Gabriel Dos Reis wrote:  > ...  > Another example: Consider the function leftLcm from  > NonCommutativeOperatorDivision(P,F) where  > P: MonogenicLinearOperator(F)  > F: Field  >  > the function definition is:  >  > leftLcm(a,b) ==  > a = 0 =>b  > b = 0 =>a  > b0 := b  > u := monomial(1,0)$P  > v := 0  > while leadingCoefficient b ~= 0 repeat  > qr := leftDivide(a,b)  > (a, b) := (b, qr.remainder)  > (u, v) := (u*qr.quotient+v, u)  > b0*u  >  >  > The problem is the definition of the local variable v:  >  > v := 0  >   I like this example, although now I believe also your first example.   > There are four candidates in scope:  >  > 0: P  > 0: F  > 0: NonNegativeInteger  > 0: Integer  >  > (the right answer is 0@...).  >   So it is a coincidence that the compiler happens to choose 0@... or that  the representation of all of these candidates is the same so that it  does not matter? It is mostly concidence. The explanation is that the type of leftLcm is (P,P) > P and before starting the compilation of a function body, the compiler automatically imports the return type and domain of each parameter. So the modemap of 0@... happens to be first on the list, and since the compilers the first that makes tentative compilation OK, it picks it and moves on.  Gaby 
From: Bill Page <bill.page@ne...>  20111024 23:29:35

On Mon, Oct 24, 2011 at 6:49 PM, Gabriel Dos Reis wrote: > ... > Another example: Consider the function leftLcm from > NonCommutativeOperatorDivision(P,F) where > P: MonogenicLinearOperator(F) > F: Field > > the function definition is: > > leftLcm(a,b) == > a = 0 =>b > b = 0 =>a > b0 := b > u := monomial(1,0)$P > v := 0 > while leadingCoefficient b ~= 0 repeat > qr := leftDivide(a,b) > (a, b) := (b, qr.remainder) > (u, v) := (u*qr.quotient+v, u) > b0*u > > > The problem is the definition of the local variable v: > > v := 0 > I like this example, although now I believe also your first example. > There are four candidates in scope: > > 0: P > 0: F > 0: NonNegativeInteger > 0: Integer > > (the right answer is 0@...). > So it is a coincidence that the compiler happens to choose 0@... or that the representation of all of these candidates is the same so that it does not matter? Regards, Bill Page 
From: Gabriel Dos Reis <gdr@cs...>  20111024 22:49:15

Gabriel Dos Reis <gdr@...> writes:  The algebra is full of examples where things work by a sheer amount of  luck. Consider the function rightPower in functor MonadWithUnit:   rightPower(a: %,n: NonNegativeInteger) ==  zero? n => 1  res := 1  for i in 1..n repeat res := res * a  res   What should be the type of constant 1 selected at the assignment   res := 1   and why? Another example: Consider the function leftLcm from NonCommutativeOperatorDivision(P,F) where P: MonogenicLinearOperator(F) F: Field the function definition is: leftLcm(a,b) == a = 0 =>b b = 0 =>a b0 := b u := monomial(1,0)$P v := 0 while leadingCoefficient b ~= 0 repeat qr := leftDivide(a,b) (a, b) := (b, qr.remainder) (u, v) := (u*qr.quotient+v, u) b0*u The problem is the definition of the local variable v: v := 0 There are four candidates in scope: 0: P 0: F 0: NonNegativeInteger 0: Integer (the right answer is 0@...).  Gaby 
From: Gabriel Dos Reis <gdr@cs...>  20111024 22:42:09

Bill Page <bill.page@...> writes:  Doesn't the compiler already know that the value of res is returned  from the function? No. At the point where the compiler is processing the local assignment res := 1 it has no clue that it will be used later as the retuned value.  Therefore infers that res must be of type % ? Nope, that is not the way the compiler works in all AXIOMs.  Even  in   zero? n => 1   you have the question of what is type of 1. No. That line says "return this value", consequently, it checks the return value (1) in the context of expected return type. That does not hold for the assignment, because at that point, the assignment is not type checked in the context of return type. Rather, it is type checked in the context of "don't care about value"  technically $NoValueMode in the compiler.  Gaby 
From: Bill Page <bill.page@ne...>  20111024 22:34:44

Doesn't the compiler already know that the value of res is returned from the function? Therefore infers that res must be of type % ? Even in zero? n => 1 you have the question of what is type of 1. On Mon, Oct 24, 2011 at 6:22 PM, Gabriel Dos Reis wrote: > > The algebra is full of examples where things work by a sheer amount of > luck. Consider the function rightPower in functor MonadWithUnit: > > rightPower(a: %,n: NonNegativeInteger) == > zero? n => 1 > res := 1 > for i in 1..n repeat res := res * a > res > > What should be the type of constant 1 selected at the assignment > > res := 1 > > and why? > > There are three candidates in in scope: > > 1: % > 1: NonNegativeInteger > 1: Integer > > Currently, all this works mostly by luck. > > The fix is to write > > res: % := 1 > > or > > res := 1@% > > or > > res := 1$% > > >  Gaby > > >  > The demand for IT networking professionals continues to grow, and the > demand for specialized networking skills is growing even more rapidly. > Take a complimentary Learning@... SelfAssessment and learn > about Cisco certifications, training, and career opportunities. > http://p.sf.net/sfu/ciscodev2dev > _______________________________________________ > openaxiomdevel mailing list > openaxiomdevel@... > https://lists.sourceforge.net/lists/listinfo/openaxiomdevel > 
From: Gabriel Dos Reis <gdr@cs...>  20111024 22:23:05

The algebra is full of examples where things work by a sheer amount of luck. Consider the function rightPower in functor MonadWithUnit: rightPower(a: %,n: NonNegativeInteger) == zero? n => 1 res := 1 for i in 1..n repeat res := res * a res What should be the type of constant 1 selected at the assignment res := 1 and why? There are three candidates in in scope: 1: % 1: NonNegativeInteger 1: Integer Currently, all this works mostly by luck. The fix is to write res: % := 1 or res := 1@% or res := 1$%  Gaby 
From: Gabriel Dos Reis <gdr@cs...>  20111024 20:29:16

Waldek Hebisch <hebisch@...> writes:  I wrote:  >  > Gabriel Dos Reis wrote:  > >  > > Waldek Hebisch <hebisch@...> writes:  <snip>  > >   > >  new : (NonNegativeInteger, S) > %  > >   > >  So the first argument to 'new' must be 'NonNegativeInteger' and the  > >  second must be '%'.  > >  > > 1. new, expects its second *argument* to be of type %. It does not  > > require that there be no implicit coercion between the argument  > > as lexically written in the source code, and the actual code  > > generated for that argument. If one thinks that the mere presence of  > > the parameter "Rep" indicates that is the representation domain,  > > therefore the implicit coercion from Rep to % is OK, then 0@... is  > > a good viable candidate.  > >  > > 2. Fortunately, in this case, 0@% is also defined explicitly to be  > > 0$Rep, but there is no requirement that be the case. And when  > > it is not, we get a problem.  >  > Actually 13.6 says that '%' take precedence over 'Rep', so this one  > is excluded.  >  > > 3. ModMonic(R,Rep) satisfies UnivariatePolynomialCategory(R), so that  > > means that there is alsoanother implicit coercion that turns  > > 0@... into a legitimate value of type %.  > >  > > 4. Similar reasoning holds for 0@... because % satisfies Ring,  > > and there is an implicit coercion from Integer to any domain that  > > satisfies Ring.  > >  > > 5. Since NonNegativeInteger is a subdomain of Integer, it also  > > provides an implicit coercion.  > >  > > So, in fact if one thinks that the mere presense of the parameter Rep is  > > sufficient to indicate representation domain and therefore implicit  > > coercions, then we have a legitimate case of ambiguity.  >  > OK, if you think about exact operations used to produce 0, then  > there is really ambiguity. However, IMO coercions are supposed  > to be homomorphims, so each of ways should lead to 0 in '%'.  >   A little correction: when checking if selected modemap  is applicable compiler tries to coerce obtained result  to requested type. AFAICS compiler only will succeed  coercing '%' to '%' and 'Rep' to '%'. I am not sure if  hacks to prefer '%' over 'Rep' work in this case. If yes  then there is no ambiguity in choice of operations.  If no, maybe we should fix compiler to choose '%' (given that  this preference is documented). See my comment in a message I just sent. I do not know whether that hack works for FriCAS all the time. I know it did not for OpenAxiom and I got frustrated  simple case is compiler error, less simple is when one gets a runtime infinite recursion without knowing where to search. This is part of what prompted me to look closer at function selection in general, and that of constants in particular.  Also, if chooses representation which has 0 different than  0 in %, then it is probably better not to specify Rep at  all. Did you consider suppresing the implicit conversion from Rep to % and vice versa?  Gaby 
From: Gabriel Dos Reis <gdr@cs...>  20111024 20:16:27

Waldek Hebisch <hebisch@...> writes:  Gabriel Dos Reis wrote:  >  > Waldek Hebisch <hebisch@...> writes:  >  >  Gabriel Dos Reis  >  >  >  >  >  > Consider the definition of ModMonoid:  >  > 8<8<8<  >  > )abbrev domain MODMON ModMonic  >  > ++ Description:  >  > ++ This package \undocumented  >  >  >  > ModMonic(R,Rep): C == T  >  >  >  <snip>  >  > Its description does not have a claim for "author", but the intersection  >  > of authors of domains using this domain leaves me with Johannes Grabmeier :)  >  >  >  >  >  > ModMonic is not a builtin domain, therefore one needs a definition of its  >  > representation, i.e. a definition for "Rep", is needed. Yet, none is  >  > provided. Rather, "Rep" here is specified as a parameter to the functor.  >  > (That is not the same as defining it locally to some value)  >   >  Hmm, I am not sure what difference makes defining:  >   >  ModMonic(R,RepT): C == T  >   >  and later  >   >  Rep := RepT  >  > that is the brownie point (and what I did internally).  >  > There are fundamental differences. First, because of the principle of  > abstraction, parameter names are and should be immaterial. Surely, you  > do not want your functions or constructors to start behavingly  > differently just because you happen to consistently rename its parameters.   In loose sense yes. But I do not expect to be able to use  'for' as a name of parameter, `for' is not a name; it is a keyword. Howeverif you write it _for, is becomes a legit name.  in general languagedefined identifiers may carry special meaning. No dispute about that. However, the special meaning is usually in specified contexts.  number of such special identifiers but they have their place  in the language. Concerning 'Rep' specifically, shadowing  builtion meaning would be worse. Agreed.  Signalling error is reasonable, but I do not see it as clearly  superior to current behaviour. I do not know how to make sense of it. There are several guess, but I do not know a general coherent principle that makes sense it. As I observed early, in old AXIOM if you write Rep == RepT you do not get the special identifier treatement. So, what is the principle. I would hate to have to paraphrase the implementation as specification, when in fact we do not even know what the implementation is correct (we do not know what it is implementing.)   >  BTW: AFAICS there is no need to have Rep at all  all Rep does is  >  allowing magic coercions between % and Rep.  >  > Let me clarify.  >  > There ought to be a way of saying what the representation domain is.  > The AXIOM book documents that you need the "special variable Rep", as  > stated in section 13.6 titled "Representation". The official grammar in  > section 13.2 (page 528) lists assignment to Rep as the first thing.   13.6 says 'uses the special variable Rep to identify the lower level  data type ...'. It does not say that you have to 'identify the lower  level data type ...'. 13.2 says 'recommended format', again no  indication that Rep is mandatory. but then why Rep == RepT does not work if you think there should be no mandatory format?  My reading of Davenport paper is that actual represention is  by design untyped. That is correct. The underlying lowlevel representation matters only from representation isomorphism point of view. But that is irrelevant in order to decide which function to pick. Otherwise, one generates wrong code, untyped lowerlevel representation notwithstanding.  In particular one can provide creation  functions and operations in lowerlevel language  consitency  of such operations with representation is responsibility of  implementer, _not_ of Spad compiler. Similarely, one can  implement creation functions and operations in Spad and  use 'pretend' to switch view between '%' and actual  representation domain.   Of course, you may wish to have more strict rules about  representation, but this is language change.   >  > Now, consider the capsulelevel variable "power". It is declared as  >  >  >  > power:PrimitiveArray(%)  >  >  >  > then later assigned to as  >  >  >  > power := new(0,0)  >  >  >  > There are two lexical occurences of the literal '0' in there. Can you  >  > guess, which one is which? There are at least five interpretations for  >  > each constant:  >  >  >  > 0: R  the parameter R satisfies Ring  >  > 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R)  >  > 0: %  the current domains satisfies same  >  > 0: NonNegativeInteger  >  > 0: Integer  >  >  >   >  Well, 'power' is declared to be of type 'PrimitiveArray(%)' so 'new'  >  should produce 'PrimitiveArray(%)' and compiler searches for it  >  in 'PrimitiveArray(%)'. And indeed, in 'PrimitiveArray(S)' we  >  have:  >   >  new : (NonNegativeInteger, S) > %  >   >  So the first argument to 'new' must be 'NonNegativeInteger' and the  >  second must be '%'.  >  > 1. new, expects its second *argument* to be of type %. It does not  > require that there be no implicit coercion between the argument  > as lexically written in the source code, and the actual code  > generated for that argument. If one thinks that the mere presence of  > the parameter "Rep" indicates that is the representation domain,  > therefore the implicit coercion from Rep to % is OK, then 0@... is  > a good viable candidate.  >  > 2. Fortunately, in this case, 0@% is also defined explicitly to be  > 0$Rep, but there is no requirement that be the case. And when  > it is not, we get a problem.   Actually 13.6 says that '%' take precedence over 'Rep', so this one  is excluded. except it is vague on what it means by '%' takes precedence over 'Rep'. The implementation is this: compNoStacking(x,m,e) == T:= comp2(x,m,e) => (m=$EmptyMode and T.mode=$Representation => [T.expr,"$",T.env]; T) $Representation is bound in compDefineFunctor, set by doIt this hack says that when something is undeclared, $ is preferred to the underlying representation  RDJ 9/12/83 compNoStacking1(x,m,e,$compStack) compNoStacking1(x,m,e,$compStack) == u:= get(if m="$" then "Rep" else m,"value",e) => (T:= comp2(x,u.expr,e) => [T.expr,m,T.env]; nil) nil By the time Rep is changed to %, the selection has already been done. The importance to Rep vs. % is that it affects overload resolution. So in the above situation where m=$EmptyMode, we are inference mode, the compiler goes and pick the constant that returns a value of type Rep. Now, it just change the *type* of the expression to %  as if by pretend. It does not necessarily select the constant with type %.  > 3. ModMonic(R,Rep) satisfies UnivariatePolynomialCategory(R), so that  > means that there is alsoanother implicit coercion that turns  > 0@... into a legitimate value of type %.  >  > 4. Similar reasoning holds for 0@... because % satisfies Ring,  > and there is an implicit coercion from Integer to any domain that  > satisfies Ring.  >  > 5. Since NonNegativeInteger is a subdomain of Integer, it also  > provides an implicit coercion.  >  > So, in fact if one thinks that the mere presense of the parameter Rep is  > sufficient to indicate representation domain and therefore implicit  > coercions, then we have a legitimate case of ambiguity.   OK, if you think about exact operations used to produce 0, then  there is really ambiguity. However, IMO coercions are supposed  to be homomorphims, so each of ways should lead to 0 in '%'. they supposed to, but we don' require that in the type system (even if we have desired it.)  Sure, in general current selection mechanism is unsafe, but  in case of 0 and 1 I would try to preserve it if possible. I am not proposing to change 0 or 1. I think the principle of selection should be clearly specified and applied to other constants too.  Gaby 
From: Waldek Hebisch <hebisch@ma...>  20111024 19:02:09

I wrote: > > Gabriel Dos Reis wrote: > > > > Waldek Hebisch <hebisch@...> writes: <snip> > >  > >  new : (NonNegativeInteger, S) > % > >  > >  So the first argument to 'new' must be 'NonNegativeInteger' and the > >  second must be '%'. > > > > 1. new, expects its second *argument* to be of type %. It does not > > require that there be no implicit coercion between the argument > > as lexically written in the source code, and the actual code > > generated for that argument. If one thinks that the mere presence of > > the parameter "Rep" indicates that is the representation domain, > > therefore the implicit coercion from Rep to % is OK, then 0@... is > > a good viable candidate. > > > > 2. Fortunately, in this case, 0@% is also defined explicitly to be > > 0$Rep, but there is no requirement that be the case. And when > > it is not, we get a problem. > > Actually 13.6 says that '%' take precedence over 'Rep', so this one > is excluded. > > > 3. ModMonic(R,Rep) satisfies UnivariatePolynomialCategory(R), so that > > means that there is alsoanother implicit coercion that turns > > 0@... into a legitimate value of type %. > > > > 4. Similar reasoning holds for 0@... because % satisfies Ring, > > and there is an implicit coercion from Integer to any domain that > > satisfies Ring. > > > > 5. Since NonNegativeInteger is a subdomain of Integer, it also > > provides an implicit coercion. > > > > So, in fact if one thinks that the mere presense of the parameter Rep is > > sufficient to indicate representation domain and therefore implicit > > coercions, then we have a legitimate case of ambiguity. > > OK, if you think about exact operations used to produce 0, then > there is really ambiguity. However, IMO coercions are supposed > to be homomorphims, so each of ways should lead to 0 in '%'. > A little correction: when checking if selected modemap is applicable compiler tries to coerce obtained result to requested type. AFAICS compiler only will succeed coercing '%' to '%' and 'Rep' to '%'. I am not sure if hacks to prefer '%' over 'Rep' work in this case. If yes then there is no ambiguity in choice of operations. If no, maybe we should fix compiler to choose '%' (given that this preference is documented). Also, if chooses representation which has 0 different than 0 in %, then it is probably better not to specify Rep at all.  Waldek Hebisch hebisch@... 
From: Waldek Hebisch <hebisch@ma...>  20111024 18:47:08

Bill Page wrote: > > On Mon, Oct 24, 2011 at 1:02 PM, Gabriel Dos Reis wrote: > > > > There is nothing reasonable about it. =A0The way that most AXIOM compilers > > do overload resolution (even in faces of ambiguity) is to pick the first > > from a list that makes the compilation works, regardless of whether the > > arguments are the best or not. =A0That list does not necessarily follow > > any principles that relates the arguments to the call, e.g. exact match > > or requiring fewer implicit coercions, etc. =A0It is just how they happen > > to be put on an internal list. > > > > As I recall that is not the case for function selection in the > interpreter. There is some heuristic which does attempt to assign a > "weight" based on the number of coercions and other factors. Yes, interpreter is quite different. It is not more reasonable: if there is valid selection of types compiler should find it (due to backtracking), but interpreter may miss it (because it commits early to the partial choice). > >  Sometimes compiler works too much to make sense of > >  user input, but IMHO this is not the case. > > > > Unfortunately, this is one of those cases. =A0We are lucky that it works > > at all; that is why it is voodoo. > > > > In your discussion you are talking about types of arguments but > function selection in Axiom also uses the return type. So the compiler > gives priority to any nullary function named Zero that returns the > proper type. No? Gaby is right here: all modemaps are considered in internal order. There is are hacks to prefer % to Rep, but I am not sure if they always work. Internal order depends on order of imports (including implicit imports), so in principle changing order of import statements you should be able to change obtained result. OTOH coercions done by compiler are of trival kind  unlike interpreter compiler will not automatically insert calls to 'coerce' (it will call 'autoCoerce' but this seem to be defined only for unions).  Waldek Hebisch hebisch@... 
From: Gabriel Dos Reis <gdr@cs...>  20111024 18:40:05

"Prof. Dr. Johannes Grabmeier" <johannes@...> writes:  thanks for the honor  or not: I am not the author of this domain.  OK, I will unregister the voodoo ownership. (but it was meant as honor :)  It is a "mutable domain"   )bo PUSH('ModMonic, $mutableDomains) Yes, but that is a different matter from having a representation (or not).  I used that, when we extended finite fields, along the lines of the  existing standard implemention at that time.  Gaby 
From: Gabriel Dos Reis <gdr@cs...>  20111024 18:36:58

Bill Page <bill.page@...> writes:  On Mon, Oct 24, 2011 at 1:02 PM, Gabriel Dos Reis wrote:  > ...  > Waldek Hebisch writes:  >  I would not call this voodoo: the compiler performs reasonable type  >  inference.  >  > There is nothing reasonable about it. The way that most AXIOM compilers  > do overload resolution (even in faces of ambiguity) is to pick the first  > from a list that makes the compilation works, regardless of whether the  > arguments are the best or not. That list does not necessarily follow  > any principles that relates the arguments to the call, e.g. exact match  > or requiring fewer implicit coercions, etc. It is just how they happen  > to be put on an internal list.  >   As I recall that is not the case for function selection in the  interpreter. There is some heuristic which does attempt to assign a  "weight" based on the number of coercions and other factors. modemap selection in compiler is different from modemap selection in the interpreter. I am currently discussing the compiler. You would be surprised to see all those places where the compiler just randomly picks the first modemap in a queue. (the interpreter is a different matter. I can't say which one is worse :)  >  Sometimes compiler works too much to make sense of  >  user input, but IMHO this is not the case.  >  > Unfortunately, this is one of those cases. We are lucky that it works  > at all; that is why it is voodoo.  >   In your discussion you are talking about types of arguments but  function selection in Axiom also uses the return type. So the compiler  gives priority to any nullary function named Zero that returns the  proper type. No? No. I think this part is getting off track. :)  Gaby 
From: Waldek Hebisch <hebisch@ma...>  20111024 18:17:13

Gabriel Dos Reis wrote: > > Waldek Hebisch <hebisch@...> writes: > >  Gabriel Dos Reis >  > >  > >  > Consider the definition of ModMonoid: >  > 8<8<8< >  > )abbrev domain MODMON ModMonic >  > ++ Description: >  > ++ This package \undocumented >  > >  > ModMonic(R,Rep): C == T >  > >  <snip> >  > Its description does not have a claim for "author", but the intersection >  > of authors of domains using this domain leaves me with Johannes Grabmeier :) >  > >  > >  > ModMonic is not a builtin domain, therefore one needs a definition of its >  > representation, i.e. a definition for "Rep", is needed. Yet, none is >  > provided. Rather, "Rep" here is specified as a parameter to the functor. >  > (That is not the same as defining it locally to some value) >  >  Hmm, I am not sure what difference makes defining: >  >  ModMonic(R,RepT): C == T >  >  and later >  >  Rep := RepT > > that is the brownie point (and what I did internally). > > There are fundamental differences. First, because of the principle of > abstraction, parameter names are and should be immaterial. Surely, you > do not want your functions or constructors to start behavingly > differently just because you happen to consistently rename its parameters. In loose sense yes. But I do not expect to be able to use 'for' as a name of parameter, in general languagedefined identifiers may carry special meaning. It is good to limit number of such special identifiers but they have their place in the language. Concerning 'Rep' specifically, shadowing builtion meaning would be worse. Signalling error is reasonable, but I do not see it as clearly superior to current behaviour. >  BTW: AFAICS there is no need to have Rep at all  all Rep does is >  allowing magic coercions between % and Rep. > > Let me clarify. > > There ought to be a way of saying what the representation domain is. > The AXIOM book documents that you need the "special variable Rep", as > stated in section 13.6 titled "Representation". The official grammar in > section 13.2 (page 528) lists assignment to Rep as the first thing. 13.6 says 'uses the special variable Rep to identify the lower level data type ...'. It does not say that you have to 'identify the lower level data type ...'. 13.2 says 'recommended format', again no indication that Rep is mandatory. My reading of Davenport paper is that actual represention is by design untyped. In particular one can provide creation functions and operations in lowerlevel language  consitency of such operations with representation is responsibility of implementer, _not_ of Spad compiler. Similarely, one can implement creation functions and operations in Spad and use 'pretend' to switch view between '%' and actual representation domain. Of course, you may wish to have more strict rules about representation, but this is language change. >  > Now, consider the capsulelevel variable "power". It is declared as >  > >  > power:PrimitiveArray(%) >  > >  > then later assigned to as >  > >  > power := new(0,0) >  > >  > There are two lexical occurences of the literal '0' in there. Can you >  > guess, which one is which? There are at least five interpretations for >  > each constant: >  > >  > 0: R  the parameter R satisfies Ring >  > 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R) >  > 0: %  the current domains satisfies same >  > 0: NonNegativeInteger >  > 0: Integer >  > >  >  Well, 'power' is declared to be of type 'PrimitiveArray(%)' so 'new' >  should produce 'PrimitiveArray(%)' and compiler searches for it >  in 'PrimitiveArray(%)'. And indeed, in 'PrimitiveArray(S)' we >  have: >  >  new : (NonNegativeInteger, S) > % >  >  So the first argument to 'new' must be 'NonNegativeInteger' and the >  second must be '%'. > > 1. new, expects its second *argument* to be of type %. It does not > require that there be no implicit coercion between the argument > as lexically written in the source code, and the actual code > generated for that argument. If one thinks that the mere presence of > the parameter "Rep" indicates that is the representation domain, > therefore the implicit coercion from Rep to % is OK, then 0@... is > a good viable candidate. > > 2. Fortunately, in this case, 0@% is also defined explicitly to be > 0$Rep, but there is no requirement that be the case. And when > it is not, we get a problem. Actually 13.6 says that '%' take precedence over 'Rep', so this one is excluded. > 3. ModMonic(R,Rep) satisfies UnivariatePolynomialCategory(R), so that > means that there is alsoanother implicit coercion that turns > 0@... into a legitimate value of type %. > > 4. Similar reasoning holds for 0@... because % satisfies Ring, > and there is an implicit coercion from Integer to any domain that > satisfies Ring. > > 5. Since NonNegativeInteger is a subdomain of Integer, it also > provides an implicit coercion. > > So, in fact if one thinks that the mere presense of the parameter Rep is > sufficient to indicate representation domain and therefore implicit > coercions, then we have a legitimate case of ambiguity. OK, if you think about exact operations used to produce 0, then there is really ambiguity. However, IMO coercions are supposed to be homomorphims, so each of ways should lead to 0 in '%'. Sure, in general current selection mechanism is unsafe, but in case of 0 and 1 I would try to preserve it if possible.  Waldek Hebisch hebisch@... 
From: Bill Page <bill.page@ne...>  20111024 18:15:41

On Mon, Oct 24, 2011 at 1:02 PM, Gabriel Dos Reis wrote: > ... > Waldek Hebisch writes: >  I would not call this voodoo: the compiler performs reasonable type >  inference. > > There is nothing reasonable about it. The way that most AXIOM compilers > do overload resolution (even in faces of ambiguity) is to pick the first > from a list that makes the compilation works, regardless of whether the > arguments are the best or not. That list does not necessarily follow > any principles that relates the arguments to the call, e.g. exact match > or requiring fewer implicit coercions, etc. It is just how they happen > to be put on an internal list. > As I recall that is not the case for function selection in the interpreter. There is some heuristic which does attempt to assign a "weight" based on the number of coercions and other factors. >  Sometimes compiler works too much to make sense of >  user input, but IMHO this is not the case. > > Unfortunately, this is one of those cases. We are lucky that it works > at all; that is why it is voodoo. > In your discussion you are talking about types of arguments but function selection in Axiom also uses the return type. So the compiler gives priority to any nullary function named Zero that returns the proper type. No? Regards, Bill Page. 
From: Gabriel Dos Reis <gdr@cs...>  20111024 17:02:56

Waldek Hebisch <hebisch@...> writes:  Gabriel Dos Reis  >  >  > Consider the definition of ModMonoid:  > 8<8<8<  > )abbrev domain MODMON ModMonic  > ++ Description:  > ++ This package \undocumented  >  > ModMonic(R,Rep): C == T  >  <snip>  > Its description does not have a claim for "author", but the intersection  > of authors of domains using this domain leaves me with Johannes Grabmeier :)  >  >  > ModMonic is not a builtin domain, therefore one needs a definition of its  > representation, i.e. a definition for "Rep", is needed. Yet, none is  > provided. Rather, "Rep" here is specified as a parameter to the functor.  > (That is not the same as defining it locally to some value)   Hmm, I am not sure what difference makes defining:   ModMonic(R,RepT): C == T   and later   Rep := RepT that is the brownie point (and what I did internally). There are fundamental differences. First, because of the principle of abstraction, parameter names are and should be immaterial. Surely, you do not want your functions or constructors to start behavingly differently just because you happen to consistently rename its parameters.  but IMHO passing Rep as argument is resonable shortcut for the above. There is a well established practice and programming technique of passing the representation as a parameter (or the subdomain or the base domain) as a parameter. They are not just called "Rep" :)  If there are differences in behaviour I would rather change compiler  so that they agree.   BTW: AFAICS there is no need to have Rep at all  all Rep does is  allowing magic coercions between % and Rep. Let me clarify. There ought to be a way of saying what the representation domain is. The AXIOM book documents that you need the "special variable Rep", as stated in section 13.6 titled "Representation". The official grammar in section 13.2 (page 528) lists assignment to Rep as the first thing. Aldor thinks of "Rep" as a distinguished *constant*, not a parameter. Speaking of the "magic coercions", if you write in the original AXIOM Rep == RepT instead of Rep := RepT you would not get the same thing, and the domain will not compile. Consequently, you need Rep in practice in AXIOM and Aldor. [the reason why the '==' version won't work is that the compiler would think it is a macro form, therefore won't give Rep an abstract definition that it gives to all parameters, and when it comes back later to ask whether there was a definition of Rep, it won't see it. A compiler implementation detail leaks out. ] In a different version of AXIOM, one may think of different way of specifying what the representation domain is; but there needs to be a way to say what the representation domain is. The distinction (or lack thereof) between Rep and % is what causes miscompilation in some old AXIOMs programs (as we discussed recently) where an infinite recursion is introduced, and therefore forces explicit $Rep. Aldor does not have that problem.  > Now, consider the capsulelevel variable "power". It is declared as  >  > power:PrimitiveArray(%)  >  > then later assigned to as  >  > power := new(0,0)  >  > There are two lexical occurences of the literal '0' in there. Can you  > guess, which one is which? There are at least five interpretations for  > each constant:  >  > 0: R  the parameter R satisfies Ring  > 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R)  > 0: %  the current domains satisfies same  > 0: NonNegativeInteger  > 0: Integer  >   Well, 'power' is declared to be of type 'PrimitiveArray(%)' so 'new'  should produce 'PrimitiveArray(%)' and compiler searches for it  in 'PrimitiveArray(%)'. And indeed, in 'PrimitiveArray(S)' we  have:   new : (NonNegativeInteger, S) > %   So the first argument to 'new' must be 'NonNegativeInteger' and the  second must be '%'. 1. new, expects its second *argument* to be of type %. It does not require that there be no implicit coercion between the argument as lexically written in the source code, and the actual code generated for that argument. If one thinks that the mere presence of the parameter "Rep" indicates that is the representation domain, therefore the implicit coercion from Rep to % is OK, then 0@... is a good viable candidate. 2. Fortunately, in this case, 0@% is also defined explicitly to be 0$Rep, but there is no requirement that be the case. And when it is not, we get a problem. 3. ModMonic(R,Rep) satisfies UnivariatePolynomialCategory(R), so that means that there is alsoanother implicit coercion that turns 0@... into a legitimate value of type %. 4. Similar reasoning holds for 0@... because % satisfies Ring, and there is an implicit coercion from Integer to any domain that satisfies Ring. 5. Since NonNegativeInteger is a subdomain of Integer, it also provides an implicit coercion. So, in fact if one thinks that the mere presense of the parameter Rep is sufficient to indicate representation domain and therefore implicit coercions, then we have a legitimate case of ambiguity. Think about it.  > That this domain compiles at all is mysterious; it happens to depend on  > a very obscure implementation detail of AXIOM compilers, one that is not  > advertised at all  and I don't think it should.  > It is voodoo. So, I am calling it Johannes's Rep voodoo :).   I would not call this voodoo: the compiler performs reasonable type  inference. There is nothing reasonable about it. The way that most AXIOM compilers do overload resolution (even in faces of ambiguity) is to pick the first from a list that makes the compilation works, regardless of whether the arguments are the best or not. That list does not necessarily follow any principles that relates the arguments to the call, e.g. exact match or requiring fewer implicit coercions, etc. It is just how they happen to be put on an internal list.  Sometimes compiler works too much to make sense of  user input, but IMHO this is not the case. Unfortunately, this is one of those cases. We are lucky that it works at all; that is why it is voodoo.  Gaby 
From: Waldek Hebisch <hebisch@ma...>  20111024 14:57:39

Gabriel Dos Reis > > > Consider the definition of ModMonoid: > 8<8<8< > )abbrev domain MODMON ModMonic > ++ Description: > ++ This package \undocumented > > ModMonic(R,Rep): C == T > <snip> > Its description does not have a claim for "author", but the intersection > of authors of domains using this domain leaves me with Johannes Grabmeier :) > > > ModMonic is not a builtin domain, therefore one needs a definition of its > representation, i.e. a definition for "Rep", is needed. Yet, none is > provided. Rather, "Rep" here is specified as a parameter to the functor. > (That is not the same as defining it locally to some value) Hmm, I am not sure what difference makes defining: ModMonic(R,RepT): C == T and later Rep := RepT but IMHO passing Rep as argument is resonable shortcut for the above. If there are differences in behaviour I would rather change compiler so that they agree. BTW: AFAICS there is no need to have Rep at all  all Rep does is allowing magic coercions between % and Rep. > Now, consider the capsulelevel variable "power". It is declared as > > power:PrimitiveArray(%) > > then later assigned to as > > power := new(0,0) > > There are two lexical occurences of the literal '0' in there. Can you > guess, which one is which? There are at least five interpretations for > each constant: > > 0: R  the parameter R satisfies Ring > 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R) > 0: %  the current domains satisfies same > 0: NonNegativeInteger > 0: Integer > Well, 'power' is declared to be of type 'PrimitiveArray(%)' so 'new' should produce 'PrimitiveArray(%)' and compiler searches for it in 'PrimitiveArray(%)'. And indeed, in 'PrimitiveArray(S)' we have: new : (NonNegativeInteger, S) > % So the first argument to 'new' must be 'NonNegativeInteger' and the second must be '%'. > > That this domain compiles at all is mysterious; it happens to depend on > a very obscure implementation detail of AXIOM compilers, one that is not > advertised at all  and I don't think it should. > It is voodoo. So, I am calling it Johannes's Rep voodoo :). I would not call this voodoo: the compiler performs reasonable type inference. Sometimes compiler works too much to make sense of user input, but IMHO this is not the case.  Waldek Hebisch hebisch@... 
From: Gabriel Dos Reis <gdr@cs...>  20111024 14:21:34

Bill Page <bill.page@...> writes:  On Mon, Oct 24, 2011 at 8:54 AM, Gabriel Dos Reis <gdr@...> wrote:  > ...  > Now, consider the capsulelevel variable "power". It is declared as  >  > power:PrimitiveArray(%)  >  > then later assigned to as  >  > power := new(0,0)  >  > There are two lexical occurences of the literal '0' in there. Can you  > guess, which one is which? There are at least five interpretations for  > each constant:  >  > 0: R  the parameter R satisfies Ring  > 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R)  > 0: %  the current domains satisfies same  > 0: NonNegativeInteger  > 0: Integer  >  >  > That this domain compiles at all is mysterious; it happens to depend on  > a very obscure implementation detail of AXIOM compilers, one that is not  > advertised at all  and I don't think it should.  > It is voodoo. So, I am calling it Johannes's Rep voodoo :).  >   I think that originally in Axiom the assignment above would be treated  like this:   power := new(Zero(),Zero())   So 0 would be resolved by the standard mechanism of function  selection, right? That is correct. But, there is nothing special to selecting via function or anthing else  in fact there are two routines in all AXIOM systems to do the selection; they all try very hard to do the same thing. However, how the selection in internally done is not the issue. It is what should be selected, and why. Because that is what is ultimatelly going to be explained to users.  I rather like this approach and sometimes wonder how  it could be extended to all constants. It is not the approach of selection (the compiler internal implementation) that is at issue. It is the meaning of that domain. Once we have established what the meaning should be, then we can see whether we can convince the compiler to do it.  If I understand correctly recently you have submitted some patches  that begin to remove the special treatment of constants 0 and 1 as  unary functions Zero and One. That is correct. 0 and 1 are not the only constants in the universe. One should be able to define 2 or 3 or red as constants too. And the selection mechanism should be the same. But, that isn't the issue here. The primary problem is: what is the representation of domains instantiated from ModMonic?  This seems to be going in the other direction.   Comment? The issue has nothing to do with how the selection is being implemented; but what should be selected, and why. The real problem is: what is the representation domain of ModMonic?  Gaby 
From: Bill Page <bill.page@ne...>  20111024 13:56:52

On Mon, Oct 24, 2011 at 8:54 AM, Gabriel Dos Reis <gdr@...> wrote: > ... > Now, consider the capsulelevel variable "power". It is declared as > > power:PrimitiveArray(%) > > then later assigned to as > > power := new(0,0) > > There are two lexical occurences of the literal '0' in there. Can you > guess, which one is which? There are at least five interpretations for > each constant: > > 0: R  the parameter R satisfies Ring > 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R) > 0: %  the current domains satisfies same > 0: NonNegativeInteger > 0: Integer > > > That this domain compiles at all is mysterious; it happens to depend on > a very obscure implementation detail of AXIOM compilers, one that is not > advertised at all  and I don't think it should. > It is voodoo. So, I am calling it Johannes's Rep voodoo :). > I think that originally in Axiom the assignment above would be treated like this: power := new(Zero(),Zero()) So 0 would be resolved by the standard mechanism of function selection, right? I rather like this approach and sometimes wonder how it could be extended to all constants. If I understand correctly recently you have submitted some patches that begin to remove the special treatment of constants 0 and 1 as unary functions Zero and One. This seems to be going in the other direction. Comment? Regards, Bill Page. 
From: Gabriel Dos Reis <gdr@cs...>  20111024 12:54:09

Consider the definition of ModMonoid: 8<8<8< )abbrev domain MODMON ModMonic ++ Description: ++ This package \undocumented ModMonic(R,Rep): C == T where R: Ring Rep: UnivariatePolynomialCategory(R) C == Join(UnivariatePolynomialCategory(R),CoercibleFrom Rep) with operations setPoly : Rep > Rep ++ setPoly(x) \undocumented modulus : > Rep ++ modulus() \undocumented reduce: Rep > % ++ reduce(x) \undocumented lift: % > Rep reduce lift = identity ++ lift(x) \undocumented Vectorise: % > Vector(R) ++ Vectorise(x) \undocumented UnVectorise: Vector(R) > % ++ UnVectorise(v) \undocumented An: % > Vector(R) ++ An(x) \undocumented pow : > PrimitiveArray(%) ++ pow() \undocumented computePowers : > PrimitiveArray(%) ++ computePowers() \undocumented if R has FiniteFieldCategory then frobenius: % > % ++ frobenius(x) \undocumented LinearTransf: (%,Vector(R)) > SquareMatrix<deg> R assertions if R has Finite then Finite T == add constants m:Rep := monomial(1,1)$Rep  degree(m) > 0 and LeadingCoef(m) = R$1 d := degree(m)$Rep d1 := (d1):NonNegativeInteger twod := 2*d1+1 frobenius?:Boolean := R has FiniteFieldCategory VectorRep:= DirectProduct(d:NonNegativeInteger,R) declarations x,y: % p: Rep d,n: Integer e,k1,k2: NonNegativeInteger c: R vect: Vector(R) power:PrimitiveArray(%) frobeniusPower:PrimitiveArray(%) computeFrobeniusPowers : () > PrimitiveArray(%) representations mutable m take this out?? define power := new(0,0) frobeniusPower := new(0,0) setPoly (mon : Rep) == mon =$Rep m => mon oldm := m not one? leadingCoefficient mon => error "polynomial must be monic"  following copy code needed since FFPOLY can modify mon copymon:Rep:= 0 while not zero? mon repeat copymon := monomial(leadingCoefficient mon, degree mon)$Rep + copymon mon := reductum mon m := copymon d := degree(m)$Rep d1 := (d1)::NonNegativeInteger twod := 2*d1+1 power := computePowers() if frobenius? then degree(oldm)>1 and not((oldm exquo$Rep m) case "failed") => for i in 1..d1 repeat frobeniusPower(i) := reduce lift frobeniusPower(i) frobeniusPower := computeFrobeniusPowers() m modulus == m if R has Finite then size == d * size()$R random == UnVectorise([random()$R for i in 0..d1]) 0 == 0$Rep 1 == 1$Rep c * x == c *$Rep x n * x == (n::R) *$Rep x coerce(c:R):% == monomial(c,0)$Rep coerce(x:%):OutputForm == coerce(x)$Rep coefficient(x,e):R == coefficient(x,e)$Rep reductum(x) == reductum(x)$Rep leadingCoefficient x == (leadingCoefficient x)$Rep degree x == (degree x)$Rep lift(x) == x pretend Rep reduce(p) == (monicDivide(p,m)$Rep).remainder coerce(p) == reduce(p) x = y == x =$Rep y x + y == x +$Rep y  x == $Rep x x * y == p := x *$Rep y ans:=0$Rep while (n:=degree p)>d1 repeat ans:=ans + leadingCoefficient(p)*power.(nd) p := reductum p ans+p Vectorise(x) == [coefficient(lift(x),i) for i in 0..d1] UnVectorise(vect) == reduce(+/[monomial(vect.(i+1),i) for i in 0..d1]) computePowers == mat : PrimitiveArray(%):= new(d,0) mat.0:= reductum(m)$Rep w: % := monomial$Rep (1,1) for i in 1..d1 repeat mat.i := w *$Rep mat.(i1) if degree mat.i=d then mat.i:= reductum mat.i + leadingCoefficient mat.i * mat.0 mat if frobenius? then computeFrobeniusPowers() == mat : PrimitiveArray(%):= new(d,1) mat.1:= mult := monomial(1, size()$R)$% for i in 2..d1 repeat mat.i := mult * mat.(i1) mat frobenius(a:%):% == aq:% := 0 while not zero? a repeat aq:= aq + leadingCoefficient(a)*frobeniusPower(degree a) a := reductum a aq pow == power monomial(c,e)== if e<d then monomial(c,e)$Rep else if e<=twod then c * power.(ed) else k1:=e quo twod k2 := (ek1*twod)::NonNegativeInteger reduce((power.d1 **k1)*monomial(c,k2)) if R has Field then (x:% exquo y:%):Union(%, "failed") == uv := extendedEuclidean(y, modulus(), x)$Rep uv case "failed" => "failed" return reduce(uv.coef1) recip(y:%):Union(%, "failed") == 1 exquo y divide(x:%, y:%) == (q := (x exquo y)) case "failed" => error "not divisible" [q, 0]  An(MM) == Vectorise((reduce(reductum(m))::MM))  LinearTransf(vect,MM) ==  ans:= 0::SquareMatrix<d>(R)  for i in 1..d do setelt(ans,i,1,vect.i)  for j in 2..d do  setelt(ans,1,j, elt(ans,d,j1) * An(MM).1)  for i in 2..d do  setelt(ans,i,j, elt(ans,i1,j1) + elt(ans,d,j1) * An(MM).i)  ans 8<8<8< Its description does not have a claim for "author", but the intersection of authors of domains using this domain leaves me with Johannes Grabmeier :) ModMonic is not a builtin domain, therefore one needs a definition of its representation, i.e. a definition for "Rep", is needed. Yet, none is provided. Rather, "Rep" here is specified as a parameter to the functor. (That is not the same as defining it locally to some value) Now, consider the capsulelevel variable "power". It is declared as power:PrimitiveArray(%) then later assigned to as power := new(0,0) There are two lexical occurences of the literal '0' in there. Can you guess, which one is which? There are at least five interpretations for each constant: 0: R  the parameter R satisfies Ring 0: Rep  the parameter Rep satisfies UnivariatePolynomialCategory(R) 0: %  the current domains satisfies same 0: NonNegativeInteger 0: Integer That this domain compiles at all is mysterious; it happens to depend on a very obscure implementation detail of AXIOM compilers, one that is not advertised at all  and I don't think it should. It is voodoo. So, I am calling it Johannes's Rep voodoo :). Brownie point to anyone who untangles it not to use the voodoo. NB: I ran into this domain while working on a completely different issue, one that related to fixing several shortcomings in the way constants are processed in many AXIOM systems.  Gaby 
From: Martin Baker <ax87438@ma...>  20111023 07:17:12

>  However this would not be compatible with existing PropositionalFormula >  and it would not be closed. That is I would like: >  PropositionalFormula Product(A,B) >  PropositionalFormula Sum(A,B) >  PropositionalFormula Exponent(A,B) >  all to be treated as: PropositionalFormula SetCategory >  Can that be done in a way that is compatible with SPAD static typing. > > SetCategory is a category, not a domain, so is not appropriate argument > for PropositionalFormula. Categories cannot be constructor arguments  > all AXIOM flavours affected. > > In OpenAxiom, you use the domain Domain, so you would get something like > > PropositionalFormula Domain > > which is probably what you want. Gaby, The Domain domain has minimal documentation (about 2 lines of inline comments for each public function), I can't find anything about: why it was created? how its intended to be used? and so on. Most of the functions call Lisp code so there is not many clues there. I am guessing its part of the universal algebra stuff you mentioned before? Is this all intended to be part of a meta model of OpenAxiom? Will it allow introspection and dynamic code creation? Is there any further documentation about this? I get the impression that the universal algebra stuff is potentially very powerful but I am very reluctant to use something that is only available on one flavor of axiom, are other flavors of Axiom planning to implement this functionality? Have I missed any documentation about this? Martin 