--* From postmaster%watson.vnet.ibm.com@yktvmv.watson.ibm.com  Sat Nov 19 19:37:34 1994
--* Received: from yktvmv-ob.watson.ibm.com by asharp.watson.ibm.com (AIX 3.2/UCB 5.64/930311)
--*           id AA19362; Sat, 19 Nov 1994 19:37:34 -0500
--* Received: from watson.vnet.ibm.com by yktvmv.watson.ibm.com (IBM VM SMTP V2R3)
--*    with BSMTP id 0537; Sat, 19 Nov 94 19:37:40 EST
--* Received: from YKTVMV by watson.vnet.ibm.com with "VAGENT.V1.0"
--*           id <A.ADK.NOTE.YKTVMV.5685.Nov.19.19:37:40.-0500>
--*           for asbugs@watson; Sat, 19 Nov 94 19:37:40 -0500
--* Received: from ibm4.scri.fsu.edu by watson.ibm.com (IBM VM SMTP V2R3) with TCP;
--*    Sat, 19 Nov 94 19:37:39 EST
--* Received: by ibm4.scri.fsu.edu id AA31273
--*   (5.67b/IDA-1.4.4 for asbugs@watson.ibm.com); Sat, 19 Nov 1994 19:37:31 -0500
--* Date: Sat, 19 Nov 1994 19:37:31 -0500
--* From: Tony Kennedy <adk@ibm4.scri.fsu.edu>
--* Message-Id: <199411200037.AA31273@ibm4.scri.fsu.edu>
--* To: asbugs@watson.ibm.com
--* Subject: [2] Self-ambiguity, strange error messages

--@ Fixed  by:  SSD   Wed Jan 11 09:08:45 EST 1995 
--@ Tested by:  none 
--@ Summary:    Type inference fixes in r1-0-2 now prevent duplicate meaning messages. See '!!' comments for other fixes. 

-- Command line: asharp -v -Fx perm.as > perm.error
-- Version: 0.37.0
-- Original bug file name: perm.as

--+ A# version 0.37.0 for AIX RS/6000
--+ "perm.as", line 27:
--+     print << "Constructing domain Permutation(" << n << ")" << newline
--+ ................................................^
--+ [L27 C49] #4 (Error) There are 2 meanings for `<<' in this context.
--+ The possible types were:
--+ 	  <<: (TextWriter, SingleInteger) -> TextWriter from SingleInteger
--+ 	  <<: (TextWriter, SingleInteger) -> TextWriter from SingleInteger
--+   The context requires an expression of type (TextWriter, SingleInteger) -> TextWriter.
--+
--+ "perm.as", line 32:     1: % == per [ i for i in 1 .. n ]
--+                     ....................^........^.^
--+ [L32 C21] #5 (Error) (After Macro Expansion) There are 2 meanings for `generator' in this context.
--+ The possible types were:
--+ 	  generator: ClosedSegment(SingleInteger) -> Generator(SingleInteger) from Segment(SingleInteger)
--+ 	  generator: ClosedSegment(SingleInteger) -> Generator(SingleInteger) from Segment(SingleInteger)
--+   The context requires an expression of type ClosedSegment(SingleInteger) -> Generator(SingleInteger).
--+ Expanded expression was: generator
--+ [L32 C30] #7 (Error) (After Macro Expansion) There are 2 meanings for `1' in this context.
--+ The possible types were:
--+ 	  1: SingleInteger from SingleInteger
--+ 	  1: SingleInteger from SingleInteger
--+   The context requires an expression of type SingleInteger.
--+ Expanded expression was: 1
--+ [L32 C32] #6 (Error) (After Macro Expansion) There are 2 meanings for `..' in this context.
--+ The possible types were:
--+ 	  ..: (SingleInteger, SingleInteger) -> ClosedSegment(SingleInteger) from Segment(SingleInteger)
--+ 	  ..: (SingleInteger, SingleInteger) -> ClosedSegment(SingleInteger) from Segment(SingleInteger)
--+   The context requires an expression of type (SingleInteger, SingleInteger) -> ClosedSegment(SingleInteger).
--+ Expanded expression was: ..
--+
--+ "perm.as", line 38:
--+       length t ~= n => error("Bad permutation: wrong number of values")
--+ ...............^
--+ [L38 C16] #8 (Error) There are 2 meanings for `~=' in this context.
--+ The possible types were:
--+ 	  ~=: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+ 	  ~=: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+   The context requires an expression of type (SingleInteger, SingleInteger) -> Boolean.
--+
--+ "perm.as", line 43:
--+         i < 1 or i > n => error("Bad permutation: value out of range")
--+ ..........^.^
--+ [L43 C11] #9 (Error) There are 2 meanings for `<' in this context.
--+ The possible types were:
--+ 	  <: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+ 	  <: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+   The context requires an expression of type (SingleInteger, SingleInteger) -> Boolean.
--+ [L43 C13] #10 (Error) There are 2 meanings for `1' in this context.
--+ The possible types were:
--+ 	  1: SingleInteger from SingleInteger
--+ 	  1: SingleInteger from SingleInteger
--+   The context requires an expression of type SingleInteger.
--+
--+ "perm.as", line 59:       if j < 1 or j > n
--+                     ...........^.^......^
--+ [L59 C12] #1 (Error) There are 2 meanings for `<' in this context.
--+ The possible types were:
--+ 	  <: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+ 	  <: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+   The context requires an expression of type (SingleInteger, SingleInteger) -> Boolean.
--+ [L59 C14] #2 (Error) There are 2 meanings for `1' in this context.
--+ The possible types were:
--+ 	  1: SingleInteger from SingleInteger
--+ 	  1: SingleInteger from SingleInteger
--+   The context requires an expression of type SingleInteger.
--+ [L59 C21] #3 (Error) There are 2 meanings for `>' in this context.
--+ The possible types were:
--+ 	  >: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+ 	  >: (SingleInteger, SingleInteger) -> Boolean from SingleInteger
--+   The context requires an expression of type (SingleInteger, SingleInteger) -> Boolean.
--+ [L59 C21] #11 (Fatal Error) Too many errors (use `-M emax=n' or `-M no-emax' to change the limit).
--+
#include "aslib.as"
#pile

