
/*
 * Computer Algebra Kit (c) 1993,96 by Comp.Alg.Objects.  All Rights Reserved.
 * $Id: cseq.m,v 1.8 1998/11/13 09:45:22 stes Exp $
 */

#include "cakit.h"

@implementation CASequence

- _setUpCarrier:aSequence
{
  carrier = aSequence;
  return self;
}

+ over:aSequence
{
  return [[[super new] _setUpCarrier:aSequence] toFirst];
}

- clear
{
  [carrier free];
  return [super clear];
}


- next
{
  id m;

  if (m = [carrier next]) {
    return m;
  } else {
    assert([carrier isEmpty] || [carrier previous] != nil);
    assert([carrier isEmpty] || m == [carrier next]);
    return m;
  }
}

- previous
{
  id m;

  if (m = [carrier previous]) {
    return m;
  } else {
    assert([carrier isEmpty] || [carrier next] != nil);
    assert([carrier isEmpty] || m == [carrier previous]);
    return m;
  }
}


- (unsigned) size
{
  return [carrier size];
}

- (BOOL) isEmpty
{
  return [carrier isEmpty];
}

- (BOOL) isKindOfSequence
{
  return YES;
}


- toFirst
{
  [carrier toFirst];
  return self;
}

- toLast
{
  [carrier toLast];
  return self;
}

- toElementAt:(int)i
{
  [carrier toElementAt:i];
  return self;
}


- lastElement
{
  id res = [[self toLast] previous];

  assert([self isEmpty] || [res check] != nil);
  return res;
}

- firstElement
{
  id res = [[self toFirst] next];

  assert([self isEmpty] || [res check] != nil);
  return res;
}

- at:(unsigned)i
{
  id res = [[self toElementAt:i] next];

#ifndef NDEBUG
  if (0 <= i && i < [self size]) {
    assert([res check]);
  } else {
    assert(res == nil);
  }
#endif
  return res;
}

- commonDenominator
{
  id d, m = [self firstElement];

  if (m) {
    d = [[m denominator] cheapCopy];
    while (m = [self next])
      d = [d lcmSelf:[m denominator]];
    return d;
  } else {
    return nil;
  }
}

- content
{
  id d, m = [self firstElement];

  if (m) {
    d = [m cheapCopy];
    while ([d notZero] && [d notOne] && (m = [self next])) {
      d = [d gcdSelf:m];
    }
    return d;
  } else {
    return nil;
  }
}


- printOn:(IOD)aFile
{
  id aMember;

  fprintf(aFile, "{");
  if (aMember = [self next])
    [aMember printOn:aFile];
  while (aMember = [self next]) {
    fprintf(aFile, ",");
    [aMember printOn:aFile];
  }
  fprintf(aFile, "}");

  return self;
}

@end

