packages feed

ghc-typelits-presburger-0.2.0.5: examples/simple-arith.hs

{-# LANGUAGE DataKinds, TypeOperators, GADTs, TypeFamilies, ExplicitForAll, FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables, CPP #-}
#if !MIN_VERSION_singletons(2,4,1)
{-# LANGUAGE KindSignatures #-}
#endif
{-# OPTIONS_GHC -fplugin GHC.TypeLits.Presburger #-}
module Main where
import Data.Type.Equality
import GHC.TypeLits       (Nat, type (<=?), CmpNat)
import Proof.Propositional (Empty(..))
import Proof.Propositional (IsTrue(Witness))
import Data.Singletons.Prelude
import Data.Singletons.Prelude.List

#if !MIN_VERSION_singletons(2,4,1)
import qualified Data.Singletons.Prelude as Sing
type n <= m = (n :: Nat) Sing.:<= (m :: Nat)
infix 4 <=
type n - m = (n :: Nat) Sing.:- (m :: Nat)
infixl 6 -
type n + m = (n :: Nat) Sing.:+ (m :: Nat)
infixl 6 +
type n * m = (n :: Nat) Sing.:* (m :: Nat)
infixl 7 *
#endif

type n <=! m = IsTrue (n <=? m)
infix 4 <=!

natLen :: (Length xs <= Length ys) ~ 'True
       => proxy xs -> proxy ys -> Length ys - Length xs + Length xs :~: Length ys
natLen _ _ = Refl

natLeqZero' :: ((n <= 0) ~ 'True) => proxy n -> n :~: 0
natLeqZero' _ = Refl

plusLeq :: (n <= m) ~ 'True => proxy (n :: Nat) -> proxy m -> ((m - n) + n :~: m)
plusLeq _ _ = Refl

(%:<=?) :: Sing n -> Sing m -> Sing (n <=? m)
n %:<=? m = case sCompare n m of
  SLT -> STrue
  SEQ -> STrue
  SGT -> SFalse

hoge :: ((n + 1 <=? n) ~ 'False) => proxy n -> ()
hoge _ = ()

hoge' :: (((n + 1) <= n) ~ 'False) => proxy n -> ()
hoge' _ = ()

bar :: ((2 * (n + 1)) ~ ((2 * n) + 2)) => proxy n -> ()
bar _ = ()

trans :: proxy n -> proxy m -> n <=! m -> (n + 1) <=! (m + 1)
trans _ _  Witness = Witness

eqv :: proxy n -> proxy m -> (n <=? m) :~: ((n + 1) <=? (m + 1))
eqv _ _ = Refl

leqSucc :: proxy n -> proxy m -> IsTrue ((n + 1) <= m) -> CmpNat n m :~: 'LT
leqSucc _ _ Witness = Refl

predSucc :: forall proxy n. Empty (n <=! 0) => proxy n -> IsTrue (n + 1 <=? 2 * n)
predSucc _ = Witness

main :: IO ()
main = putStrLn "finished"

succLEqLTSucc :: Sing m -> Compare 0 (m + 1) :~: 'LT
succLEqLTSucc _ = Refl

succCompare :: Sing (n :: Nat) -> Sing m -> CmpNat n m :~: CmpNat (n + 1) (m + 1)
succCompare _ _ = Refl

eqToRefl :: Sing (n :: Nat) -> Sing (m :: Nat) -> CmpNat n m :~: 'EQ -> n :~: m
eqToRefl _n _m Refl = Refl