--* From BMT%WATSON.vnet.ibm.com@yktvmh.watson.ibm.com  Tue Apr 13 15:17:56 1993
--* Received: from yktvmh.watson.ibm.com by radical.watson.ibm.com (AIX 3.2/UCB 5.64/900524)
--*           id AA25530; Tue, 13 Apr 1993 15:17:56 -0400
--* Received: from watson.vnet.ibm.com by yktvmh.watson.ibm.com (IBM VM SMTP V2R3)
--*    with BSMTP id 5969; Tue, 13 Apr 93 15:17:57 EDT
--* Received: from YKTVMH by watson.vnet.ibm.com with "VAGENT.V1.0"
--*           id <A.BMT.NOTE.VAGENT2.5641.Apr.13.15:17:16.-0400>
--*           for asbugs@watson; Tue, 13 Apr 93 15:17:46 -0400
--* Received: from YKTVMH by watson.vnet.ibm.com with "VAGENT.V1.0"
--*           id 5630; Tue, 13 Apr 1993 15:17:16 EDT
--* Received: from cyst.watson.ibm.com by yktvmh.watson.ibm.com (IBM VM SMTP V2R3)
--*    with TCP; Tue, 13 Apr 93 15:16:12 EDT
--* Received: from spadserv.watson.ibm.com by cyst.watson.ibm.com (AIX 1.3/900528)
--*   id AA26248; Tue, 13 Apr 93 15:16:06 -0400
--* Received: by spadserv.watson.ibm.com (AIX 3.2/UCB 5.64/900524)
--*           id AA18064; Tue, 13 Apr 1993 15:06:41 -0400
--* Date: Tue, 13 Apr 1993 15:06:41 -0400
--* From: bmt@spadserv.watson.ibm.com
--* X-External-Networks: yes
--* Message-Id: <9304131906.AA18064@spadserv.watson.ibm.com>
--* To: asbugs@watson.ibm.com
--* Subject: bogus compiler error when redefining function sup from add [dirprod2.as][27.6 (current)]

--@ Fixed  by:  SSD   Wed Oct 20 12:16:31 1993 
--@ Tested by:  none 
--@ Summary:    Same as bug259. GradedDirectProduct and LexicographicDirectProduct had the same signature. 


#include "aslib.as"
macro SI == SingleInteger
macro S == SingleInteger
OrderedDirectProduct(dim:SI,lessThan?:(Array(S),Array(S)) -> Bit ):with
   Object
   Ordered
   Arithmetic
   sup: (%, %) -> %
   sum: % -> S
   nonNegative?: % -> Bit
   vector: Tuple S -> %
   apply: (%, SI)    -> S

 == add
   Rep ==> Array(S)
   import Rep
   import S
   map(f:S-> S, v: %):% ==
         vv:Rep := new(dim,0)
         for i: SI in 1..dim repeat
            set!(vv, i, f apply(v,i))
         per vv

   map(f:(S,S) -> S, v1:%, v2:%) :% ==
         vv:Rep := new(dim,0)
         for i: SI in 1..dim repeat
            set!(vv, i, f(apply(v1,i), apply(v2,i)))
         per vv

   vector(ts : Tuple S): % == per array ts

   0:% == per new(dim,0)
   1:% == per new(dim,1)
   (v1:% = v2:%):Bit == rep(v1) = rep(v2)
   (v1:% ~= v2:%):Bit == rep(v1) ~= rep(v2)
   (v1:% < v2:%):Bit == lessThan?(rep(v1), rep(v2))
   (v1:% > v2:%):Bit == v2 < v1
   (v1:% <= v2:%):Bit == not(v2 < v1)
   (v1:% >= v2:%):Bit == not(v1 < v2)

   (v1:% + v2:%):% == map(+, v1, v2)
   (v1:% - v2:%):% == map(-, v1, v2)
   (- v:%):% == map(-, v)
   sum(v:%):S ==
      s:S:=0
      for vv in rep v repeat s := s+vv
      s
   sup(v1:%, v2:%):% ==
     map((%1:S,%2:S):S +-> if %1<%2 then %2 else %1, v1, v2)
   apply(v:%, s:SI):S == rep(v).s
   nonNegative?(v:%):Bit ==
      for i:SI in 1..dim repeat
        if v(i)<0 then return false
      true
   apply(p:Outport, v:%):Outport == p(rep v)


