
# Autogenerated by mlir-tblgen; don't manually edit.

from ._ods_common import _cext as _ods_cext
from ._ods_common import (
    equally_sized_accessor as _ods_equally_sized_accessor,
    get_default_loc_context as _ods_get_default_loc_context,
    get_op_results_or_values as _get_op_results_or_values,
    segmented_accessor as _ods_segmented_accessor,
)
_ods_ir = _ods_cext.ir
_ods_cext.globals.register_traceback_file_exclusion(__file__)

import builtins
from typing import Any as _Any, Sequence as _Sequence, Union as _Union, Optional as _Optional
import sys as _sys
if _sys.version_info >= (3, 12):
  from collections.abc import Buffer as _Buffer  # pytype: disable=not-supported-yet
else:
  try:
    from typing_extensions import Buffer as _Buffer
  except ImportError:
    _Buffer = _Any


@_ods_cext.register_dialect
class _Dialect(_ods_ir.Dialect):
  DIALECT_NAMESPACE = "pdl"

@_ods_cext.register_operation(_Dialect)
class ApplyNativeConstraintOp(_ods_ir.OpView):
  r"""
  `pdl.apply_native_constraint` operations apply a native C++ constraint, that
  has been registered externally with the consumer of PDL, to a given set of
  entities and optionally return a number of values.
  
  Example:
  
  ```mlir
  // Apply `myConstraint` to the entities defined by `input`, `attr`, and `op`.
  pdl.apply_native_constraint "myConstraint"(%input, %attr, %op : !pdl.value, !pdl.attribute, !pdl.operation)
  // Apply constraint `with_result` to `root`. This constraint returns an attribute.
  %attr = pdl.apply_native_constraint "with_result"(%root : !pdl.operation) : !pdl.attribute
  ```
  """

  OPERATION_NAME = "pdl.apply_native_constraint"

  _ODS_REGIONS = (0, True)

  def __init__(self, results_: _Sequence[_ods_ir.Type], name: _Union[str, _ods_ir.StringAttr], args: _Sequence[_ods_ir.Value], *, isNegated: _Optional[_Union[bool, _ods_ir.BoolAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(args))
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["name"] = (name if (
    isinstance(name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(name, context=_ods_context))
    if isNegated is not None: attributes["isNegated"] = (isNegated if (
        isinstance(isNegated, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('BoolAttr')) else
          _ods_ir.AttrBuilder.get('BoolAttr')(isNegated, context=_ods_context))
    results = []
    results.extend(results_)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def args(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def name(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["name"]

  @name.setter
  def name(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["name"] = value

  @builtins.property
  def isNegated(self) -> _ods_ir.BoolAttr:
    return self.operation.attributes["isNegated"]

  @isNegated.setter
  def isNegated(self, value: _ods_ir.BoolAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["isNegated"] = value

  @builtins.property
  def results_(self) -> _ods_ir.OpResultList:
    _ods_variadic_group_length = len(self.operation.results) - 1 + 1
    return self.operation.results[0:0 + _ods_variadic_group_length]

@_ods_cext.register_op_adaptor(ApplyNativeConstraintOp)
class ApplyNativeConstraintOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.apply_native_constraint"

  @builtins.property
  def args(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def name(self) -> _ods_ir.StringAttr:
    return self.attributes["name"]

  @builtins.property
  def isNegated(self) -> _ods_ir.BoolAttr:
    return self.attributes["isNegated"]

def apply_native_constraint(results_: _Sequence[_ods_ir.Type], name: _Union[str, _ods_ir.StringAttr], args: _Sequence[_ods_ir.Value], *, is_negated: _Optional[_Union[bool, _ods_ir.BoolAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _Union[_ods_ir.OpResult, _ods_ir.OpResultList, ApplyNativeConstraintOp]:
  op = ApplyNativeConstraintOp(results_=results_, name=name, args=args, isNegated=is_negated, loc=loc, ip=ip); results = op.results
  return results if len(results) > 1 else (results[0] if len(results) == 1 else op)

@_ods_cext.register_operation(_Dialect)
class ApplyNativeRewriteOp(_ods_ir.OpView):
  r"""
  `pdl.apply_native_rewrite` operations apply a native C++ function, that has
  been registered externally with the consumer of PDL, to perform a rewrite
  and optionally return a number of values. The native function may accept any
  number of arguments. This operation is used within a pdl.rewrite region to enable
  the interleaving of native rewrite methods with other pdl constructs.
  
  Example:
  
  ```mlir
  // Apply a native rewrite method that returns an attribute.
  %ret = pdl.apply_native_rewrite "myNativeFunc"(%arg0, %attr1) : !pdl.attribute
  ```
  
  ```c++
  // The native rewrite as defined in C++:
  static Attribute myNativeFunc(PatternRewriter &rewriter, Value arg0, Attribute arg1) {
    // Just return the second arg.
    return arg1;
  }
  
  void registerNativeRewrite(PDLPatternModule &pdlModule) {
    pdlModule.registerRewriteFunction("myNativeFunc", myNativeFunc);
  }
  ```
  """

  OPERATION_NAME = "pdl.apply_native_rewrite"

  _ODS_REGIONS = (0, True)

  def __init__(self, results_: _Sequence[_ods_ir.Type], name: _Union[str, _ods_ir.StringAttr], args: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(args))
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["name"] = (name if (
    isinstance(name, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrAttr')) else
      _ods_ir.AttrBuilder.get('StrAttr')(name, context=_ods_context))
    results = []
    results.extend(results_)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def args(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def name(self) -> _ods_ir.StringAttr:
    return self.operation.attributes["name"]

  @name.setter
  def name(self, value: _ods_ir.StringAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["name"] = value

  @builtins.property
  def results_(self) -> _ods_ir.OpResultList:
    _ods_variadic_group_length = len(self.operation.results) - 1 + 1
    return self.operation.results[0:0 + _ods_variadic_group_length]

@_ods_cext.register_op_adaptor(ApplyNativeRewriteOp)
class ApplyNativeRewriteOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.apply_native_rewrite"

  @builtins.property
  def args(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def name(self) -> _ods_ir.StringAttr:
    return self.attributes["name"]

def apply_native_rewrite(results_: _Sequence[_ods_ir.Type], name: _Union[str, _ods_ir.StringAttr], args: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _Union[_ods_ir.OpResult, _ods_ir.OpResultList, ApplyNativeRewriteOp]:
  op = ApplyNativeRewriteOp(results_=results_, name=name, args=args, loc=loc, ip=ip); results = op.results
  return results if len(results) > 1 else (results[0] if len(results) == 1 else op)

@_ods_cext.register_operation(_Dialect)
class AttributeOp(_ods_ir.OpView):
  r"""
  `pdl.attribute` operations capture named attribute edges into an operation.
  Instances of this operation define, and partially constrain, attributes of a
  given operation. A `pdl.attribute` may partially constrain the input by
  specifying an expected attribute value type (via a `pdl.type` operation), or
  a constant value for the attribute (via `val`). Only one of these may be set
  for a given input, as the type of the constant value provides the type. When
  defined within a `pdl.rewrite` region, the constant value must be specified.
  
  Example:
  
  ```mlir
  // Define an attribute:
  %attr = pdl.attribute
  
  // Define an attribute with an expected type:
  %type = pdl.type : i32
  %attr = pdl.attribute : %type
  
  // Define an attribute with a constant value:
  %attr = pdl.attribute = "hello"
  ```
  """

  OPERATION_NAME = "pdl.attribute"

  _ODS_REGIONS = (0, True)

  def __init__(self, attr: _ods_ir.Type, *, valueType: _Optional[_ods_ir.Value] = None, value: _Optional[_Union[_Any, _ods_ir.Attribute]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    if valueType is not None: operands.append(valueType)
    _ods_context = _ods_get_default_loc_context(loc)
    if value is not None: attributes["value"] = (value if (
        isinstance(value, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('AnyAttr')) else
          _ods_ir.AttrBuilder.get('AnyAttr')(value, context=_ods_context))
    results = []
    results.append(attr)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def valueType(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operation.operands) < 1 else self.operation.operands[0]

  @builtins.property
  def value(self) -> _Optional[_ods_ir.Attribute]:
    if "value" not in self.operation.attributes:
      return None
    return self.operation.attributes["value"]

  @value.setter
  def value(self, value: _Optional[_ods_ir.Attribute]):
    if value is not None:
      self.operation.attributes["value"] = value
    elif "value" in self.operation.attributes:
      del self.operation.attributes["value"]

  @value.deleter
  def value(self):
    del self.operation.attributes["value"]

  @builtins.property
  def attr(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(AttributeOp)
class AttributeOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.attribute"

  @builtins.property
  def valueType(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operands) < 1 else self.operands[0]

  @builtins.property
  def value(self) -> _Optional[_ods_ir.Attribute]:
    if "value" not in self.attributes:
      return None
    return self.attributes["value"]

def attribute(attr: _ods_ir.Type, *, value_type: _Optional[_ods_ir.Value] = None, value: _Optional[_Union[_Any, _ods_ir.Attribute]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return AttributeOp(attr=attr, valueType=value_type, value=value, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class EraseOp(_ods_ir.OpView):
  r"""
  `pdl.erase` operations are used within `pdl.rewrite` regions to specify that
  an input operation should be marked as erased. The semantics of this
  operation correspond with the `eraseOp` method on a `PatternRewriter`.
  
  Example:
  
  ```mlir
  pdl.erase %root
  ```
  """

  OPERATION_NAME = "pdl.erase"

  _ODS_REGIONS = (0, True)

  def __init__(self, opValue: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(opValue)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def opValue(self) -> _ods_ir.Value:
    return self.operation.operands[0]

@_ods_cext.register_op_adaptor(EraseOp)
class EraseOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.erase"

  @builtins.property
  def opValue(self) -> _ods_ir.Value:
    return self.operands[0]

def erase(op_value: _ods_ir.Value, *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> EraseOp:
  return EraseOp(opValue=op_value, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class OperandOp(_ods_ir.OpView):
  r"""
  `pdl.operand` operations capture external operand edges into an operation
  node that originate from operations or block arguments not otherwise
  specified within the pattern (i.e. via `pdl.result` or `pdl.results`). These
  operations define individual operands of a given operation. A `pdl.operand`
  may partially constrain an operand by specifying an expected value type
  (via a `pdl.type` operation).
  
  Example:
  
  ```mlir
  // Define an external operand:
  %operand = pdl.operand
  
  // Define an external operand with an expected type:
  %type = pdl.type : i32
  %operand = pdl.operand : %type
  ```
  """

  OPERATION_NAME = "pdl.operand"

  _ODS_REGIONS = (0, True)

  def __init__(self, value: _ods_ir.Type, *, valueType: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    if valueType is not None: operands.append(valueType)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(value)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def valueType(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operation.operands) < 1 else self.operation.operands[0]

  @builtins.property
  def value(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(OperandOp)
class OperandOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.operand"

  @builtins.property
  def valueType(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operands) < 1 else self.operands[0]

def operand(value: _ods_ir.Type, *, value_type: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return OperandOp(value=value, valueType=value_type, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class OperandsOp(_ods_ir.OpView):
  r"""
  `pdl.operands` operations capture external operand range edges into an
  operation node that originate from operations or block arguments not
  otherwise specified within the pattern (i.e. via `pdl.result` or
  `pdl.results`). These operations define groups of input operands into a
  given operation. A `pdl.operands` may partially constrain a set of input
  operands by specifying expected value types (via `pdl.types` operations).
  
  Example:
  
  ```mlir
  // Define a range of input operands:
  %operands = pdl.operands
  
  // Define a range of input operands with expected types:
  %types = pdl.types : [i32, i64, i32]
  %typed_operands = pdl.operands : %types
  ```
  """

  OPERATION_NAME = "pdl.operands"

  _ODS_REGIONS = (0, True)

  def __init__(self, value: _ods_ir.Type, *, valueType: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    if valueType is not None: operands.append(valueType)
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(value)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def valueType(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operation.operands) < 1 else self.operation.operands[0]

  @builtins.property
  def value(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(OperandsOp)
class OperandsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.operands"

  @builtins.property
  def valueType(self) -> _Optional[_ods_ir.Value]:
    return None if len(self.operands) < 1 else self.operands[0]

def operands_(value: _ods_ir.Type, *, value_type: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return OperandsOp(value=value, valueType=value_type, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class OperationOp(_ods_ir.OpView):
  r"""
  `pdl.operation` operations define operation nodes within a pattern. Within
  a match sequence, i.e. when directly nested within a `pdl.pattern`, these
  operations correspond to input operations, or those that already existing
  within the MLIR module. Inside of a `pdl.rewrite`, these operations
  correspond to operations that should be created as part of the replacement
  sequence.
  
  `pdl.operation`s are composed of a name, and a set of attribute, operand,
  and result type values, that map to what those that would be on a
  constructed instance of that operation. The results of a `pdl.operation` are
  a handle to the operation itself. Handles to the results of the operation
  can be extracted via `pdl.result`.
  
  Example:
  
  ```mlir
  // Define an instance of a `foo.op` operation.
  %op = pdl.operation "foo.op"(%arg0, %arg1 : !pdl.value, !pdl.value)
    {"attrA" = %attr0} -> (%type, %type : !pdl.type, !pdl.type)
  ```
  
  When used within a matching context, the name of the operation may be
  omitted.
  
  When used within a rewriting context, i.e. when defined within a
  `pdl.rewrite`, all of the result types must be "inferable". This means that
  the type must be attributable to either a constant type value or the result
  type of another entity, such as an attribute, the result of a
  `apply_native_rewrite`, or the result type of another operation. If the
  result type value does not meet any of these criteria, the operation must
  override the `InferTypeOpInterface` to ensure that the result types can be
  inferred.
  
  The operands of the operation are interpreted in the following ways:
  
  1) A single !pdl.range<value>:
  
  In this case, the single range is treated as all of the operands of the
  operation.
  
  ```mlir
  // Define an instance with single range of operands.
  %op = pdl.operation "func.return"(%allArgs : !pdl.range<value>)
  ```
  
  2) A variadic number of either !pdl.value or !pdl.range<value>:
  
  In this case, the inputs are expected to correspond with the operand groups
  defined on the operation in ODS.
  
  ```tablgen
  // Given the following operation definition in ODS:
  def MyIndirectCallOp {
    let results = (outs FunctionType:$call, Variadic<AnyType>:$args);
  }
  ```
  
  ```mlir
  // We can match the operands as so:
  %op = pdl.operation "my.indirect_call"(%call, %args : !pdl.value, !pdl.range<value>)
  ```
  
  The results of the operation are interpreted in the following ways:
  
  1) A single !pdl.range<type>:
  
  In this case, the single range is treated as all of the result types of the
  operation.
  
  ```mlir
  // Define an instance with single range of types.
  %allResultTypes = pdl.types
  %op = pdl.operation "builtin.unrealized_conversion_cast" -> (%allResultTypes : !pdl.types)
  ```
  
  2) A variadic number of either !pdl.type or !pdl.range<type>:
  
  In this case, the inputs are expected to correspond with the result groups
  defined on the operation in ODS.
  
  ```tablgen
  // Given the following operation definition in ODS:
  def MyOp {
    let results = (outs SomeType:$result, Variadic<SomeType>:$otherResults);
  }
  ```
  
  ```mlir
  // We can match the results as so:
  %result = pdl.type
  %otherResults = pdl.types
  %op = pdl.operation "foo.op" -> (%result, %otherResults : !pdl.type, !pdl.range<type>)
  ```
  """

  OPERATION_NAME = "pdl.operation"

  _ODS_OPERAND_SEGMENTS = [-1,-1,-1,]

  _ODS_REGIONS = (0, True)

  def __init__(self, op: _ods_ir.Type, operandValues: _Sequence[_ods_ir.Value], attributeValues: _Sequence[_ods_ir.Value], attributeValueNames: _Union[_Sequence[str], _ods_ir.ArrayAttr], typeValues: _Sequence[_ods_ir.Value], *, opName: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(_get_op_results_or_values(operandValues))
    operands.append(_get_op_results_or_values(attributeValues))
    operands.append(_get_op_results_or_values(typeValues))
    _ods_context = _ods_get_default_loc_context(loc)
    if opName is not None: attributes["opName"] = (opName if (
        isinstance(opName, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('StrAttr')) else
          _ods_ir.AttrBuilder.get('StrAttr')(opName, context=_ods_context))
    attributes["attributeValueNames"] = (attributeValueNames if (
    isinstance(attributeValueNames, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('StrArrayAttr')) else
      _ods_ir.AttrBuilder.get('StrArrayAttr')(attributeValueNames, context=_ods_context))
    results = []
    results.append(op)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def operandValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 0)
    return operand_range

  @builtins.property
  def attributeValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 1)
    return operand_range

  @builtins.property
  def typeValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 2)
    return operand_range

  @builtins.property
  def opName(self) -> _Optional[_ods_ir.StringAttr]:
    if "opName" not in self.operation.attributes:
      return None
    return self.operation.attributes["opName"]

  @opName.setter
  def opName(self, value: _Optional[_ods_ir.StringAttr]):
    if value is not None:
      self.operation.attributes["opName"] = value
    elif "opName" in self.operation.attributes:
      del self.operation.attributes["opName"]

  @opName.deleter
  def opName(self):
    del self.operation.attributes["opName"]

  @builtins.property
  def attributeValueNames(self) -> _ods_ir.ArrayAttr:
    return self.operation.attributes["attributeValueNames"]

  @attributeValueNames.setter
  def attributeValueNames(self, value: _ods_ir.ArrayAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["attributeValueNames"] = value

  @builtins.property
  def op(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(OperationOp)
class OperationOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.operation"

  @builtins.property
  def operandValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 0)
    return operand_range

  @builtins.property
  def attributeValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 1)
    return operand_range

  @builtins.property
  def typeValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 2)
    return operand_range

  @builtins.property
  def opName(self) -> _Optional[_ods_ir.StringAttr]:
    if "opName" not in self.attributes:
      return None
    return self.attributes["opName"]

  @builtins.property
  def attributeValueNames(self) -> _ods_ir.ArrayAttr:
    return self.attributes["attributeValueNames"]

def operation_(op: _ods_ir.Type, operand_values: _Sequence[_ods_ir.Value], attribute_values: _Sequence[_ods_ir.Value], attribute_value_names: _Union[_Sequence[str], _ods_ir.ArrayAttr], type_values: _Sequence[_ods_ir.Value], *, op_name: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return OperationOp(op=op, operandValues=operand_values, attributeValues=attribute_values, attributeValueNames=attribute_value_names, typeValues=type_values, opName=op_name, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class PatternOp(_ods_ir.OpView):
  r"""
  `pdl.pattern` operations provide a transformable representation for a
  `RewritePattern`. The attributes on this operation correspond to the various
  metadata on a `RewritePattern`, such as the benefit. The match section of
  the pattern is specified within the region body, with the rewrite provided
  by a terminating `pdl.rewrite`.
  
  Example:
  
  ```mlir
  // Provide a pattern matching "foo.op" that replaces the root with its
  // operand.
  pdl.pattern : benefit(1) {
    %resultType = pdl.type
    %inputOperand = pdl.operand
    %root = pdl.operation "foo.op"(%inputOperand) -> (%resultType)
    pdl.rewrite %root {
      pdl.replace %root with (%inputOperand)
    }
  }
  ```
  """

  OPERATION_NAME = "pdl.pattern"

  _ODS_REGIONS = (1, True)

  def __init__(self, benefit: _Union[int, _ods_ir.IntegerAttr], *, sym_name: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["benefit"] = (benefit if (
    isinstance(benefit, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('I16Attr')) else
      _ods_ir.AttrBuilder.get('I16Attr')(benefit, context=_ods_context))
    if sym_name is not None: attributes["sym_name"] = (sym_name if (
        isinstance(sym_name, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('SymbolNameAttr')) else
          _ods_ir.AttrBuilder.get('SymbolNameAttr')(sym_name, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def benefit(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["benefit"]

  @benefit.setter
  def benefit(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["benefit"] = value

  @builtins.property
  def sym_name(self) -> _Optional[_ods_ir.StringAttr]:
    if "sym_name" not in self.operation.attributes:
      return None
    return self.operation.attributes["sym_name"]

  @sym_name.setter
  def sym_name(self, value: _Optional[_ods_ir.StringAttr]):
    if value is not None:
      self.operation.attributes["sym_name"] = value
    elif "sym_name" in self.operation.attributes:
      del self.operation.attributes["sym_name"]

  @sym_name.deleter
  def sym_name(self):
    del self.operation.attributes["sym_name"]

  @builtins.property
  def bodyRegion(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(PatternOp)
class PatternOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.pattern"

  @builtins.property
  def benefit(self) -> _ods_ir.IntegerAttr:
    return self.attributes["benefit"]

  @builtins.property
  def sym_name(self) -> _Optional[_ods_ir.StringAttr]:
    if "sym_name" not in self.attributes:
      return None
    return self.attributes["sym_name"]

def pattern(benefit: _Union[int, _ods_ir.IntegerAttr], *, sym_name: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> PatternOp:
  return PatternOp(benefit=benefit, sym_name=sym_name, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class RangeOp(_ods_ir.OpView):
  r"""
  `pdl.range` operations construct a range from a given set of PDL entities,
  which all share the same underlying element type. For example, a
  `!pdl.range<value>` may be constructed from a list of `!pdl.value`
  or `!pdl.range<value>` entities.
  
  Example:
  
  ```mlir
  // Construct a range of values.
  %valueRange = pdl.range %inputValue, %inputRange : !pdl.value, !pdl.range<value>
  
  // Construct a range of types.
  %typeRange = pdl.range %inputType, %inputRange : !pdl.type, !pdl.range<type>
  
  // Construct an empty range of types.
  %valueRange = pdl.range : !pdl.range<type>
  ```
  
  TODO: Range construction is currently limited to rewrites, but it could
  be extended to constraints under certain circustances; i.e., if we can
  determine how to extract the underlying elements. If we can't, e.g. if
  there are multiple sub ranges used for construction, we won't be able
  to determine their sizes during constraint time.
  """

  OPERATION_NAME = "pdl.range"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, arguments: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.extend(_get_op_results_or_values(arguments))
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def arguments(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operation.operands) - 1 + 1
    return self.operation.operands[0:0 + _ods_variadic_group_length]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(RangeOp)
class RangeOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.range"

  @builtins.property
  def arguments(self) -> _ods_ir.OpOperandList:
    _ods_variadic_group_length = len(self.operands) - 1 + 1
    return self.operands[0:0 + _ods_variadic_group_length]

def range(result: _ods_ir.Type, arguments: _Sequence[_ods_ir.Value], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return RangeOp(result=result, arguments=arguments, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ReplaceOp(_ods_ir.OpView):
  r"""
  `pdl.replace` operations are used within `pdl.rewrite` regions to specify
  that an input operation should be marked as replaced. The semantics of this
  operation correspond with the `replaceOp` method on a `PatternRewriter`. The
  set of replacement values can be either:
  * a single `Operation` (`replOperation` should be populated)
    - The operation will be replaced with the results of this operation.
  * a set of `Value`s (`replValues` should be populated)
    - The operation will be replaced with these values.
  
  Example:
  
  ```mlir
  // Replace root node with 2 values:
  pdl.replace %root with (%val0, %val1 : !pdl.value, !pdl.value)
  
  // Replace root node with a range of values:
  pdl.replace %root with (%vals : !pdl.range<value>)
  
  // Replace root with another operation:
  pdl.replace %root with %otherOp
  ```
  """

  OPERATION_NAME = "pdl.replace"

  _ODS_OPERAND_SEGMENTS = [1,0,-1,]

  _ODS_REGIONS = (0, True)

  def __init__(self, opValue: _ods_ir.Value, replValues: _Sequence[_ods_ir.Value], *, replOperation: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(opValue)
    operands.append(replOperation)
    operands.append(_get_op_results_or_values(replValues))
    _ods_context = _ods_get_default_loc_context(loc)
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def opValue(self) -> _ods_ir.Value:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 0)
    return operand_range[0]

  @builtins.property
  def replOperation(self) -> _Optional[_ods_ir.Value]:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 1)
    return operand_range[0] if len(operand_range) > 0 else None

  @builtins.property
  def replValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 2)
    return operand_range

@_ods_cext.register_op_adaptor(ReplaceOp)
class ReplaceOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.replace"

  @builtins.property
  def opValue(self) -> _ods_ir.Value:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 0)
    return operand_range[0]

  @builtins.property
  def replOperation(self) -> _Optional[_ods_ir.Value]:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 1)
    return operand_range[0] if len(operand_range) > 0 else None

  @builtins.property
  def replValues(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 2)
    return operand_range

def replace(op_value: _ods_ir.Value, repl_values: _Sequence[_ods_ir.Value], *, repl_operation: _Optional[_ods_ir.Value] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> ReplaceOp:
  return ReplaceOp(opValue=op_value, replValues=repl_values, replOperation=repl_operation, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class ResultOp(_ods_ir.OpView):
  r"""
  `pdl.result` operations extract result edges from an operation node within
  a pattern or rewrite region. The provided index is zero-based, and
  represents the concrete result to extract, i.e. this is not the result index
  as defined by the ODS definition of the operation.
  
  Example:
  
  ```mlir
  // Extract a result:
  %operation = pdl.operation ...
  %pdl_result = pdl.result 1 of %operation
  
  // Imagine the following IR being matched:
  %result_0, %result_1 = foo.op ...
  
  // If the example pattern snippet above were matching against `foo.op` in
  // the IR snippet, `%pdl_result` would correspond to `%result_1`.
  ```
  """

  OPERATION_NAME = "pdl.result"

  _ODS_REGIONS = (0, True)

  def __init__(self, val: _ods_ir.Type, parent: _ods_ir.Value, index: _Union[int, _ods_ir.IntegerAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(parent)
    _ods_context = _ods_get_default_loc_context(loc)
    attributes["index"] = (index if (
    isinstance(index, _ods_ir.Attribute) or
    not _ods_ir.AttrBuilder.contains('I32Attr')) else
      _ods_ir.AttrBuilder.get('I32Attr')(index, context=_ods_context))
    results = []
    results.append(val)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def parent(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def index(self) -> _ods_ir.IntegerAttr:
    return self.operation.attributes["index"]

  @index.setter
  def index(self, value: _ods_ir.IntegerAttr):
    if value is None:
      raise ValueError("'None' not allowed as value for mandatory attributes")
    self.operation.attributes["index"] = value

  @builtins.property
  def val(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(ResultOp)
class ResultOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.result"

  @builtins.property
  def parent(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def index(self) -> _ods_ir.IntegerAttr:
    return self.attributes["index"]

def result(val: _ods_ir.Type, parent: _ods_ir.Value, index: _Union[int, _ods_ir.IntegerAttr], *, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return ResultOp(val=val, parent=parent, index=index, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class ResultsOp(_ods_ir.OpView):
  r"""
  `pdl.results` operations extract a result group from an operation within a
  pattern or rewrite region. If an index is provided, this operation extracts
  a result group as defined by the ODS definition of the operation. In this
  case the result of this operation may be either a single `pdl.value` or
  a `pdl.range<value>`, depending on the constraint of the result in ODS. If
  no index is provided, this operation extracts the full result range of the
  operation.
  
  Example:
  
  ```mlir
  // Extract all of the results of an operation:
  %operation = pdl.operation ...
  %results = pdl.results of %operation
  
  // Extract the results in the first result group of an operation, which is
  // variadic:
  %operation = pdl.operation ...
  %results = pdl.results 0 of %operation -> !pdl.range<value>
  
  // Extract the results in the second result group of an operation, which is
  // not variadic:
  %operation = pdl.operation ...
  %results = pdl.results 1 of %operation -> !pdl.value
  ```
  """

  OPERATION_NAME = "pdl.results"

  _ODS_REGIONS = (0, True)

  def __init__(self, val: _ods_ir.Type, parent: _ods_ir.Value, *, index: _Optional[_Union[int, _ods_ir.IntegerAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(parent)
    _ods_context = _ods_get_default_loc_context(loc)
    if index is not None: attributes["index"] = (index if (
        isinstance(index, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('I32Attr')) else
          _ods_ir.AttrBuilder.get('I32Attr')(index, context=_ods_context))
    results = []
    results.append(val)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def parent(self) -> _ods_ir.Value:
    return self.operation.operands[0]

  @builtins.property
  def index(self) -> _Optional[_ods_ir.IntegerAttr]:
    if "index" not in self.operation.attributes:
      return None
    return self.operation.attributes["index"]

  @index.setter
  def index(self, value: _Optional[_ods_ir.IntegerAttr]):
    if value is not None:
      self.operation.attributes["index"] = value
    elif "index" in self.operation.attributes:
      del self.operation.attributes["index"]

  @index.deleter
  def index(self):
    del self.operation.attributes["index"]

  @builtins.property
  def val(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(ResultsOp)
class ResultsOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.results"

  @builtins.property
  def parent(self) -> _ods_ir.Value:
    return self.operands[0]

  @builtins.property
  def index(self) -> _Optional[_ods_ir.IntegerAttr]:
    if "index" not in self.attributes:
      return None
    return self.attributes["index"]

def results_(val: _ods_ir.Type, parent: _ods_ir.Value, *, index: _Optional[_Union[int, _ods_ir.IntegerAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return ResultsOp(val=val, parent=parent, index=index, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class RewriteOp(_ods_ir.OpView):
  r"""
  `pdl.rewrite` operations terminate the region of a `pdl.pattern` and specify
  the main rewrite of a `pdl.pattern`, on the optional root operation. The
  rewrite is specified either via a string name (`name`) to a native
  rewrite function, or via the region body. The rewrite region, if specified,
  must contain a single block. If the rewrite is external it functions
  similarly to `pdl.apply_native_rewrite`, and takes a set of additional
  positional values defined within the matcher as arguments. If the rewrite is
  external, the root operation is passed to the native function as the leading
  arguments. The root operation, if provided, specifies the starting point in
  the pattern for the subgraph isomorphism search. Pattern matching will proceed
  from this node downward (towards the defining operation) or upward
  (towards the users) until all the operations in the pattern have been matched.
  If the root is omitted, the pdl_interp lowering will automatically select
  the best root of the pdl.rewrite among all the operations in the pattern.
  
  Example:
  
  ```mlir
  // Specify an external rewrite function:
  pdl.rewrite %root with "myExternalRewriter"(%value : !pdl.value)
  
  // Specify a rewrite inline using PDL with the given root:
  pdl.rewrite %root {
    %op = pdl.operation "foo.op"(%arg0, %arg1)
    pdl.replace %root with %op
  }
  
  // Specify a rewrite inline using PDL, automatically selecting root:
  pdl.rewrite {
    %op1 = pdl.operation "foo.op"(%arg0, %arg1)
    %op2 = pdl.operation "bar.op"(%arg0, %arg1)
    pdl.replace %root1 with %op1
    pdl.replace %root2 with %op2
  }
  ```
  """

  OPERATION_NAME = "pdl.rewrite"

  _ODS_OPERAND_SEGMENTS = [0,-1,]

  _ODS_REGIONS = (1, True)

  def __init__(self, externalArgs: _Sequence[_ods_ir.Value], *, root: _Optional[_ods_ir.Value] = None, name: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    operands.append(root)
    operands.append(_get_op_results_or_values(externalArgs))
    _ods_context = _ods_get_default_loc_context(loc)
    if name is not None: attributes["name"] = (name if (
        isinstance(name, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('StrAttr')) else
          _ods_ir.AttrBuilder.get('StrAttr')(name, context=_ods_context))
    results = []
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def root(self) -> _Optional[_ods_ir.Value]:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 0)
    return operand_range[0] if len(operand_range) > 0 else None

  @builtins.property
  def externalArgs(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operation.operands,
         self.operation.attributes["operandSegmentSizes"], 1)
    return operand_range

  @builtins.property
  def name(self) -> _Optional[_ods_ir.StringAttr]:
    if "name" not in self.operation.attributes:
      return None
    return self.operation.attributes["name"]

  @name.setter
  def name(self, value: _Optional[_ods_ir.StringAttr]):
    if value is not None:
      self.operation.attributes["name"] = value
    elif "name" in self.operation.attributes:
      del self.operation.attributes["name"]

  @name.deleter
  def name(self):
    del self.operation.attributes["name"]

  @builtins.property
  def bodyRegion(self) -> _ods_ir.Region:
    return self.regions[0]

@_ods_cext.register_op_adaptor(RewriteOp)
class RewriteOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.rewrite"

  @builtins.property
  def root(self) -> _Optional[_ods_ir.Value]:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 0)
    return operand_range[0] if len(operand_range) > 0 else None

  @builtins.property
  def externalArgs(self) -> _ods_ir.OpOperandList:
    operand_range = _ods_segmented_accessor(
         self.operands,
         self.attributes["operandSegmentSizes"], 1)
    return operand_range

  @builtins.property
  def name(self) -> _Optional[_ods_ir.StringAttr]:
    if "name" not in self.attributes:
      return None
    return self.attributes["name"]

def rewrite(external_args: _Sequence[_ods_ir.Value], *, root: _Optional[_ods_ir.Value] = None, name: _Optional[_Union[str, _ods_ir.StringAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> RewriteOp:
  return RewriteOp(externalArgs=external_args, root=root, name=name, loc=loc, ip=ip)

@_ods_cext.register_operation(_Dialect)
class TypeOp(_ods_ir.OpView):
  r"""
  `pdl.type` operations capture result type constraints of `Attributes`,
  `Values`, and `Operations`. Instances of this operation define, and
  partially constrain, results types of a given entity. A `pdl.type` may
  partially constrain the result by specifying a constant `Type`.
  
  Example:
  
  ```mlir
  // Define a type:
  %type = pdl.type
  
  // Define a type with a constant value:
  %type = pdl.type : i32
  ```
  """

  OPERATION_NAME = "pdl.type"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, *, constantType: _Optional[_Union[_ods_ir.Type, _ods_ir.TypeAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    if constantType is not None: attributes["constantType"] = (constantType if (
        isinstance(constantType, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('TypeAttr')) else
          _ods_ir.AttrBuilder.get('TypeAttr')(constantType, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def constantType(self) -> _Optional[_ods_ir.TypeAttr]:
    if "constantType" not in self.operation.attributes:
      return None
    return self.operation.attributes["constantType"]

  @constantType.setter
  def constantType(self, value: _Optional[_ods_ir.TypeAttr]):
    if value is not None:
      self.operation.attributes["constantType"] = value
    elif "constantType" in self.operation.attributes:
      del self.operation.attributes["constantType"]

  @constantType.deleter
  def constantType(self):
    del self.operation.attributes["constantType"]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(TypeOp)
class TypeOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.type"

  @builtins.property
  def constantType(self) -> _Optional[_ods_ir.TypeAttr]:
    if "constantType" not in self.attributes:
      return None
    return self.attributes["constantType"]

def type_(result: _ods_ir.Type, *, constant_type: _Optional[_Union[_ods_ir.Type, _ods_ir.TypeAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return TypeOp(result=result, constantType=constant_type, loc=loc, ip=ip).result

@_ods_cext.register_operation(_Dialect)
class TypesOp(_ods_ir.OpView):
  r"""
  `pdl.types` operations capture result type constraints of `Value`s, and
  `Operation`s. Instances of this operation define results types of a given
  entity. A `pdl.types` may partially constrain the results by specifying
  an array of `Type`s.
  
  Example:
  
  ```mlir
  // Define a range of types:
  %types = pdl.types
  
  // Define a range of types with a range of constant values:
  %types = pdl.types : [i32, i64, i32]
  ```
  """

  OPERATION_NAME = "pdl.types"

  _ODS_REGIONS = (0, True)

  def __init__(self, result: _ods_ir.Type, *, constantTypes: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None):
    operands = []
    attributes = {}
    regions = None
    _ods_context = _ods_get_default_loc_context(loc)
    if constantTypes is not None: attributes["constantTypes"] = (constantTypes if (
        isinstance(constantTypes, _ods_ir.Attribute) or
        not _ods_ir.AttrBuilder.contains('TypeArrayAttr')) else
          _ods_ir.AttrBuilder.get('TypeArrayAttr')(constantTypes, context=_ods_context))
    results = []
    results.append(result)
    _ods_successors = None
    super().__init__(self.OPERATION_NAME, self._ODS_REGIONS, self._ODS_OPERAND_SEGMENTS, self._ODS_RESULT_SEGMENTS, attributes=attributes, results=results, operands=operands, successors=_ods_successors, regions=regions, loc=loc, ip=ip)

  @builtins.property
  def constantTypes(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "constantTypes" not in self.operation.attributes:
      return None
    return self.operation.attributes["constantTypes"]

  @constantTypes.setter
  def constantTypes(self, value: _Optional[_ods_ir.ArrayAttr]):
    if value is not None:
      self.operation.attributes["constantTypes"] = value
    elif "constantTypes" in self.operation.attributes:
      del self.operation.attributes["constantTypes"]

  @constantTypes.deleter
  def constantTypes(self):
    del self.operation.attributes["constantTypes"]

  @builtins.property
  def result(self) -> _ods_ir.OpResult:
    return self.operation.results[0]

@_ods_cext.register_op_adaptor(TypesOp)
class TypesOpAdaptor(_ods_ir.OpAdaptor):
  OPERATION_NAME = "pdl.types"

  @builtins.property
  def constantTypes(self) -> _Optional[_ods_ir.ArrayAttr]:
    if "constantTypes" not in self.attributes:
      return None
    return self.attributes["constantTypes"]

def types(result: _ods_ir.Type, *, constant_types: _Optional[_Union[_Any, _ods_ir.ArrayAttr]] = None, loc: _Optional[_ods_ir.Location] = None, ip: _Optional[_ods_ir.InsertionPoint] = None) -> _ods_ir.OpResult:
  return TypesOp(result=result, constantTypes=constant_types, loc=loc, ip=ip).result
