<commit_before>class ArrayConstraintVariable < ConstraintObject
  attr_writer :constraint_variables

  # A metaobject to hold multiple constraints over ranges of the
  # array.
  class RangeConstraint < ConstraintObject
    def initialize(constraints)
      @constraints = constraints
    end

    def enable(strength = :required)
      @constraints.each do |c|
        c.enable(strength)
      end
    end

    def disable
      @constraints.each do |c|
        c.disable
      end
    end
  end

  def initialize(ary)
    @ary = ary
    @constraint_variables = @ary.collect do |var|
      __constrain__ { var }
    end
  end

  def sum
    return 0 if @ary.empty?
    @constraint_variables[0] + self[1..-1].sum
  end

  def __size
    @ary.size
  end

  def length
    @length = @ary.size unless @length
    __constrain__ { @length }
  end
  alias size length

  def [](*args)
    idx, l = args
    if idx.is_a? Numeric and (l.nil? or l == 1)
      idx = idx + @ary.size if idx < 0
      if idx >= @ary.size
        a = 0
        @constraint_variables[idx] = __constrain__ { a }
      end
      @constraint_variables[idx]
    else
      var = ArrayConstraintVariable.new(@ary[*args])
      var.constraint_variables = @constraint_variables[*args]
      var
    end
  end

  def ==(other)
    return false unless other.is_a?(Array) || other.is_a?(self.class)
    equality_constraints = [self.length == other.length]
    os = other.is_a?(self.class) ? other.__size : other.size

    (0...(@ary.size > os ? @ary.size : os)).each do |idx|
      equality_constraints << (self[idx] == (other[idx] || 0))
    end
    r = RangeConstraint.new(equality_constraints)
    r.enable
    r
  end

  # VM interface
  def value
    result = @ary.dup

    if @length
      if result.size < (l = @length)
        while (l -= 1) > 0
          result << 0
        end
      else
        result = result[0...@length] if @length
      end
    end

    @constraint_variables.each_with_index do |cv, idx|
      result[idx] = cv.value if cv && cv.value
    end
    result
  end

  def suggest_value(val)
    initialize(val)
  end

  def method_missing(method, *args)
    raise "Cannot solve array constraints using #{method}"
  end
end

class Array
  def for_constraint(name)
    if self.all? { |e| e.is_a? Numeric }
      ArrayConstraintVariable.new(self)
    end
  end

  def assign_constraint_value(val)
    replace(val)
  end
end
<commit_msg>make sure that we always work with the latest known result array<commit_after>class ArrayConstraintVariable < ConstraintObject
  attr_writer :constraint_variables

  # A metaobject to hold multiple constraints over ranges of the
  # array.
  class RangeConstraint < ConstraintObject
    def initialize(constraints)
      @constraints = constraints
    end

    def enable(strength = :required)
      @constraints.each do |c|
        c.enable(strength)
      end
    end

    def disable
      @constraints.each do |c|
        c.disable
      end
    end
  end

  def initialize(ary)
    @ary = ary
    @constraint_variables = @ary.collect do |var|
      __constrain__ { var }
    end
  end

  def sum
    return 0 if value.empty?
    @constraint_variables[0] + self[1..-1].sum
  end

  def __size
    value.size
  end

  def length
    @length = value.size unless @length
    __constrain__ { @length }
  end
  alias size length

  def [](*args)
    idx, l = args
    ary = value
    if idx.is_a? Numeric and (l.nil? or l == 1)
      idx = idx + ary.size if idx < 0
      if idx >= ary.size
        a = 0
        @constraint_variables[idx] = __constrain__ { a }
      end
      @constraint_variables[idx]
    else
      var = ArrayConstraintVariable.new(ary[*args])
      var.constraint_variables = @constraint_variables[*args]
      var
    end
  end

  def ==(other)
    return false unless other.is_a?(Array) || other.is_a?(self.class)
    ary = value
    equality_constraints = [self.length == other.length]
    os = other.is_a?(self.class) ? other.__size : other.size

    (0...(ary.size > os ? ary.size : os)).each do |idx|
      equality_constraints << (self[idx] == (other[idx] || 0))
    end
    r = RangeConstraint.new(equality_constraints)
    r.enable
    r
  end

  # VM interface
  def value
    result = @ary.dup

    if @length
      if result.size < (l = @length)
        while (l -= 1) > 0
          result << 0
        end
      else
        result = result[0...@length] if @length
      end
    end

    @constraint_variables.each_with_index do |cv, idx|
      result[idx] = cv.value if cv && cv.value
    end
    result
  end

  def suggest_value(val)
    initialize(val)
  end

  def method_missing(method, *args)
    raise "Cannot solve array constraints using #{method}"
  end
end

class Array
  def for_constraint(name)
    if self.all? { |e| e.is_a? Numeric }
      ArrayConstraintVariable.new(self)
    end
  end

  def assign_constraint_value(val)
    replace(val)
  end
end

{'fraction_non_alphanumeric': 0.09953280520008125, 'fraction_numerical': 0.005281332520820638, 'mean_word_length': 2.3633879781420766, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1848917', 'n_tokens_mistral': 1637, 'n_tokens_neox': 1584, 'n_words': 451}