module Quox.Definition import public Quox.No import public Quox.Syntax import public Data.SortedMap import public Control.Monad.Reader import Decidable.Decidable public export data DefBody q = Concrete (Term q 0 0) | Postulate namespace DefBody public export (.term0) : DefBody q -> Maybe (Term q 0 0) (Concrete t).term0 = Just t (Postulate).term0 = Nothing public export record Definition' q (isGlobal : Pred q) where constructor MkDef qty : q type0 : Term q 0 0 body0 : DefBody q {auto 0 qtyGlobal : isGlobal qty} public export 0 Definition : (q : Type) -> IsQty q => Type Definition q = Definition' q IsGlobal public export %inline mkPostulate : IsQty q => (qty : q) -> (0 _ : IsGlobal qty) => (type0 : Term q 0 0) -> Definition q mkPostulate qty type0 = MkDef {qty, type0, body0 = Postulate} public export %inline mkDef : IsQty q => (qty : q) -> (0 _ : IsGlobal qty) => (type0, term0 : Term q 0 0) -> Definition q mkDef qty type0 term0 = MkDef {qty, type0, body0 = Concrete term0} public export %inline (.qtyP) : forall q, isGlobal. Definition' q isGlobal -> Subset q isGlobal g.qtyP = Element g.qty g.qtyGlobal parameters {d, n : Nat} public export %inline (.type) : Definition' q _ -> Term q d n g.type = g.type0 // shift0 d // shift0 n public export %inline (.term) : Definition' q _ -> Maybe (Term q d n) g.term = g.body0.term0 <&> \t => t // shift0 d // shift0 n public export %inline toElim : Definition' q _ -> Maybe $ Elim q d n toElim def = pure $ !def.term :# def.type public export 0 IsZero : IsQty q => Pred $ Definition q IsZero g = IsZero g.qty public export %inline isZero : (p : IsQty q) => Dec1 $ Definition.IsZero @{p} isZero g = isZero g.qty public export 0 Definitions' : (q : Type) -> Pred q -> Type Definitions' q isGlobal = SortedMap Name $ Definition' q isGlobal public export 0 Definitions : (q : Type) -> IsQty q => Type Definitions q = Definitions' q IsGlobal public export 0 HasDefs' : (q : Type) -> (q -> Type) -> (Type -> Type) -> Type HasDefs' q isGlobal = MonadReader (Definitions' q isGlobal) public export 0 HasDefs : (q : Type) -> IsQty q => (Type -> Type) -> Type HasDefs q = HasDefs' q IsGlobal public export %inline lookupElim : forall isGlobal. {d, n : Nat} -> Name -> Definitions' q isGlobal -> Maybe (Elim q d n) lookupElim x defs = toElim !(lookup x defs)