def inject(*args, &action)
      options = args.last.is_a?(Hash) ? args.pop : {}
      unless action or options[:block]
        unless [1, 2].member? args.size
          raise "Inject expected 1 or 2 arguments but got #{args.size}" 
        end
        initial, symbol = args[-2], args[-1]
        action = proc { |a,b| a.send symbol, b }
      else
        raise "Inject expected 0 or 1 arguments but got #{args.size}" if args.size > 1
        initial = args.empty? ? nil : args.first
      end
      unless initial.nil?
        initial = Node.match( initial ).new initial unless initial.matched?
        initial_typecode = initial.typecode
      else
        initial_typecode = typecode
      end
      var1 = options[ :var1 ] || Variable.new( initial_typecode )
      var2 = options[ :var2 ] || Variable.new( typecode )
      block = options[ :block ] || action.call( var1, var2 )
      if dimension == 0
        if initial
          block.subst(var1 => initial, var2 => self).simplify
        else
          demand
        end
      else
        index = Variable.new Hornetseye::INDEX( nil )
        value = element( index ).inject nil, :block => block,
                                        :var1 => var1, :var2 => var2
        value = typecode.new value unless value.matched?
        if initial.nil? and index.size.get == 0
          raise "Array was empty and no initial value for injection was given"
        end
        Inject.new( value, index, initial, block, var1, var2 ).force
      end
    end
def inject(*args, &action)
      options = args.last.is_a?(Hash) ? args.pop : {}
      unless action or options[:block]
        unless [1, 2].member? args.size
          raise "Inject expected 1 or 2 arguments but got #{args.size}" 
        end
        initial, symbol = args[-2], args[-1]
        action = proc { |a,b| a.send symbol, b }
      else
        raise "Inject expected 0 or 1 arguments but got #{args.size}" if args.size > 1
        initial = args.empty? ? nil : args.first
      end
      unless initial.nil?
        initial = Node.match( initial ).new initial unless initial.matched?
        initial_typecode = initial.typecode
      else
        initial_typecode = typecode
      end
      var1 = options[ :var1 ] || Variable.new( initial_typecode )
      var2 = options[ :var2 ] || Variable.new( typecode )
      block = options[ :block ] || action.call( var1, var2 )
      if dimension == 0
        if initial
          block.subst(var1 => initial, var2 => self).simplify
        else
          demand
        end
      else
        index = Variable.new Hornetseye::INDEX( nil )
        value = element( index ).inject nil, :block => block,
                                        :var1 => var1, :var2 => var2
        value = typecode.new value unless value.matched?
        if initial.nil? and index.size.get == 0
          raise "Array was empty and no initial value for injection was given"
        end
        Inject.new( value, index, initial, block, var1, var2 ).force
      end
    end
Perform cummulative operation on array

 @overload inject(initial = nil, options = {}, &action)
   @param [Object] initial Initial value for cummulative operation.
   @option options [Variable] :var1 First variable defining operation.
   @option options [Variable] :var1 Second variable defining operation.
   @option options [Variable] :block (action.call(var1, var2)) The operation to apply.

 @overload inject(initial = nil, symbol)
   @param [Object] initial Initial value for cummulative operation.
   @param [Symbol,String] symbol The operation to apply.

 @return [Object] Result of injection.