# Algebraic Extension Field
#
#   by Shin-ichiro Hara
#
# Version 1.00 (2002.02.27)

require "polynomial"
#require "m-polynomial"
require "residue-class-ring"
require "polynomial"

module Algebra
  def AlgebraicExtensionField(field, var, &b)
    AlgebraicExtensionField.create(field, var, &b)
  end
  module_function :AlgebraicExtensionField

  class AlgebraicExtensionField < ResidueClassRing
    def self.create(field, var_obj)
      poly_ring = Algebra.Polynomial(field, var_obj)

      modulus = yield(poly_ring.var)
      klass = super(poly_ring, modulus)

      def klass.var; self[ground.var]; end
      klass.sysvar :base, field

      if Algebra::AlgebraicExtensionField >= field
	env_ring = Algebra.Polynomial(field.env_ring, var_obj)
	klass.sysvar :def_polys, field.def_polys + [modulus]
      else
	env_ring = poly_ring
	klass.sysvar :def_polys, [modulus]
      end

      poly_ring.class_eval <<-__DEF__
      def abs_lift
	if Algebra::AlgebraicExtensionField >= ground
	  project(type.env_ring) {|c, n| c.abs_lift }
	else
	  project(type.env_ring) {|c, n| c }
	end
      end
      __DEF__
      poly_ring.sysvar :env_ring, env_ring
      klass.sysvar :env_ring, env_ring

      klass
    end

    def abs_lift
      Algebra::AlgebraicExtensionField >= type.base ? lift.abs_lift : lift
    end
  end
end

if $0 == __FILE__
end
