Skip to content
Snippets Groups Projects
Commit 65aa60b5 authored by Iavor S. Diatchki's avatar Iavor S. Diatchki Committed by Herbert Valerio Riedel
Browse files

Implement ordering comparisons for type-level naturals and symbols.

This is done with two built-in type families: `CmpNat and `CmpSymbol`.
Both of these return a promoted `Ordering` type (EQ, LT, or GT).

(cherry picked from commit 5e4bdb5f)
parent 09062bdf
No related branches found
No related tags found
No related merge requests found
...@@ -1472,6 +1472,7 @@ rep1TyConKey = mkPreludeTyConUnique 156 ...@@ -1472,6 +1472,7 @@ rep1TyConKey = mkPreludeTyConUnique 156
typeNatKindConNameKey, typeSymbolKindConNameKey, typeNatKindConNameKey, typeSymbolKindConNameKey,
typeNatAddTyFamNameKey, typeNatMulTyFamNameKey, typeNatExpTyFamNameKey, typeNatAddTyFamNameKey, typeNatMulTyFamNameKey, typeNatExpTyFamNameKey,
typeNatLeqTyFamNameKey, typeNatSubTyFamNameKey typeNatLeqTyFamNameKey, typeNatSubTyFamNameKey
, typeSymbolCmpTyFamNameKey, typeNatCmpTyFamNameKey
:: Unique :: Unique
typeNatKindConNameKey = mkPreludeTyConUnique 160 typeNatKindConNameKey = mkPreludeTyConUnique 160
typeSymbolKindConNameKey = mkPreludeTyConUnique 161 typeSymbolKindConNameKey = mkPreludeTyConUnique 161
...@@ -1480,6 +1481,8 @@ typeNatMulTyFamNameKey = mkPreludeTyConUnique 163 ...@@ -1480,6 +1481,8 @@ typeNatMulTyFamNameKey = mkPreludeTyConUnique 163
typeNatExpTyFamNameKey = mkPreludeTyConUnique 164 typeNatExpTyFamNameKey = mkPreludeTyConUnique 164
typeNatLeqTyFamNameKey = mkPreludeTyConUnique 165 typeNatLeqTyFamNameKey = mkPreludeTyConUnique 165
typeNatSubTyFamNameKey = mkPreludeTyConUnique 166 typeNatSubTyFamNameKey = mkPreludeTyConUnique 166
typeSymbolCmpTyFamNameKey = mkPreludeTyConUnique 167
typeNatCmpTyFamNameKey = mkPreludeTyConUnique 168
ntTyConKey:: Unique ntTyConKey:: Unique
ntTyConKey = mkPreludeTyConUnique 174 ntTyConKey = mkPreludeTyConUnique 174
......
...@@ -20,6 +20,8 @@ module TysWiredIn ( ...@@ -20,6 +20,8 @@ module TysWiredIn (
ltDataCon, ltDataConId, ltDataCon, ltDataConId,
eqDataCon, eqDataConId, eqDataCon, eqDataConId,
gtDataCon, gtDataConId, gtDataCon, gtDataConId,
promotedOrderingTyCon,
promotedLTDataCon, promotedEQDataCon, promotedGTDataCon,
-- * Char -- * Char
charTyCon, charDataCon, charTyCon_RDR, charTyCon, charDataCon, charTyCon_RDR,
...@@ -831,5 +833,19 @@ promotedTrueDataCon = promoteDataCon trueDataCon ...@@ -831,5 +833,19 @@ promotedTrueDataCon = promoteDataCon trueDataCon
promotedFalseDataCon = promoteDataCon falseDataCon promotedFalseDataCon = promoteDataCon falseDataCon
\end{code} \end{code}
Promoted Ordering
\begin{code}
promotedOrderingTyCon
, promotedLTDataCon
, promotedEQDataCon
, promotedGTDataCon
:: TyCon
promotedOrderingTyCon = promoteTyCon orderingTyCon
promotedLTDataCon = promoteDataCon ltDataCon
promotedEQDataCon = promoteDataCon eqDataCon
promotedGTDataCon = promoteDataCon gtDataCon
\end{code}
...@@ -12,9 +12,14 @@ import Coercion ( Role(..) ) ...@@ -12,9 +12,14 @@ import Coercion ( Role(..) )
import TcRnTypes ( Xi ) import TcRnTypes ( Xi )
import CoAxiom ( CoAxiomRule(..), BuiltInSynFamily(..) ) import CoAxiom ( CoAxiomRule(..), BuiltInSynFamily(..) )
import Name ( Name, BuiltInSyntax(..) ) import Name ( Name, BuiltInSyntax(..) )
import TysWiredIn ( typeNatKind, mkWiredInTyConName import TysWiredIn ( typeNatKind, typeSymbolKind
, mkWiredInTyConName
, promotedBoolTyCon , promotedBoolTyCon
, promotedFalseDataCon, promotedTrueDataCon , promotedFalseDataCon, promotedTrueDataCon
, promotedOrderingTyCon
, promotedLTDataCon
, promotedEQDataCon
, promotedGTDataCon
) )
import TysPrim ( tyVarList, mkArrowKinds ) import TysPrim ( tyVarList, mkArrowKinds )
import PrelNames ( gHC_TYPELITS import PrelNames ( gHC_TYPELITS
...@@ -23,6 +28,8 @@ import PrelNames ( gHC_TYPELITS ...@@ -23,6 +28,8 @@ import PrelNames ( gHC_TYPELITS
, typeNatExpTyFamNameKey , typeNatExpTyFamNameKey
, typeNatLeqTyFamNameKey , typeNatLeqTyFamNameKey
, typeNatSubTyFamNameKey , typeNatSubTyFamNameKey
, typeNatCmpTyFamNameKey
, typeSymbolCmpTyFamNameKey
) )
import FastString ( FastString, fsLit ) import FastString ( FastString, fsLit )
import qualified Data.Map as Map import qualified Data.Map as Map
...@@ -39,6 +46,8 @@ typeNatTyCons = ...@@ -39,6 +46,8 @@ typeNatTyCons =
, typeNatExpTyCon , typeNatExpTyCon
, typeNatLeqTyCon , typeNatLeqTyCon
, typeNatSubTyCon , typeNatSubTyCon
, typeNatCmpTyCon
, typeSymbolCmpTyCon
] ]
typeNatAddTyCon :: TyCon typeNatAddTyCon :: TyCon
...@@ -103,6 +112,45 @@ typeNatLeqTyCon = ...@@ -103,6 +112,45 @@ typeNatLeqTyCon =
, sfInteractInert = interactInertLeq , sfInteractInert = interactInertLeq
} }
typeNatCmpTyCon :: TyCon
typeNatCmpTyCon =
mkSynTyCon name
(mkArrowKinds [ typeNatKind, typeNatKind ] orderingKind)
(take 2 $ tyVarList typeNatKind)
[Nominal,Nominal]
(BuiltInSynFamTyCon ops)
NoParentTyCon
where
name = mkWiredInTyConName UserSyntax gHC_TYPELITS (fsLit "CmpNat")
typeNatCmpTyFamNameKey typeNatCmpTyCon
ops = BuiltInSynFamily
{ sfMatchFam = matchFamCmpNat
, sfInteractTop = interactTopCmpNat
, sfInteractInert = \_ _ _ _ -> []
}
typeSymbolCmpTyCon :: TyCon
typeSymbolCmpTyCon =
mkSynTyCon name
(mkArrowKinds [ typeSymbolKind, typeSymbolKind ] orderingKind)
(take 2 $ tyVarList typeSymbolKind)
[Nominal,Nominal]
(BuiltInSynFamTyCon ops)
NoParentTyCon
where
name = mkWiredInTyConName UserSyntax gHC_TYPELITS (fsLit "CmpSymbol")
typeSymbolCmpTyFamNameKey typeSymbolCmpTyCon
ops = BuiltInSynFamily
{ sfMatchFam = matchFamCmpSymbol
, sfInteractTop = interactTopCmpSymbol
, sfInteractInert = \_ _ _ _ -> []
}
-- Make a binary built-in constructor of kind: Nat -> Nat -> Nat -- Make a binary built-in constructor of kind: Nat -> Nat -> Nat
mkTypeNatFunTyCon2 :: Name -> BuiltInSynFamily -> TyCon mkTypeNatFunTyCon2 :: Name -> BuiltInSynFamily -> TyCon
...@@ -127,6 +175,8 @@ axAddDef ...@@ -127,6 +175,8 @@ axAddDef
, axMulDef , axMulDef
, axExpDef , axExpDef
, axLeqDef , axLeqDef
, axCmpNatDef
, axCmpSymbolDef
, axAdd0L , axAdd0L
, axAdd0R , axAdd0R
, axMul0L , axMul0L
...@@ -137,6 +187,8 @@ axAddDef ...@@ -137,6 +187,8 @@ axAddDef
, axExp0R , axExp0R
, axExp1R , axExp1R
, axLeqRefl , axLeqRefl
, axCmpNatRefl
, axCmpSymbolRefl
, axLeq0L , axLeq0L
, axSubDef , axSubDef
, axSub0R , axSub0R
...@@ -154,6 +206,25 @@ axExpDef = mkBinAxiom "ExpDef" typeNatExpTyCon $ ...@@ -154,6 +206,25 @@ axExpDef = mkBinAxiom "ExpDef" typeNatExpTyCon $
axLeqDef = mkBinAxiom "LeqDef" typeNatLeqTyCon $ axLeqDef = mkBinAxiom "LeqDef" typeNatLeqTyCon $
\x y -> Just $ bool (x <= y) \x y -> Just $ bool (x <= y)
axCmpNatDef = mkBinAxiom "CmpNatDef" typeNatCmpTyCon
$ \x y -> Just $ ordering (compare x y)
axCmpSymbolDef =
CoAxiomRule
{ coaxrName = fsLit "CmpSymbolDef"
, coaxrTypeArity = 2
, coaxrAsmpRoles = []
, coaxrRole = Nominal
, coaxrProves = \ts cs ->
case (ts,cs) of
([s,t],[]) ->
do x <- isStrLitTy s
y <- isStrLitTy t
return (mkTyConApp typeSymbolCmpTyCon [s,t] ===
ordering (compare x y))
_ -> Nothing
}
axSubDef = mkBinAxiom "SubDef" typeNatSubTyCon $ axSubDef = mkBinAxiom "SubDef" typeNatSubTyCon $
\x y -> fmap num (minus x y) \x y -> fmap num (minus x y)
...@@ -168,6 +239,10 @@ axExp1L = mkAxiom1 "Exp1L" $ \t -> (num 1 .^. t) === num 1 ...@@ -168,6 +239,10 @@ axExp1L = mkAxiom1 "Exp1L" $ \t -> (num 1 .^. t) === num 1
axExp0R = mkAxiom1 "Exp0R" $ \t -> (t .^. num 0) === num 1 axExp0R = mkAxiom1 "Exp0R" $ \t -> (t .^. num 0) === num 1
axExp1R = mkAxiom1 "Exp1R" $ \t -> (t .^. num 1) === t axExp1R = mkAxiom1 "Exp1R" $ \t -> (t .^. num 1) === t
axLeqRefl = mkAxiom1 "LeqRefl" $ \t -> (t <== t) === bool True axLeqRefl = mkAxiom1 "LeqRefl" $ \t -> (t <== t) === bool True
axCmpNatRefl = mkAxiom1 "CmpNatRefl"
$ \t -> (cmpNat t t) === ordering EQ
axCmpSymbolRefl = mkAxiom1 "CmpSymbolRefl"
$ \t -> (cmpSymbol t t) === ordering EQ
axLeq0L = mkAxiom1 "Leq0L" $ \t -> (num 0 <== t) === bool True axLeq0L = mkAxiom1 "Leq0L" $ \t -> (num 0 <== t) === bool True
typeNatCoAxiomRules :: Map.Map FastString CoAxiomRule typeNatCoAxiomRules :: Map.Map FastString CoAxiomRule
...@@ -176,6 +251,8 @@ typeNatCoAxiomRules = Map.fromList $ map (\x -> (coaxrName x, x)) ...@@ -176,6 +251,8 @@ typeNatCoAxiomRules = Map.fromList $ map (\x -> (coaxrName x, x))
, axMulDef , axMulDef
, axExpDef , axExpDef
, axLeqDef , axLeqDef
, axCmpNatDef
, axCmpSymbolDef
, axAdd0L , axAdd0L
, axAdd0R , axAdd0R
, axMul0L , axMul0L
...@@ -186,6 +263,8 @@ typeNatCoAxiomRules = Map.fromList $ map (\x -> (coaxrName x, x)) ...@@ -186,6 +263,8 @@ typeNatCoAxiomRules = Map.fromList $ map (\x -> (coaxrName x, x))
, axExp0R , axExp0R
, axExp1R , axExp1R
, axLeqRefl , axLeqRefl
, axCmpNatRefl
, axCmpSymbolRefl
, axLeq0L , axLeq0L
, axSubDef , axSubDef
] ]
...@@ -211,6 +290,12 @@ s .^. t = mkTyConApp typeNatExpTyCon [s,t] ...@@ -211,6 +290,12 @@ s .^. t = mkTyConApp typeNatExpTyCon [s,t]
(<==) :: Type -> Type -> Type (<==) :: Type -> Type -> Type
s <== t = mkTyConApp typeNatLeqTyCon [s,t] s <== t = mkTyConApp typeNatLeqTyCon [s,t]
cmpNat :: Type -> Type -> Type
cmpNat s t = mkTyConApp typeNatCmpTyCon [s,t]
cmpSymbol :: Type -> Type -> Type
cmpSymbol s t = mkTyConApp typeSymbolCmpTyCon [s,t]
(===) :: Type -> Type -> Pair Type (===) :: Type -> Type -> Pair Type
x === y = Pair x y x === y = Pair x y
...@@ -232,6 +317,25 @@ isBoolLitTy tc = ...@@ -232,6 +317,25 @@ isBoolLitTy tc =
| tc == promotedTrueDataCon -> return True | tc == promotedTrueDataCon -> return True
| otherwise -> Nothing | otherwise -> Nothing
orderingKind :: Kind
orderingKind = mkTyConApp promotedOrderingTyCon []
ordering :: Ordering -> Type
ordering o =
case o of
LT -> mkTyConApp promotedLTDataCon []
EQ -> mkTyConApp promotedEQDataCon []
GT -> mkTyConApp promotedGTDataCon []
isOrderingLitTy :: Type -> Maybe Ordering
isOrderingLitTy tc =
do (tc1,[]) <- splitTyConApp_maybe tc
case () of
_ | tc1 == promotedLTDataCon -> return LT
| tc1 == promotedEQDataCon -> return EQ
| tc1 == promotedGTDataCon -> return GT
| otherwise -> Nothing
known :: (Integer -> Bool) -> TcType -> Bool known :: (Integer -> Bool) -> TcType -> Bool
known p x = case isNumLitTy x of known p x = case isNumLitTy x of
Just a -> p a Just a -> p a
...@@ -258,6 +362,8 @@ mkBinAxiom str tc f = ...@@ -258,6 +362,8 @@ mkBinAxiom str tc f =
_ -> Nothing _ -> Nothing
} }
mkAxiom1 :: String -> (Type -> Pair Type) -> CoAxiomRule mkAxiom1 :: String -> (Type -> Pair Type) -> CoAxiomRule
mkAxiom1 str f = mkAxiom1 str f =
CoAxiomRule CoAxiomRule
...@@ -328,6 +434,25 @@ matchFamLeq [s,t] ...@@ -328,6 +434,25 @@ matchFamLeq [s,t]
mbY = isNumLitTy t mbY = isNumLitTy t
matchFamLeq _ = Nothing matchFamLeq _ = Nothing
matchFamCmpNat :: [Type] -> Maybe (CoAxiomRule, [Type], Type)
matchFamCmpNat [s,t]
| Just x <- mbX, Just y <- mbY =
Just (axCmpNatDef, [s,t], ordering (compare x y))
| tcEqType s t = Just (axCmpNatRefl, [s], ordering EQ)
where mbX = isNumLitTy s
mbY = isNumLitTy t
matchFamCmpNat _ = Nothing
matchFamCmpSymbol :: [Type] -> Maybe (CoAxiomRule, [Type], Type)
matchFamCmpSymbol [s,t]
| Just x <- mbX, Just y <- mbY =
Just (axCmpSymbolDef, [s,t], ordering (compare x y))
| tcEqType s t = Just (axCmpSymbolRefl, [s], ordering EQ)
where mbX = isStrLitTy s
mbY = isStrLitTy t
matchFamCmpSymbol _ = Nothing
{------------------------------------------------------------------------------- {-------------------------------------------------------------------------------
Interact with axioms Interact with axioms
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
...@@ -415,6 +540,17 @@ interactTopLeq [s,t] r ...@@ -415,6 +540,17 @@ interactTopLeq [s,t] r
mbZ = isBoolLitTy r mbZ = isBoolLitTy r
interactTopLeq _ _ = [] interactTopLeq _ _ = []
interactTopCmpNat :: [Xi] -> Xi -> [Pair Type]
interactTopCmpNat [s,t] r
| Just EQ <- isOrderingLitTy r = [ s === t ]
interactTopCmpNat _ _ = []
interactTopCmpSymbol :: [Xi] -> Xi -> [Pair Type]
interactTopCmpSymbol [s,t] r
| Just EQ <- isOrderingLitTy r = [ s === t ]
interactTopCmpSymbol _ _ = []
{------------------------------------------------------------------------------- {-------------------------------------------------------------------------------
...@@ -466,6 +602,10 @@ interactInertLeq _ _ _ _ = [] ...@@ -466,6 +602,10 @@ interactInertLeq _ _ _ _ = []
{- ----------------------------------------------------------------------------- {- -----------------------------------------------------------------------------
These inverse functions are used for simplifying propositions using These inverse functions are used for simplifying propositions using
concrete natural numbers. concrete natural numbers.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment