blob: 99960e154a0a261189d83725110e69a905b250bc [file] [log] [blame] [edit]
--
-- Copyright 2019, Data61
-- Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-- ABN 41 687 119 230.
--
-- This software may be distributed and modified according to the terms of
-- the GNU General Public License version 2. Note that NO WARRANTY is provided.
-- See "LICENSE_GPLv2.txt" for details.
--
-- @TAG(DATA61_GPL)
--
{-# LANGUAGE DataKinds #-}
{- LANGUAGE DeriveFoldable #-}
{- LANGUAGE DeriveFunctor #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Fin where
import Cogent.Compiler (__impossible)
#if __GLASGOW_HASKELL__ < 711
import Cogent.Compiler (__ghc_t3927)
#endif
import Cogent.Util
import Data.Ex
import Data.Nat
-- import Data.PropEq
import Control.Applicative
import Data.Binary
#if __GLASGOW_HASKELL__ >= 709
import Data.Foldable (find)
#else
import Data.Foldable
#endif
import Data.Monoid
import Data.Traversable
import GHC.Generics (Generic, Rep, V1)
import Prelude hiding (length, repeat, splitAt, take, unzip, zip, zipWith)
import qualified Text.PrettyPrint.ANSI.Leijen as L
data Fin :: Nat -> * where
FZero :: Fin ('Suc n)
FSuc :: Fin n -> Fin ('Suc n)
deriving instance Eq (Fin n)
deriving instance Show (Fin n)
deriving instance Ord (Fin n)
instance Generic (Fin 'Zero) where
type Rep (Fin 'Zero) = V1
instance Binary (Fin 'Zero) where
-- These functions don't need to be defined, as 'Fin \'Zero' has no inhabitants.
f0 = FZero
f1 = FSuc f0
f2 = FSuc f1
finInt :: Fin n -> Int
finInt FZero = 0
finInt (FSuc f) = finInt f + 1
finNat :: Fin n -> Nat
finNat FZero = n0
finNat (FSuc f) = Suc $ finNat f
atList :: [t] -> Fin a -> t
atList [] _ = __impossible "atList"
atList (x:xs) FZero = x
atList (x:xs) (FSuc s) = atList xs s
widen :: Fin n -> Fin ('Suc n)
widen FZero = FZero
widen (FSuc n) = FSuc (widen n)
widenN :: Fin n -> SNat m -> Fin (n :+: m)
widenN f (SZero) = f
widenN f (SSuc n) = widen (widenN f n)
upshift :: Fin n -> SNat m -> Fin (n :+: m)
upshift n SZero = n
upshift n (SSuc m) = FSuc (upshift n m)
-- liftIdx idx var means:
-- if idx <= var, var -> var + 1; otherwise intact
liftIdx :: Fin ('Suc n) -> Fin n -> Fin ('Suc n)
liftIdx FZero v = FSuc v
liftIdx (FSuc i) FZero = FZero
liftIdx (FSuc i) (FSuc v) = FSuc $ liftIdx i v
maxFin :: SNat n -> Fin ('Suc n)
maxFin SZero = FZero
maxFin (SSuc n) = FSuc $ maxFin n