macro SI == SingleInteger

-- `Permutation' is a domain of permutations.
--
-- Author: ADK
-- Date Created: 13-JUL-1993 22:06:19.00
-- Modifications: 19-NOV-1994 19:12:49.00 (ADK) Modify for A# V0.37.0

Permutation(n: SI): Join(Group, Finite) with
    bracket: Tuple SI -> %		++ Construct a permutation
    coerce: Tuple SI -> %		++ Construct a permutation
    coerce: Cycle n -> %		++ Construct a permutation
    apply: (%, SI) -> SI		++ Cayley action

  == add

    macro Rep == Array SI

    import from Rep, String, Segment SI

    default
      i: SI

    print << "Constructing domain Permutation(" << n << ")" << newline

    #: Integer == coerce n
    sample: % == 1 -- Why do I need this instead of the category default?
    --!! Because the default is in AbelianMonoid, but not Monoid.

    --!! Added a missing export.
    ( a: % ) ^ ( b: Integer ) : % == error "not implemented"

    1: % == per [ i for i in 1 .. n ]

    ( a: % ) = ( b: % ) : Boolean == (rep a) = (rep b)
    ( a: % ) ~= ( b: % ) : Boolean == ~(a = b)

    [t: Tuple SI]: % ==
      length t ~= n => error("Bad permutation: wrong number of values")
      local
        r: Array Boolean == new(n, false)
        s: Boolean := true
      for i in [t] repeat
	i < 1 or i > n => error("Bad permutation: value out of range")
        r.i := true
      for b: Boolean in r while s repeat s := s and b
      ~s => error("Bad permutation: not all values specified")
      per [t]

    coerce(t: Tuple SI): % == [t]

    (p: TextWriter) << (q: %): TextWriter ==
      local r: Rep == rep q
      p << "permutation("
      if not empty? r then p << r.1
      for i in 2 .. #r repeat p << ", " << r.i
      p << ")"

    apply(p: %, j: SI): SI ==
      if j < 1 or j > n
        then error("Bad permutation application: value out of range")
      (rep p).j

    ( a: % ) * ( b: % ) : % ==
      per [ (rep a)((rep b) i) for i in 1 .. n ]

    inv(a: %): % ==
      local r: Rep == new(n, 0)
      for i in 1 .. n repeat r((rep a) i) := i
      per r

    coerce(c: Cycle n): % == per [ c.i for i in 1 .. n ]

-- `Cycle' is a domain of permutations.
--
-- Author: ADK
-- Date Created: 19-JUL-1993 12:55:57.00
-- Modifications: 19-NOV-1994 19:12:49.00 (ADK) Modify for A# V0.37.0