macro
  OrderedAbelianMonoid == with
     Object
     Ordered
     Arithmetic
  Boolean == Bit
  qelt == apply
  VS   == Array SS
OrderingFunctions(dim:SI,SS:OrderedAbelianMonoid): with

     pureLex    :  (VS,VS)  -> Boolean
     totalLex   :  (VS,VS)  -> Boolean
     reverseLex :  (VS,VS)  -> Boolean
     gradRevLex :  (VS,VS)  -> Boolean

  == add
    import SS
    n:SI:=dim

 -- pure lexicographical ordering
    pureLex(v1:VS,v2:VS) : Boolean ==
      for i in 1..n repeat
        if qelt(v1,i) < qelt(v2,i) then return true
        if qelt(v2,i) < qelt(v1,i) then return false
      false

 -- total ordering refined with lex
    totalLex(v1:VS,v2:VS) :Boolean ==
      n1:SS:=0
      n2:SS:=0
      for i in 1..n repeat
        n1:= n1+qelt(v1,i)
        n2:=n2+qelt(v2,i)
      n1<n2 => true
      n2<n1 => false
      for i in 1..n repeat
        if qelt(v1,i) < qelt(v2,i) then return true
        if qelt(v2,i) < qelt(v1,i) then return false
      false

 -- reverse lexicographical ordering
    reverseLex(v1:VS,v2:VS) :Boolean ==
      n1:SS:=0
      n2:SS:=0
      for i in 1..n repeat
        n1:= n1+qelt(v1,i)
        n2:=n2+qelt(v2,i)
      n1<n2 => true
      n2<n1 => false
      for i in n..1 by -1 repeat
        if qelt(v2,i) < qelt(v1,i) then return true
        if qelt(v1,i) < qelt(v2,i) then return false
      false

 -- reverse lexicographical ordering assuming total degree in first position
    gradRevLex(v1:VS,v2:VS) :Boolean ==
      n1:= qelt(v1,1)
      n2:= qelt(v2,1)
      n1<n2 => true
      n2<n1 => false
      for i in n..2 by -1 repeat
        if qelt(v2,i) < qelt(v1,i) then return true
        if qelt(v1,i) < qelt(v2,i) then return false
      false

HomogeneousDirectProduct(dim:SI):with
   Object
   Ordered
   Arithmetic
   sup: (%, %) -> %
   sum: % -> SI
   nonNegative?: % -> Bit
   vector: Tuple SI -> %
   apply: (%, SI)    -> SI
 ==
  OrderedDirectProduct(dim,reverseLex$OrderingFunctions(dim,SI)) add

GradedDirectProduct(dim:SI):with
   Object
   Ordered
   Arithmetic
   sup: (%, %) -> %
   sum: % -> SI
   nonNegative?: % -> Bit
   vector: Tuple SI -> %
   apply: (%, SI)    -> SI
 ==
  OrderedDirectProduct(dim+1,gradRevLex$OrderingFunctions(dim,SI)) add
     Rep ==>  OrderedDirectProduct(dim+1,gradRevLex$OrderingFunctions(dim,SI))
     import Rep
     sup(e1:%, e2:%):% ==
        re := sup( rep e1, rep e2)
        s := sum(re) - re.1
        v:Array(SI) := re pretend Array(SI)
        v.1 := s
        v pretend %

LexicographicDirectProduct(dim:SI):with
   Object
   Ordered
   Arithmetic
   sup: (%, %) -> %
   sum: % -> SI
   nonNegative?: % -> Bit
   vector: Tuple SI -> %
   apply: (%, SI)    -> SI
 ==
  OrderedDirectProduct(dim,pureLex$OrderingFunctions(dim,SI)) add



 
