<commit_before># Extensions for RDF classes

module RDF
  class URI
    ##
    # Returns the SXP representation of this object.
    #
    # @return [String]
    def to_sxp; qname || "<#{self}>"; end
    
    # Override qname to save value for SXP serialization
    def qname=(value); @qname = value; end
    def qname; @qname; end
  end

  class Literal
    ##
    # Returns the SXP representation of a Literal.
    #
    # @return [String]
    def to_sxp
      case datatype
      when XSD.boolean, XSD.integer, XSD.double, XSD.decimal, XSD.time
        object.to_sxp
      else
        text = value.dump
        text << "@#{language}" if self.has_language?
        text << "^^#{datatype.to_sxp}" if self.has_datatype?
        text
      end
    end
  end

  class Statement
    # Transform Query into an Array form of an SXP
    # @return [Statement]
    def to_sxa
      [:triple, subject, predicate, object]
    end

    # Transform Statement into an SXP
    # @return [String]
    def to_sxp
      to_sxa.to_sxp
    end
  end
  
  class Query
    ##
    # @return [RDF::Resource]
    attr_accessor :context

    # Add patterns from another query to form a new Query
    # @param [RDF::Query] other
    # @return [RDF::Query]
    def +(other)
      Query.new(self.patterns + other.patterns)
    end
    
    # Is this is a named query?
    # @return [Boolean]
    def named?
      !unnamed?
    end
    
    def unnamed?
      options[:context].nil?
    end
    
    # Add name to query
    # @param [RDF::Value] value
    # @return [RDF::Value]
    def context=(value)
      options[:context] = value
    end
    
    # Name of this query, if any
    # @return [RDF::Value]
    def context
      options[:context]
    end

    # Transform Query into an Array form of an SXP
    #
    # If Query is named, it's treated as a GroupGraphPattern, otherwise, a BGP
    #
    # @return [Array]
    def to_sxa
      res = [:bgp] + patterns
      named? ? [:graph, context, res] : res
    end
    
    # Transform Query into an SXP
    # @return [String]
    def to_sxp
      to_sxa.to_sxp
    end
  end
  
  ##
  # A Query sub-class to represent :join, :union and :leftjoin
  #
  # Represents pairs of Queries with an operation.
  #
  # Variables, solutions, and patterns can be derived via an operation on the constituent graphs.
  # This may be done after execution of sub-components, or as an optimization phase to resolve
  # a AlgebraQuery object into a new QueryAlebra object with a simpler graph, or to a Query object
  class AlgebraQuery < Query
    ##
    # Queries included. No greater than 2.
    # @return [RDF::Query]
    attr_accessor :queries

    ##
    # Operation to be performed, one of :join, :leftjoin, or :union.
    # @return [Symbol]
    attr_accessor :operation

    ##
    # Initializes a new algebra query.
    #
    # @param  [Array<RDF::Query>] queries
    # @param  [to_sym] operation (:join)
    #   Must be one of :join, :leftjoin, or :union
    # @param  [Hash{Symbol => Object}] options
    #   any additional keyword options
    # @option options [RDF::Query::Solutions] :solutions (Solutions.new)
    # @yield  [query]
    # @yieldparam  [RDF::AlgebraQuery] query
    # @yieldreturn [void] ignored
    def initialize(queries = [], operation = :join, options = {}, &block)
      super(nil, options) do
        @queries = queries
        @operation = operation

        if block_given?
          case block.arity
            when 0 then instance_eval(&block)
            else block.call(self)
          end
        end
      end
    end
    
    # Transform AlgebraQuery into an Array form of an SXP
    #
    # @return [Array]
    def to_sxa
      [operation] + queries.map {|q| [q.to_sxa]}
    end
  end
  
  class Query::Variable
    def to_sxp; to_s; end
  end
end<commit_msg>Added AlgebraQuery#<< and #query<commit_after># Extensions for RDF classes

