{-# LANGUAGE PatternSynonyms #-}

-- |
-- Module      : Jikka.Core.Language.BuiltinPatterns
-- Description : provides pattern synonyms for builtin functions. / 組み込み関数のための pattern synonyms を提供します。
-- Copyright   : (c) Kimiyuki Onaka, 2020
-- License     : Apache License 2.0
-- Maintainer  : kimiyuki95@gmail.com
-- Stability   : experimental
-- Portability : portable
--
-- `Jikka.Core.Language.BuiltinPatterns` provides pattern synonyms for applications of `Builtin` functions.
-- For example, provide a pattern @Sum' e@ which is interpreted as @AppBuiltin Sum [e]@, or the same thing, @App (Lit (LitBuiltin Sum)) [e]@.
module Jikka.Core.Language.BuiltinPatterns where

import Jikka.Core.Language.Expr

-- arithmetical functions
pattern $bNegate' :: Expr -> Expr
$mNegate' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Negate' e = AppBuiltin Negate e

pattern $bPlus' :: Expr -> Expr -> Expr
$mPlus' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Plus' e1 e2 = AppBuiltin2 Plus e1 e2

pattern $bMinus' :: Expr -> Expr -> Expr
$mMinus' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Minus' e1 e2 = AppBuiltin2 Minus e1 e2

pattern $bMult' :: Expr -> Expr -> Expr
$mMult' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Mult' e1 e2 = AppBuiltin2 Mult e1 e2

pattern $bFloorDiv' :: Expr -> Expr -> Expr
$mFloorDiv' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
FloorDiv' e1 e2 = AppBuiltin2 FloorDiv e1 e2

pattern $bFloorMod' :: Expr -> Expr -> Expr
$mFloorMod' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
FloorMod' e1 e2 = AppBuiltin2 FloorMod e1 e2

pattern $bCeilDiv' :: Expr -> Expr -> Expr
$mCeilDiv' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
CeilDiv' e1 e2 = AppBuiltin2 CeilDiv e1 e2

pattern $bCeilMod' :: Expr -> Expr -> Expr
$mCeilMod' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
CeilMod' e1 e2 = AppBuiltin2 CeilMod e1 e2

pattern $bPow' :: Expr -> Expr -> Expr
$mPow' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Pow' e1 e2 = AppBuiltin2 Pow e1 e2

-- advanced arithmetical functions
pattern $bAbs' :: Expr -> Expr
$mAbs' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Abs' e = AppBuiltin Abs e

pattern $bGcd' :: Expr -> Expr -> Expr
$mGcd' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Gcd' e1 e2 = AppBuiltin2 Gcd e1 e2

pattern $bLcm' :: Expr -> Expr -> Expr
$mLcm' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Lcm' e1 e2 = AppBuiltin2 Lcm e1 e2

pattern $bMin2' :: Type -> Expr -> Expr -> Expr
$mMin2' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Min2' t e1 e2 = AppBuiltin2 (Min2 t) e1 e2

pattern $bMax2' :: Type -> Expr -> Expr -> Expr
$mMax2' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Max2' t e1 e2 = AppBuiltin2 (Max2 t) e1 e2

pattern $bIterate' :: Type -> Expr -> Expr -> Expr -> Expr
$mIterate' :: forall r.
Expr -> (Type -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
Iterate' t n step base = AppBuiltin3 (Iterate t) n step base

-- logical functions
pattern $bNot' :: Expr -> Expr
$mNot' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Not' e = AppBuiltin Not e

pattern $bAnd' :: Expr -> Expr -> Expr
$mAnd' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
And' e1 e2 = AppBuiltin2 And e1 e2

pattern $bOr' :: Expr -> Expr -> Expr
$mOr' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Or' e1 e2 = AppBuiltin2 Or e1 e2

pattern $bImplies' :: Expr -> Expr -> Expr
$mImplies' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Implies' e1 e2 = AppBuiltin2 Implies e1 e2

pattern $bIf' :: Type -> Expr -> Expr -> Expr -> Expr
$mIf' :: forall r.
Expr -> (Type -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
If' t e1 e2 e3 = AppBuiltin3 (If t) e1 e2 e3

-- bitwise functions
pattern $bBitNot' :: Expr -> Expr
$mBitNot' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
BitNot' e = AppBuiltin BitNot e

pattern $bBitAnd' :: Expr -> Expr -> Expr
$mBitAnd' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
BitAnd' e1 e2 = AppBuiltin2 BitAnd e1 e2

pattern $bBitOr' :: Expr -> Expr -> Expr
$mBitOr' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
BitOr' e1 e2 = AppBuiltin2 BitOr e1 e2

pattern $bBitXor' :: Expr -> Expr -> Expr
$mBitXor' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
BitXor' e1 e2 = AppBuiltin2 BitXor e1 e2

pattern $bBitLeftShift' :: Expr -> Expr -> Expr
$mBitLeftShift' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
BitLeftShift' e1 e2 = AppBuiltin2 BitLeftShift e1 e2

pattern $bBitRightShift' :: Expr -> Expr -> Expr
$mBitRightShift' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
BitRightShift' e1 e2 = AppBuiltin2 BitRightShift e1 e2

-- matrix functions

pattern $bMatAp' :: Int -> Int -> Expr -> Expr -> Expr
$mMatAp' :: forall r.
Expr -> (Int -> Int -> Expr -> Expr -> r) -> (Void# -> r) -> r
MatAp' h w e1 e2 = AppBuiltin2 (MatAp h w) e1 e2

pattern $bMatAdd' :: Int -> Int -> Expr -> Expr -> Expr
$mMatAdd' :: forall r.
Expr -> (Int -> Int -> Expr -> Expr -> r) -> (Void# -> r) -> r
MatAdd' h w e1 e2 = AppBuiltin2 (MatAdd h w) e1 e2

pattern $bMatMul' :: Int -> Int -> Int -> Expr -> Expr -> Expr
$mMatMul' :: forall r.
Expr
-> (Int -> Int -> Int -> Expr -> Expr -> r) -> (Void# -> r) -> r
MatMul' h n w e1 e2 = AppBuiltin2 (MatMul h n w) e1 e2

pattern $bMatPow' :: Int -> Expr -> Expr -> Expr
$mMatPow' :: forall r. Expr -> (Int -> Expr -> Expr -> r) -> (Void# -> r) -> r
MatPow' n e1 e2 = AppBuiltin2 (MatPow n) e1 e2

pattern $bVecFloorMod' :: Int -> Expr -> Expr -> Expr
$mVecFloorMod' :: forall r. Expr -> (Int -> Expr -> Expr -> r) -> (Void# -> r) -> r
VecFloorMod' n e1 e2 = AppBuiltin2 (VecFloorMod n) e1 e2

pattern $bMatFloorMod' :: Int -> Int -> Expr -> Expr -> Expr
$mMatFloorMod' :: forall r.
Expr -> (Int -> Int -> Expr -> Expr -> r) -> (Void# -> r) -> r
MatFloorMod' h w e1 e2 = AppBuiltin2 (MatFloorMod h w) e1 e2

-- modular functions
pattern $bModNegate' :: Expr -> Expr -> Expr
$mModNegate' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
ModNegate' e1 e2 = AppBuiltin2 ModNegate e1 e2

pattern $bModPlus' :: Expr -> Expr -> Expr -> Expr
$mModPlus' :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModPlus' e1 e2 e3 = AppBuiltin3 ModPlus e1 e2 e3

pattern $bModMinus' :: Expr -> Expr -> Expr -> Expr
$mModMinus' :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModMinus' e1 e2 e3 = AppBuiltin3 ModMinus e1 e2 e3

pattern $bModMult' :: Expr -> Expr -> Expr -> Expr
$mModMult' :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModMult' e1 e2 e3 = AppBuiltin3 ModMult e1 e2 e3

pattern $bModInv' :: Expr -> Expr -> Expr
$mModInv' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
ModInv' e1 e2 = AppBuiltin2 ModInv e1 e2

pattern $bModPow' :: Expr -> Expr -> Expr -> Expr
$mModPow' :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModPow' e1 e2 e3 = AppBuiltin3 ModPow e1 e2 e3

pattern $bModMatAp' :: Int -> Int -> Expr -> Expr -> Expr -> Expr
$mModMatAp' :: forall r.
Expr
-> (Int -> Int -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModMatAp' h w e1 e2 e3 = AppBuiltin3 (ModMatAp h w) e1 e2 e3

pattern $bModMatAdd' :: Int -> Int -> Expr -> Expr -> Expr -> Expr
$mModMatAdd' :: forall r.
Expr
-> (Int -> Int -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModMatAdd' h w e1 e2 e3 = AppBuiltin3 (ModMatAdd h w) e1 e2 e3

pattern $bModMatMul' :: Int -> Int -> Int -> Expr -> Expr -> Expr -> Expr
$mModMatMul' :: forall r.
Expr
-> (Int -> Int -> Int -> Expr -> Expr -> Expr -> r)
-> (Void# -> r)
-> r
ModMatMul' h n w e1 e2 e3 = AppBuiltin3 (ModMatMul h n w) e1 e2 e3

pattern $bModMatPow' :: Int -> Expr -> Expr -> Expr -> Expr
$mModMatPow' :: forall r.
Expr -> (Int -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ModMatPow' n e1 e2 e3 = AppBuiltin3 (ModMatPow n) e1 e2 e3

-- list functions
pattern $bNil' :: Type -> Expr
$mNil' :: forall r. Expr -> (Type -> r) -> (Void# -> r) -> r
Nil' t = Lit (LitNil t)

pattern $bCons' :: Type -> Expr -> Expr -> Expr
$mCons' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Cons' t e1 e2 = AppBuiltin2 (Cons t) e1 e2

pattern $bSnoc' :: Type -> Expr -> Expr -> Expr
$mSnoc' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Snoc' t e1 e2 = AppBuiltin2 (Snoc t) e1 e2

pattern $bFoldl' :: Type -> Type -> Expr -> Expr -> Expr -> Expr
$mFoldl' :: forall r.
Expr
-> (Type -> Type -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
Foldl' t1 t2 e1 e2 e3 = AppBuiltin3 (Foldl t1 t2) e1 e2 e3

pattern $bScanl' :: Type -> Type -> Expr -> Expr -> Expr -> Expr
$mScanl' :: forall r.
Expr
-> (Type -> Type -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
Scanl' t1 t2 e1 e2 e3 = AppBuiltin3 (Scanl t1 t2) e1 e2 e3

pattern $bBuild' :: Type -> Expr -> Expr -> Expr -> Expr
$mBuild' :: forall r.
Expr -> (Type -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
Build' t e1 e2 e3 = AppBuiltin3 (Build t) e1 e2 e3

pattern $bLen' :: Type -> Expr -> Expr
$mLen' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
Len' t e = AppBuiltin (Len t) e

pattern $bMap' :: Type -> Type -> Expr -> Expr -> Expr
$mMap' :: forall r.
Expr -> (Type -> Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Map' t1 t2 f e = AppBuiltin2 (Map t1 t2) f e

pattern $bFilter' :: Type -> Expr -> Expr -> Expr
$mFilter' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Filter' t f e = AppBuiltin2 (Filter t) f e

pattern $bAt' :: Type -> Expr -> Expr -> Expr
$mAt' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
At' t e1 e2 = AppBuiltin2 (At t) e1 e2

pattern $bSetAt' :: Type -> Expr -> Expr -> Expr -> Expr
$mSetAt' :: forall r.
Expr -> (Type -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
SetAt' t e1 e2 e3 = AppBuiltin3 (SetAt t) e1 e2 e3

pattern $bElem' :: Type -> Expr -> Expr -> Expr
$mElem' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Elem' t e1 e2 = AppBuiltin2 (Elem t) e1 e2

pattern $bSum' :: Expr -> Expr
$mSum' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Sum' e = AppBuiltin Sum e

pattern $bProduct' :: Expr -> Expr
$mProduct' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Product' e = AppBuiltin Product e

pattern $bModSum' :: Expr -> Expr -> Expr
$mModSum' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
ModSum' e1 e2 = AppBuiltin2 ModSum e1 e2

pattern $bModProduct' :: Expr -> Expr -> Expr
$mModProduct' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
ModProduct' e1 e2 = AppBuiltin2 ModProduct e1 e2

pattern $bMin1' :: Type -> Expr -> Expr
$mMin1' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
Min1' t e = AppBuiltin (Min1 t) e

pattern $bMax1' :: Type -> Expr -> Expr
$mMax1' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
Max1' t e = AppBuiltin (Max1 t) e

pattern $bArgMin' :: Type -> Expr -> Expr
$mArgMin' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
ArgMin' t e = AppBuiltin (ArgMin t) e

pattern $bArgMax' :: Type -> Expr -> Expr
$mArgMax' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
ArgMax' t e = AppBuiltin (ArgMax t) e

pattern $bAll' :: Expr -> Expr
$mAll' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
All' e = AppBuiltin All e

pattern $bAny' :: Expr -> Expr
$mAny' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Any' e = AppBuiltin Any e

pattern $bSorted' :: Type -> Expr -> Expr
$mSorted' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
Sorted' t e = AppBuiltin (Sorted t) e

pattern $bReversed' :: Type -> Expr -> Expr
$mReversed' :: forall r. Expr -> (Type -> Expr -> r) -> (Void# -> r) -> r
Reversed' t e = AppBuiltin (Reversed t) e

pattern $bRange1' :: Expr -> Expr
$mRange1' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Range1' e = AppBuiltin Range1 e

pattern $bRange2' :: Expr -> Expr -> Expr
$mRange2' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Range2' e1 e2 = AppBuiltin2 Range2 e1 e2

pattern $bRange3' :: Expr -> Expr -> Expr -> Expr
$mRange3' :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
Range3' e1 e2 e3 = AppBuiltin3 Range3 e1 e2 e3

-- tuple functions
pattern $bTuple' :: [Type] -> Expr
$mTuple' :: forall r. Expr -> ([Type] -> r) -> (Void# -> r) -> r
Tuple' ts = Lit (LitBuiltin (Tuple ts))

pattern $bProj' :: [Type] -> Int -> Expr -> Expr
$mProj' :: forall r. Expr -> ([Type] -> Int -> Expr -> r) -> (Void# -> r) -> r
Proj' ts n e = AppBuiltin (Proj ts n) e

-- arithmetical relations
pattern $bLessThan' :: Type -> Expr -> Expr -> Expr
$mLessThan' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
LessThan' t e1 e2 = AppBuiltin2 (LessThan t) e1 e2

pattern $bLessEqual' :: Type -> Expr -> Expr -> Expr
$mLessEqual' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
LessEqual' t e1 e2 = AppBuiltin2 (LessEqual t) e1 e2

pattern $bGreaterThan' :: Type -> Expr -> Expr -> Expr
$mGreaterThan' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
GreaterThan' t e1 e2 = AppBuiltin2 (GreaterThan t) e1 e2

pattern $bGreaterEqual' :: Type -> Expr -> Expr -> Expr
$mGreaterEqual' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
GreaterEqual' t e1 e2 = AppBuiltin2 (GreaterEqual t) e1 e2

-- equality relations (polymorphic)
pattern $bEqual' :: Type -> Expr -> Expr -> Expr
$mEqual' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
Equal' t e1 e2 = AppBuiltin2 (Equal t) e1 e2

pattern $bNotEqual' :: Type -> Expr -> Expr -> Expr
$mNotEqual' :: forall r. Expr -> (Type -> Expr -> Expr -> r) -> (Void# -> r) -> r
NotEqual' t e1 e2 = AppBuiltin2 (NotEqual t) e1 e2

-- combinational functions
pattern $bFact' :: Expr -> Expr
$mFact' :: forall r. Expr -> (Expr -> r) -> (Void# -> r) -> r
Fact' e = AppBuiltin Fact e

pattern $bChoose' :: Expr -> Expr -> Expr
$mChoose' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Choose' e1 e2 = AppBuiltin2 Choose e1 e2

pattern $bPermute' :: Expr -> Expr -> Expr
$mPermute' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
Permute' e1 e2 = AppBuiltin2 Permute e1 e2

pattern $bMultiChoose' :: Expr -> Expr -> Expr
$mMultiChoose' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
MultiChoose' e1 e2 = AppBuiltin2 MultiChoose e1 e2

-- data structures
pattern $bConvexHullTrickInit' :: Expr
$mConvexHullTrickInit' :: forall r. Expr -> (Void# -> r) -> (Void# -> r) -> r
ConvexHullTrickInit' = Lit (LitBuiltin ConvexHullTrickInit)

pattern $bConvexHullTrickGetMin' :: Expr -> Expr -> Expr
$mConvexHullTrickGetMin' :: forall r. Expr -> (Expr -> Expr -> r) -> (Void# -> r) -> r
ConvexHullTrickGetMin' cht a = AppBuiltin2 ConvexHullTrickGetMin cht a

pattern $bConvexHullTrickInsert' :: Expr -> Expr -> Expr -> Expr
$mConvexHullTrickInsert' :: forall r. Expr -> (Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
ConvexHullTrickInsert' cht a b = AppBuiltin3 ConvexHullTrickInsert cht a b

pattern $bSegmentTreeInitList' :: Semigroup' -> Expr -> Expr
$mSegmentTreeInitList' :: forall r. Expr -> (Semigroup' -> Expr -> r) -> (Void# -> r) -> r
SegmentTreeInitList' semigrp a = AppBuiltin (SegmentTreeInitList semigrp) a

pattern $bSegmentTreeGetRange' :: Semigroup' -> Expr -> Expr -> Expr -> Expr
$mSegmentTreeGetRange' :: forall r.
Expr
-> (Semigroup' -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
SegmentTreeGetRange' semigrp segtree e1 e2 = AppBuiltin3 (SegmentTreeGetRange semigrp) segtree e1 e2

pattern $bSegmentTreeSetPoint' :: Semigroup' -> Expr -> Expr -> Expr -> Expr
$mSegmentTreeSetPoint' :: forall r.
Expr
-> (Semigroup' -> Expr -> Expr -> Expr -> r) -> (Void# -> r) -> r
SegmentTreeSetPoint' semigrp segtree e1 e2 = AppBuiltin3 (SegmentTreeSetPoint semigrp) segtree e1 e2

-- errors
pattern $bBottom' :: Type -> String -> Expr
$mBottom' :: forall r. Expr -> (Type -> String -> r) -> (Void# -> r) -> r
Bottom' t err = Lit (LitBottom t err)