Cycle(n: SI): Join(Group, Finite) with
    bracket: Tuple SI -> %		++ Construct a cycle
    coerce: Tuple SI -> %		++ Construct a cycle
    apply: (%, SI) -> SI		++ Cayley action
    coerce: Permutation n -> %		++ Construct a cycle

  == add

    macro Rep == List List SI

    import from Rep, List SI, String

    default sub: List SI
    default i: SI

    print << "Constructing domain Cycle(" << n << ")" << newline

    #: Integer == coerce n
    sample: % == 1 -- Why do I need this instead of the category default?
    --!! Because the default is in AbelianMonoid, but not Monoid.

    --!! Added a missing export.
    ( a: % ) ^ ( b: Integer ) : % == error "not implemented"

    apply(c: %, j: SI): SI ==
      if j < 1 or j > n
        then error("Bad cycle application: value out of range")
      for sub in (rep c) repeat
        for i in sub repeat
          if i = j
	    -- the next lines looks wrong: why empty?
            then return( if empty? sub then sub(1) else sub(i+1) )
      error("This cannot be reached")

    (p: TextWriter) << (c: %): TextWriter ==
      p << "cycle("
      for sub in (rep c) repeat
	p << "("
        if not empty? sub then p << first sub
	for i in rest sub repeat p << " " << i
	p << ")"
      p << ")"

    -- Compute the subcycle from permutation p starting with element j
    -- and ending with element k <= j. Unless all the elements are >= k
    -- an empty list will be returned.

    subcycle(p: Permutation n, j: SI, k: SI): List SI ==
      j < k => nil
      p.j = k => [j]
      local c: List SI == subcycle(p, p.j, k)
      empty? c => nil
      cons(j, c)

    coerce(p: Permutation n): % ==
      l: Rep := nil
      for i in n .. 1 by -1 repeat
        sub == subcycle(p, i, i)
	if not empty? sub then l := cons(sub, l)
      per l

    1: % == per [ [i]@List SI for i in 1 .. n ]

    ( a: % ) = ( b: % ) : Boolean == (rep a) = (rep b)
    ( a: % ) ~= ( b: % ) : Boolean == ~(a = b)

    [t: Tuple SI]: % ==
      import from  Permutation n
      t :: Permutation n :: %

    coerce(t: Tuple SI): % == [t]

    ( a: % ) * ( b: % ) : % ==
      --!! Added an import statement.
      import from  Permutation n
      ( (a :: Permutation n) * (b :: Permutation n) ) :: %

    inv(a: %): % ==
      --!! Added an import statement.
      import from  Permutation n
      ( inv (a :: Permutation n) ) :: %

-- Tests

import from String, SI
default i: SI

print << "Testing Permutation and Cycle domains..." << newline

macro P6 == Permutation 6
macro C6 == Cycle 6
macro P7 == Permutation 7
macro C7 == Cycle 7

print << "Unit permutation on six objects: " << 1@P6 << newline

local
  b: P6 == [3,1,2,4,6,5]
  bc: C6 == ( b :: C6 )

print << "b = " << b << " = " << bc << newline
print << "inv b = " << inv b << " = " << inv bc << newline
print << "b * inv b = " << b * inv b << " = " << bc * inv bc << newline
print << "b / b = " << b / b << " = " << bc / bc << newline
print << "b 3 = " << b 3 << " = " << bc 3 << newline

local c6: P6 := b
for i in 1 .. while c6 ~= 1 repeat
  print << "b ** " << i << " = " << c6 << " = " << c6::C6 << newline
  c6 := c6 * b

local d: P7 == [2, 3, 4, 5, 6, 7, 1]
local c7 := d
for i in 1 .. while c7 ~= 1 repeat
  --!! Added an import statement.
  import from C7
  print << "d ** " << i << " = " << c7 << " = " << c7::C7 << newline
  c7 := c7 * d

#if TestErrorsToo
[1, 2, 3, 4, 5]@P6
[1, 2, 3, 4, 5, 7]@P6
[1, 2, 6, 4, 5, 2]@P6
#endif

print << "End of test." << newline
 