module RDF
  class URI
    ##
    # Returns the SXP representation of this object.
    #
    # @return [String]
    def to_sxp; qname || "<#{self}>"; end
    
    # Override qname to save value for SXP serialization
    def qname=(value); @qname = value; end
    def qname; @qname; end
  end

  class Literal
    ##
    # Returns the SXP representation of a Literal.
    #
    # @return [String]
    def to_sxp
      case datatype
      when XSD.boolean, XSD.integer, XSD.double, XSD.decimal, XSD.time
        object.to_sxp
      else
        text = value.dump
        text << "@#{language}" if self.has_language?
        text << "^^#{datatype.to_sxp}" if self.has_datatype?
        text
      end
    end
  end

  class Statement
    def inspect
      to_sxa.map(&:to_sxp).inspect
    end
    
    # Transform Query into an Array form of an SXP
    # @return [Statement]
    def to_sxa
      [:triple, subject, predicate, object]
    end

    # Transform Statement into an SXP
    # @return [String]
    def to_sxp
      to_sxa.to_sxp
    end
  end
  
  class Query
    ##
    # @return [RDF::Resource]
    attr_accessor :context

    # Add patterns from another query to form a new Query
    # @param [RDF::Query] other
    # @return [RDF::Query]
    def +(other)
      Query.new(self.patterns + other.patterns)
    end
    
    # Is this is a named query?
    # @return [Boolean]
    def named?
      !unnamed?
    end
    
    def unnamed?
      options[:context].nil?
    end
    
    # Add name to query
    # @param [RDF::Value] value
    # @return [RDF::Value]
    def context=(value)
      options[:context] = value
    end
    
    # Name of this query, if any
    # @return [RDF::Value]
    def context
      options[:context]
    end

    def inspect
      "RDF::Query(#{context ? context.to_sxp : 'nil'})#{patterns.inspect}"
    end

    # Transform Query into an Array form of an SXP
    #
    # If Query is named, it's treated as a GroupGraphPattern, otherwise, a BGP
    #
    # @return [Array]
    def to_sxa
      res = [:bgp] + patterns
      named? ? [:graph, context, res] : res
    end
    
    # Transform Query into an SXP
    # @return [String]
    def to_sxp
      to_sxa.to_sxp
    end
  end
  
  ##
  # A Query sub-class to represent :join, :union and :leftjoin
  #
  # Represents pairs of Queries with an operation.
  #
  # Variables, solutions, and patterns can be derived via an operation on the constituent graphs.
  # This may be done after execution of sub-components, or as an optimization phase to resolve
  # a AlgebraQuery object into a new QueryAlebra object with a simpler graph, or to a Query object
  class AlgebraQuery < Query
    ##
    # Queries included. No greater than 2.
    # @return [RDF::Query]
    attr_accessor :queries

    ##
    # Operation to be performed, one of :join, :leftjoin, or :union.
    # @return [Symbol]
    attr_accessor :operation

    ##
    # Initializes a new algebra query.
    #
    # @param  [Array<RDF::Query>] queries
    #   Queries to be operated upon
    # @param  [to_sym] operation (:join)
    #   Must be one of :join, :leftjoin, or :union
    # @param  [Hash{Symbol => Object}] options
    #   any additional keyword options
    # @option options [RDF::Query::Solutions] :solutions (Solutions.new)
    # @yield  [query]
    # @yieldparam  [RDF::AlgebraQuery] query
    # @yieldreturn [void] ignored
    def initialize(queries = [], operation = :join, options = {}, &block)
      super(nil, options) do
        @queries = queries
        @operation = operation

        if block_given?
          case block.arity
            when 0 then instance_eval(&block)
            else block.call(self)
          end
        end
      end
    end
    
    ##
    # Appends the given query to this query.
    #
    # @param  [RDF::Query] query
    #   a query
    # @return [void] self
    def <<(query)
      @queries << query
      self
    end

    ##
    # Appends the given query to this query.
    #
    # @param  [RDF::Query] query
    #   a query
    # @return [void] self
    def query(query)
      @queries << query
      self
    end

    def inspect
      "RDF::AlgebraQuery(#{operation})#{queries.inspect}"
    end
    
    # Transform AlgebraQuery into an Array form of an SXP
    #
    # @return [Array]
    def to_sxa
      [operation] + queries.map {|q| q.to_sxa}
    end
  end
  
  class Query::Variable
    def to_sxp; to_s; end
  end
end
{'fraction_non_alphanumeric': 0.09736747205192932, 'fraction_numerical': 0.0004808270224786633, 'mean_word_length': 2.204930662557781, 'pattern_counts': {'":': 0, '<': 25, '<?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': '6517983', 'n_tokens_mistral': 2734, 'n_tokens_neox': 2659, 'n_words': 879}