text: //------------------------------------------------------------------------------
  // GB_semiring_template.c: built-in unary and binary functions and operators
  //------------------------------------------------------------------------------
  
  // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
  // SPDX-License-Identifier: Apache-2.0
  
  //------------------------------------------------------------------------------
  
  // This file is #include'd many times in GB_ops.c to define the built-in
  // semirings.  That file has defined either GB_BOOLEAN, or GB_TYPE as one of
  // the 10 non-boolean types.
  
  // Using built-in types and operators, many unique semirings can be built.
  // Below is the list of pre-defined semirings in SuiteSparse:GraphBLAS:
  
  // 1000 semirings with a multiply operator TxT -> T where T is non-Boolean, from
  // the complete cross product of:
  
  //      5 monoids: MIN, MAX, PLUS, TIMES, ANY
  //      20 multiply operators:
  //          FIRST, SECOND, PAIR, MIN, MAX, PLUS, MINUS, RMINUS, TIMES, DIV, RDIV
  //          ISEQ, ISNE, ISGT, ISLT, ISGE, ISLE,
  //          LOR, LAND, LXOR
  //      10 non-Boolean types, T
  
  //      a single instance of this file creates 100 semirings of this
  //      form, of one type T, when T is not BOOL
  
  // 300 semirings with a comparator TxT -> bool, where T is
  // non-Boolean, from the complete cross product of:
  
  //      5 Boolean monoids: LAND, LOR, LXOR, EQ, ANY
  //      6 multiply operators: EQ, NE, GT, LT, GE, LE
  //      10 non-Boolean types, T
  
  //      a single instance of this file creates 30 semirings of this form,
  //      of one type T, when T is not BOOL
  
  // 55 semirings with purely Boolean types, bool x bool -> bool, from the
  // complete cross product of:
  
  //      5 Boolean monoids: LAND, LOR, LXOR, EQ, ANY
  //      11 multiply operators:
  //          FIRST, SECOND, PAIR, LOR, LAND, LXOR, EQ, GT, LT, GE, LE
  
  //      a single instance of this file creates all 5*11 = 55 purely Boolean
  //      semirings, when T is BOOL and GB_BOOLEAN is defined
  
  // 54 complex semirings:
  
  //      3 complex monoids: PLUS, TIMES, ANY
  //      9 multiply operators: FIRST, SECOND, PAIR, PLUS, MINUS, TIMES,
  //          DIV, RDIV, RMINUS
  //      2 complex types (FC32 and FC64)
  
  // 64 bitwise semirings:
  
  //      4 bitwise monoids: BOR, BAND, BXOR, BXNOR
  //      4 bitwise multiply operators: BOR, BAND, BXOR, BXNOR
  //      4 unsigned integer types: UINT8, UINT16, UINT32, UINT64
  
  // 80 positional semirings:
  
  //      5 monoids: MIN, MAX, PLUS, TIMES, ANY
  //      8 multiply operators:
  //          FIRSTI, FIRSTI1, FIRSTJ, FIRSTJ1,
  //          SECONDI, SECONDI1, SECONDJ, SECONDJ1
  //      2 types: INT32, INT64
  
  #if defined ( GB_BOOLEAN )
  
      //--------------------------------------------------------------------------
      // 55 purely Boolean semirings
      //--------------------------------------------------------------------------
  
      // All types in these 44 semirings are BOOL
  
      // 11 semirings with LOR monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( LOR   , FIRST  )
      GXB_SEMIRING ( LOR   , SECOND )
      GXB_SEMIRING ( LOR   , PAIR   )
      GXB_SEMIRING ( LOR   , LOR    )
      GXB_SEMIRING ( LOR   , LAND   )
      GXB_SEMIRING ( LOR   , LXOR   )
      GXB_SEMIRING ( LOR   , EQ     )
      GXB_SEMIRING ( LOR   , GT     )
      GXB_SEMIRING ( LOR   , LT     )
      GXB_SEMIRING ( LOR   , GE     )
      GXB_SEMIRING ( LOR   , LE     )
  
      // 11 semirings with LAND monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( LAND  , FIRST  )
      GXB_SEMIRING ( LAND  , SECOND )
      GXB_SEMIRING ( LAND  , PAIR   )
      GXB_SEMIRING ( LAND  , LOR    )
      GXB_SEMIRING ( LAND  , LAND   )
      GXB_SEMIRING ( LAND  , LXOR   )
      GXB_SEMIRING ( LAND  , EQ     )
      GXB_SEMIRING ( LAND  , GT     )
      GXB_SEMIRING ( LAND  , LT     )
      GXB_SEMIRING ( LAND  , GE     )
      GXB_SEMIRING ( LAND  , LE     )
  
      // 11 semirings with LXOR monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( LXOR  , FIRST  )
      GXB_SEMIRING ( LXOR  , SECOND )
      GXB_SEMIRING ( LXOR  , PAIR   )
      GXB_SEMIRING ( LXOR  , LOR    )
      GXB_SEMIRING ( LXOR  , LAND   )
      GXB_SEMIRING ( LXOR  , LXOR   )
      GXB_SEMIRING ( LXOR  , EQ     )
      GXB_SEMIRING ( LXOR  , GT     )
      GXB_SEMIRING ( LXOR  , LT     )
      GXB_SEMIRING ( LXOR  , GE     )
      GXB_SEMIRING ( LXOR  , LE     )
  
      // 11 semirings with EQ monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( EQ    , FIRST  )
      GXB_SEMIRING ( EQ    , SECOND )
      GXB_SEMIRING ( EQ    , PAIR   )
      GXB_SEMIRING ( EQ    , LOR    )
      GXB_SEMIRING ( EQ    , LAND   )
      GXB_SEMIRING ( EQ    , LXOR   )
      GXB_SEMIRING ( EQ    , EQ     )
      GXB_SEMIRING ( EQ    , GT     )
      GXB_SEMIRING ( EQ    , LT     )
      GXB_SEMIRING ( EQ    , GE     )
      GXB_SEMIRING ( EQ    , LE     )
  
      // 11 semirings with ANY monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( ANY   , FIRST  )
      GXB_SEMIRING ( ANY   , SECOND )
      GXB_SEMIRING ( ANY   , PAIR   )
      GXB_SEMIRING ( ANY   , LOR    )
      GXB_SEMIRING ( ANY   , LAND   )
      GXB_SEMIRING ( ANY   , LXOR   )
      GXB_SEMIRING ( ANY   , EQ     )
      GXB_SEMIRING ( ANY   , GT     )
      GXB_SEMIRING ( ANY   , LT     )
      GXB_SEMIRING ( ANY   , GE     )
      GXB_SEMIRING ( ANY   , LE     )
  
  #elif defined ( GB_COMPLEX )
  
      //--------------------------------------------------------------------------
      // 27 complex semirings of the form TxT->t
      //--------------------------------------------------------------------------
  
      // 9 semirings with PLUS monoid
      GXB_SEMIRING ( PLUS  , FIRST  )
      GXB_SEMIRING ( PLUS  , SECOND )
      GXB_SEMIRING ( PLUS  , PAIR   )
      GXB_SEMIRING ( PLUS  , PLUS   )
      GXB_SEMIRING ( PLUS  , MINUS  )
      GXB_SEMIRING ( PLUS  , RMINUS )
      GXB_SEMIRING ( PLUS  , TIMES  )
      GXB_SEMIRING ( PLUS  , DIV    )
      GXB_SEMIRING ( PLUS  , RDIV   )
  
      // 9 semirings with TIMES monoid
      GXB_SEMIRING ( TIMES , FIRST  )
      GXB_SEMIRING ( TIMES , SECOND )
      GXB_SEMIRING ( TIMES , PAIR   )
      GXB_SEMIRING ( TIMES , PLUS   )
      GXB_SEMIRING ( TIMES , MINUS  )
      GXB_SEMIRING ( TIMES , RMINUS )
      GXB_SEMIRING ( TIMES , TIMES  )
      GXB_SEMIRING ( TIMES , DIV    )
      GXB_SEMIRING ( TIMES , RDIV   )
  
      // 9 semirings with ANY monoid
      GXB_SEMIRING ( ANY   , FIRST  )
      GXB_SEMIRING ( ANY   , SECOND )
      GXB_SEMIRING ( ANY   , PAIR   )
      GXB_SEMIRING ( ANY   , PLUS   )
      GXB_SEMIRING ( ANY   , MINUS  )
      GXB_SEMIRING ( ANY   , RMINUS )
      GXB_SEMIRING ( ANY   , TIMES  )
      GXB_SEMIRING ( ANY   , DIV    )
      GXB_SEMIRING ( ANY   , RDIV   )
  
  #else
  
      //--------------------------------------------------------------------------
      // 100 semirings of the form TxT->T
      //--------------------------------------------------------------------------
  
      // All types in these semirings are the same.  These are defined for
      // the 10 non-Boolean types, not when T is BOOL.
  
      // 20 semirings with MIN monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( MIN   , FIRST  )
      GXB_SEMIRING ( MIN   , SECOND )
      GXB_SEMIRING ( MIN   , PAIR   )
      GXB_SEMIRING ( MIN   , MIN    )
      GXB_SEMIRING ( MIN   , MAX    )
      GXB_SEMIRING ( MIN   , PLUS   )
      GXB_SEMIRING ( MIN   , MINUS  )
      GXB_SEMIRING ( MIN   , RMINUS )
      GXB_SEMIRING ( MIN   , TIMES  )
      GXB_SEMIRING ( MIN   , DIV    )
      GXB_SEMIRING ( MIN   , RDIV   )
      GXB_SEMIRING ( MIN   , ISEQ   )
      GXB_SEMIRING ( MIN   , ISNE   )
      GXB_SEMIRING ( MIN   , ISGT   )
      GXB_SEMIRING ( MIN   , ISLT   )
      GXB_SEMIRING ( MIN   , ISGE   )
      GXB_SEMIRING ( MIN   , ISLE   )
      GXB_SEMIRING ( MIN   , LOR    )
      GXB_SEMIRING ( MIN   , LAND   )
      GXB_SEMIRING ( MIN   , LXOR   )
  
      // 20 semirings with MAX monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( MAX   , FIRST  )
      GXB_SEMIRING ( MAX   , SECOND )
      GXB_SEMIRING ( MAX   , PAIR   )
      GXB_SEMIRING ( MAX   , MIN    )
      GXB_SEMIRING ( MAX   , MAX    )
      GXB_SEMIRING ( MAX   , PLUS   )
      GXB_SEMIRING ( MAX   , MINUS  )
      GXB_SEMIRING ( MAX   , RMINUS )
      GXB_SEMIRING ( MAX   , TIMES  )
      GXB_SEMIRING ( MAX   , DIV    )
      GXB_SEMIRING ( MAX   , RDIV   )
      GXB_SEMIRING ( MAX   , ISEQ   )
      GXB_SEMIRING ( MAX   , ISNE   )
      GXB_SEMIRING ( MAX   , ISGT   )
      GXB_SEMIRING ( MAX   , ISLT   )
      GXB_SEMIRING ( MAX   , ISGE   )
      GXB_SEMIRING ( MAX   , ISLE   )
      GXB_SEMIRING ( MAX   , LOR    )
      GXB_SEMIRING ( MAX   , LAND   )
      GXB_SEMIRING ( MAX   , LXOR   )
  
      // 20 semirings with PLUS monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( PLUS  , FIRST  )
      GXB_SEMIRING ( PLUS  , SECOND )
      GXB_SEMIRING ( PLUS  , PAIR   )
      GXB_SEMIRING ( PLUS  , MIN    )
      GXB_SEMIRING ( PLUS  , MAX    )
      GXB_SEMIRING ( PLUS  , PLUS   )
      GXB_SEMIRING ( PLUS  , MINUS  )
      GXB_SEMIRING ( PLUS  , RMINUS )
      GXB_SEMIRING ( PLUS  , TIMES  )
      GXB_SEMIRING ( PLUS  , DIV    )
      GXB_SEMIRING ( PLUS  , RDIV   )
      GXB_SEMIRING ( PLUS  , ISEQ   )
      GXB_SEMIRING ( PLUS  , ISNE   )
      GXB_SEMIRING ( PLUS  , ISGT   )
      GXB_SEMIRING ( PLUS  , ISLT   )
      GXB_SEMIRING ( PLUS  , ISGE   )
      GXB_SEMIRING ( PLUS  , ISLE   )
      GXB_SEMIRING ( PLUS  , LOR    )
      GXB_SEMIRING ( PLUS  , LAND   )
      GXB_SEMIRING ( PLUS  , LXOR   )
  
      // 20 semirings with TIMES monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( TIMES , FIRST  )
      GXB_SEMIRING ( TIMES , SECOND )
      GXB_SEMIRING ( TIMES , PAIR   )
      GXB_SEMIRING ( TIMES , MIN    )
      GXB_SEMIRING ( TIMES , MAX    )
      GXB_SEMIRING ( TIMES , PLUS   )
      GXB_SEMIRING ( TIMES , MINUS  )
      GXB_SEMIRING ( TIMES , RMINUS )
      GXB_SEMIRING ( TIMES , TIMES  )
      GXB_SEMIRING ( TIMES , DIV    )
      GXB_SEMIRING ( TIMES , RDIV   )
      GXB_SEMIRING ( TIMES , ISEQ   )
      GXB_SEMIRING ( TIMES , ISNE   )
      GXB_SEMIRING ( TIMES , ISGT   )
      GXB_SEMIRING ( TIMES , ISLT   )
      GXB_SEMIRING ( TIMES , ISGE   )
      GXB_SEMIRING ( TIMES , ISLE   )
      GXB_SEMIRING ( TIMES , LOR    )
      GXB_SEMIRING ( TIMES , LAND   )
      GXB_SEMIRING ( TIMES , LXOR   )
  
      // 20 semirings with ANY monoid; the 2nd argument is the multiply operator
      GXB_SEMIRING ( ANY   , FIRST  )
      GXB_SEMIRING ( ANY   , SECOND )
      GXB_SEMIRING ( ANY   , PAIR   )
      GXB_SEMIRING ( ANY   , MIN    )
      GXB_SEMIRING ( ANY   , MAX    )
      GXB_SEMIRING ( ANY   , PLUS   )
      GXB_SEMIRING ( ANY   , MINUS  )
      GXB_SEMIRING ( ANY   , RMINUS )
      GXB_SEMIRING ( ANY   , TIMES  )
      GXB_SEMIRING ( ANY   , DIV    )
      GXB_SEMIRING ( ANY   , RDIV   )
      GXB_SEMIRING ( ANY   , ISEQ   )
      GXB_SEMIRING ( ANY   , ISNE   )
      GXB_SEMIRING ( ANY   , ISGT   )
      GXB_SEMIRING ( ANY   , ISLT   )
      GXB_SEMIRING ( ANY   , ISGE   )
      GXB_SEMIRING ( ANY   , ISLE   )
      GXB_SEMIRING ( ANY   , LOR    )
      GXB_SEMIRING ( ANY   , LAND   )
      GXB_SEMIRING ( ANY   , LXOR   )
  
      //--------------------------------------------------------------------------
      // 30 semirings of the form TxT -> bool
      //--------------------------------------------------------------------------
  
      // The multiply operator has the form z=compare(x,y), where x and y are of
      // type T, and z is Boolean.  These operators are combined with the four
      // Boolean monoids.
  
      // These are defined when T is one of the 10 non-Boolean types, not when T
      // is BOOL
  
      // 6 semrings with LOR monoid; the 2nd argument is the comparator
      GXB_SEMIRING_COMPARE ( LOR  , EQ )
      GXB_SEMIRING_COMPARE ( LOR  , NE )
      GXB_SEMIRING_COMPARE ( LOR  , GT )
      GXB_SEMIRING_COMPARE ( LOR  , LT )
      GXB_SEMIRING_COMPARE ( LOR  , GE )
      GXB_SEMIRING_COMPARE ( LOR  , LE )
  
      // 6 semrings with LAND monoid; the 2nd argument is the comparator
      GXB_SEMIRING_COMPARE ( LAND , EQ )
      GXB_SEMIRING_COMPARE ( LAND , NE )
      GXB_SEMIRING_COMPARE ( LAND , GT )
      GXB_SEMIRING_COMPARE ( LAND , LT )
      GXB_SEMIRING_COMPARE ( LAND , GE )
      GXB_SEMIRING_COMPARE ( LAND , LE )
  
      // 6 semrings with LXOR monoid; the 2nd argument is the comparator
      GXB_SEMIRING_COMPARE ( LXOR , EQ )
      GXB_SEMIRING_COMPARE ( LXOR , NE )
      GXB_SEMIRING_COMPARE ( LXOR , GT )
      GXB_SEMIRING_COMPARE ( LXOR , LT )
      GXB_SEMIRING_COMPARE ( LXOR , GE )
      GXB_SEMIRING_COMPARE ( LXOR , LE )
  
      // 6 semrings with EQ monoid; the 2nd argument is the comparator
      GXB_SEMIRING_COMPARE ( EQ   , EQ )
      GXB_SEMIRING_COMPARE ( EQ   , NE )
      GXB_SEMIRING_COMPARE ( EQ   , GT )
      GXB_SEMIRING_COMPARE ( EQ   , LT )
      GXB_SEMIRING_COMPARE ( EQ   , GE )
      GXB_SEMIRING_COMPARE ( EQ   , LE )
  
      // 6 semrings with ANY monoid; the 2nd argument is the comparator
      GXB_SEMIRING_COMPARE ( ANY  , EQ )
      GXB_SEMIRING_COMPARE ( ANY  , NE )
      GXB_SEMIRING_COMPARE ( ANY  , GT )
      GXB_SEMIRING_COMPARE ( ANY  , LT )
      GXB_SEMIRING_COMPARE ( ANY  , GE )
      GXB_SEMIRING_COMPARE ( ANY  , LE )
  
  #endif
  
  #if defined ( GB_UNSIGNED_INT )
  
      //--------------------------------------------------------------------------
      // 16 bitwise semirings (for unsigned integers only)
      //--------------------------------------------------------------------------
  
      GXB_SEMIRING ( BOR   , BOR    )
      GXB_SEMIRING ( BOR   , BAND   )
      GXB_SEMIRING ( BOR   , BXOR   )
      GXB_SEMIRING ( BOR   , BXNOR  )
  
      GXB_SEMIRING ( BAND  , BOR    )
      GXB_SEMIRING ( BAND  , BAND   )
      GXB_SEMIRING ( BAND  , BXOR   )
      GXB_SEMIRING ( BAND  , BXNOR  )
  
      GXB_SEMIRING ( BXOR  , BOR    )
      GXB_SEMIRING ( BXOR  , BAND   )
      GXB_SEMIRING ( BXOR  , BXOR   )
      GXB_SEMIRING ( BXOR  , BXNOR  )
  
      GXB_SEMIRING ( BXNOR , BOR    )
      GXB_SEMIRING ( BXNOR , BAND   )
      GXB_SEMIRING ( BXNOR , BXOR   )
      GXB_SEMIRING ( BXNOR , BXNOR  )
  
  #endif
  
  #if defined ( GB_POSITIONAL )
  
      //--------------------------------------------------------------------------
      // 40 positional semirings:
      //--------------------------------------------------------------------------
  
      GXB_SEMIRING ( MIN   , FIRSTI   )
      GXB_SEMIRING ( MIN   , FIRSTI1  )
      GXB_SEMIRING ( MIN   , FIRSTJ   )
      GXB_SEMIRING ( MIN   , FIRSTJ1  )
      GXB_SEMIRING ( MIN   , SECONDI  )
      GXB_SEMIRING ( MIN   , SECONDI1 )
      GXB_SEMIRING ( MIN   , SECONDJ  )
      GXB_SEMIRING ( MIN   , SECONDJ1 )
  
      GXB_SEMIRING ( MAX   , FIRSTI   )
      GXB_SEMIRING ( MAX   , FIRSTI1  )
      GXB_SEMIRING ( MAX   , FIRSTJ   )
      GXB_SEMIRING ( MAX   , FIRSTJ1  )
      GXB_SEMIRING ( MAX   , SECONDI  )
      GXB_SEMIRING ( MAX   , SECONDI1 )
      GXB_SEMIRING ( MAX   , SECONDJ  )
      GXB_SEMIRING ( MAX   , SECONDJ1 )
  
      GXB_SEMIRING ( ANY   , FIRSTI   )
      GXB_SEMIRING ( ANY   , FIRSTI1  )
      GXB_SEMIRING ( ANY   , FIRSTJ   )
      GXB_SEMIRING ( ANY   , FIRSTJ1  )
      GXB_SEMIRING ( ANY   , SECONDI  )
      GXB_SEMIRING ( ANY   , SECONDI1 )
      GXB_SEMIRING ( ANY   , SECONDJ  )
      GXB_SEMIRING ( ANY   , SECONDJ1 )
  
      GXB_SEMIRING ( PLUS  , FIRSTI   )
      GXB_SEMIRING ( PLUS  , FIRSTI1  )
      GXB_SEMIRING ( PLUS  , FIRSTJ   )
      GXB_SEMIRING ( PLUS  , FIRSTJ1  )
      GXB_SEMIRING ( PLUS  , SECONDI  )
      GXB_SEMIRING ( PLUS  , SECONDI1 )
      GXB_SEMIRING ( PLUS  , SECONDJ  )
      GXB_SEMIRING ( PLUS  , SECONDJ1 )
  
      GXB_SEMIRING ( TIMES , FIRSTI   )
      GXB_SEMIRING ( TIMES , FIRSTI1  )
      GXB_SEMIRING ( TIMES , FIRSTJ   )
      GXB_SEMIRING ( TIMES , FIRSTJ1  )
      GXB_SEMIRING ( TIMES , SECONDI  )
      GXB_SEMIRING ( TIMES , SECONDI1 )
      GXB_SEMIRING ( TIMES , SECONDJ  )
      GXB_SEMIRING ( TIMES , SECONDJ1 )
  
  #endif
  
  #undef GB_XTYPE
  #undef GB_BOOLEAN
  #undef GB_COMPLEX
  #undef GB_UNSIGNED_INT
  #undef GB_POSITIONAL
  
  