1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE DeriveFoldable #-}
3 {-# LANGUAGE DeriveFunctor #-}
4 {-# LANGUAGE DeriveTraversable #-}
5 {-# LANGUAGE EmptyDataDecls #-}
6 {-# LANGUAGE ExistentialQuantification #-}
7 {-# LANGUAGE FlexibleContexts #-}
8 {-# LANGUAGE FlexibleInstances #-}
10 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
11 {-# LANGUAGE NamedFieldPuns #-}
12 {-# LANGUAGE NoImplicitPrelude #-}
13 {-# LANGUAGE OverloadedStrings #-}
14 {-# LANGUAGE Rank2Types #-}
15 {-# LANGUAGE ScopedTypeVariables #-}
16 {-# LANGUAGE StandaloneDeriving #-}
17 {-# LANGUAGE TupleSections #-}
18 {-# LANGUAGE TypeFamilies #-}
19 {-# LANGUAGE ViewPatterns #-}
20 {-# OPTIONS_GHC -fno-warn-tabs #-}
21 module Calculus.Lambda.Omega.Explicit where
25 import qualified Data.Char as Char
26 import Data.Function (on)
27 import Data.Map.Strict (Map)
28 import qualified Data.Map.Strict as Map
29 import Data.Maybe (catMaybes)
30 import Data.Maybe (fromJust)
31 import Data.Monoid ((<>))
32 import Data.Text (Text)
33 import qualified Data.Text as Text
34 import Data.Text.Buildable (Buildable(..))
35 import qualified Data.Text.Lazy as TL
36 import qualified Data.Text.Lazy.Builder as Builder
37 import Data.Typeable as Typeable
39 import Data.Eq (Eq(..))
40 import Data.Maybe (Maybe(..), maybe)
41 import Data.Foldable (Foldable(..))
42 import Data.Either (Either(..))
43 import Data.List ((++))
44 import Data.Monoid (Monoid(..))
45 import Data.Function (($), (.), id, const, flip)
46 import Data.String (String)
47 import Data.Traversable (Traversable(..))
48 import Data.Ord (Ord(..))
49 import Control.Applicative (Applicative(..), (<$>))
50 import Text.Show (Show(..), showParen, showString)
51 import Prelude (Int, Integer, Num(..), error)
56 import Calculus.Abstraction.DeBruijn.Generalized
59 -- | 'Term' @var@ forms the main /Abstract Syntax Tree/
60 -- of the present /explicitely typed/ (aka. /à la Church/) /lambda-calculus/,
61 -- whose /term constructors/ are:
63 -- * 'TeTy_Var': for /term variable/ or /type variable/, see 'Abstraction'.
64 -- * 'TeTy_App': for /term application/ or /type application/, see 'normalize'.
65 -- * 'Term_Abst': for /term abstraction/ (aka. /λ-term/), see 'Abstraction'.
66 -- * 'Type_Abst': for /type abstraction/ (aka. /Π-type/, aka. /dependent product/), see 'sort_of_type_abst'.
67 -- * 'Type_Sort': for /sort constant/ of a /Pure Type System/ (aka. /PTS/), see 'sort_of_sort'.
68 -- * 'TeTy_Axiom': for /custom axiom/, see 'Axiomable'.
70 -- Note that 'Type' and 'Term' share this same data-type
71 -- (hence the varying prefixes of the Haskell /data constructors/),
72 -- which avoids duplication of code for their common operations.
74 -- Note that this Haskell type DOES NOT guarantee by itself
75 -- the /well-formedness/ of the 'Term' (or 'Type'),
76 -- for instance one can construct such @malformed_type@: @(* *)@:
79 -- > let star = 'Type_Sort' 'sort_star_mono'
80 -- > let malformed_type = 'TeTy_App' star star
81 -- > 'left' 'type_error_msg' '$' 'type_of' 'context' malformed_type
82 -- Left ('Type_Error_Msg_Not_a_function' … )
85 -- Though an Haskell type could be crafted to get a stronger guarantee
86 -- over the /well-formedness/, it is not done here
87 -- for the following reasons :
89 -- 1. The /well-formedness/ alone is not really useful,
90 -- it’s the /well-typedness/ which matters,
91 -- and this depends upon a specific 'Context'.
93 -- 2. Guaranteeing a good combinaison of 'TeTy_App' with respect to 'Term_Abst' (or 'Type_Abst')
94 -- while using the 'Abstraction' approach could be done:
95 -- for instance by using @GADTs@ on 'Term'
96 -- to add an Haskell /type parameter/ @ty@ (aka. /index/)
97 -- constrained to @(i -> o)@, @i@ or @o@ depending on the /term constructors/,
98 -- and then by defining Haskell /type classes/
99 -- replicating: 'Functor', 'Foldable', 'Traversable', 'Monad' and 'Monad_Module_Left',
100 -- but working on /natural transformations/ (giving /indexed functors/, /indexed monads/, …),
101 -- however this yields to a significant increase in code complexity,
102 -- which is not really worth the resulting guarantee
103 -- (to my mind, here, simplicity has priority
104 -- over comprehensive automated checking,
105 -- especially since it’s a research project
106 -- where I don't fully know all what will be needed
107 -- and thus appreciate some level of flexibility).
109 -- So, with this actual 'Term' data-type:
110 -- 'type_of' MUST be used to check the /well-formedness/ along the /well-typedness/
111 -- of a 'Term' (or equivalently of a 'Type') with respect to a 'Context'.
114 | TeTy_App (Term var) (Term var)
115 | Term_Abst (Suggest Var_Name) (Type var) (Abstraction (Suggest Var_Name) (Term) var)
116 | Type_Abst (Suggest Var_Name) (Type var) (Abstraction (Suggest Var_Name) (Type) var)
119 ( Axiomable (Axiom ax)
121 ) => TeTy_Axiom (Axiom ax)
122 -- deriving (Eq, Show, Functor, Foldable, Traversable)
123 -- | 'Eq' instance ignores /bound variables/' 'Var_Name',
124 -- effectively testing for /α-equivalence/.
125 instance (Eq var, Show var) => Eq (Term var) where
126 TeTy_Var x == TeTy_Var y = x == y
127 TeTy_App xf xa == TeTy_App yf ya = xf == yf && xa == ya
128 Term_Abst _ xty xf == Term_Abst _ yty yf = xty == yty && xf == yf -- NOTE: ignore Var_Name
129 Type_Abst _ xty xf == Type_Abst _ yty yf = xty == yty && xf == yf -- NOTE: ignore Var_Name
130 Type_Sort x == Type_Sort y = x == y
131 TeTy_Axiom x == TeTy_Axiom y = x `axiom_eq` y
133 deriving instance Show var => Show (Term var)
134 -- | A 'Functor' instance capturing the notion of /variable renaming/.
135 deriving instance Functor Term
136 deriving instance Foldable Term
137 deriving instance Traversable Term
138 deriving instance Typeable Term
139 instance Show1 Term where showsPrec1 = showsPrec
140 instance Eq1 Term where (==#) = (==)
142 instance Applicative (Term) where
145 -- | A 'Monad' instance capturing the notion of /variable substitution/ with /capture-avoiding/.
146 instance Monad (Term) where
148 Type_Sort s >>= _ = Type_Sort s
149 TeTy_Axiom a >>= _ = TeTy_Axiom a
150 TeTy_Var v >>= go = go v
151 TeTy_App f x >>= go = TeTy_App (f >>= go) (x >>= go)
152 Term_Abst v f_in f >>= go = Term_Abst v (f_in >>= go) (f >>>= go)
153 Type_Abst v f_in f >>= go = Type_Abst v (f_in >>= go) (f >>>= go)
154 instance Buildable var => Buildable (Term var) where
155 build = go False False
157 go :: forall v. (Buildable v)
161 go parenBind parenApp te =
163 Type_Sort s -> build s
164 TeTy_Axiom ax -> build ax
165 TeTy_Var v -> build v
167 (if parenApp then "(" else "")
168 <> go True False f <> " " <> go True True x
169 <> (if parenApp then ")" else "")
171 (if parenBind then "(" else "")
172 <> "λ"{- <> "\\"-} <> go_abst parenBind parenApp te
173 Type_Abst (Suggest x) f_in f_out ->
174 (if parenBind then "(" else "")
176 then go True False f_in
177 else "∀" <> "(" <> build x <> ":" <> go False False f_in <> ")" )
179 <> go False False (abstract_normalize f_out)
180 <> (if parenBind then ")" else "")
181 go_abst :: forall v. (Buildable v)
185 go_abst parenBind parenApp te =
187 Term_Abst (Suggest x) f_in f ->
188 let body = abstract_normalize f in
191 "(" <> go_var_def x <> ":" <> go False False f_in <> ")"
192 <> " " <> go_abst parenBind parenApp body
194 "(" <> go_var_def x <> ":" <> go False False f_in <> ")"
196 <> go False False body
197 <> (if parenBind then ")" else "")
198 _ -> go parenBind parenApp te
199 go_var_def x = if x == "" then "_" else build x
202 -- | Four /PTS/ /sort constants/
203 -- are formed by combining
204 -- 'Type_Level' and 'Type_Morphism':
206 -- * @*m@: the 'Sort' to form the 'Type' of a monomorphic 'Term'.
207 -- * @*p@: the 'Sort' to form the 'Type' of a polymorphic 'Term'.
208 -- * @□m@: the 'Sort' to form the 'Type' of a monomorphic 'Type'.
209 -- * @□p@: the 'Sort' to form the 'Type' of a polymorphic 'Type'.
210 type Sort = (Type_Level, Type_Morphism)
211 instance Buildable Sort where
213 (sort, morphism) -> build sort <> build morphism
215 -- | @*m@: the 'Sort' to form the 'Type' of a monomorphic 'Term'.
216 sort_star_mono :: Sort
217 sort_star_mono = (Type_Level_0, Type_Morphism_Mono)
219 -- | @*p@: the 'Sort' to form the 'Type' of a polymorphic 'Term'.
220 sort_star_poly :: Sort
221 sort_star_poly = (Type_Level_0, Type_Morphism_Poly)
223 -- *** Type 'Type_Level'
225 = Type_Level_0 -- ^ aka. /@*@ (Star) sort constant/.
226 | Type_Level_1 -- ^ aka. /@□@ (Box) sort constant/.
227 deriving (Eq, Ord, Show)
228 instance Buildable Type_Level where
233 -- *** Type 'Type_Morphism'
237 deriving (Eq, Ord, Show)
238 instance Buildable Type_Morphism where
240 Type_Morphism_Mono -> "" -- "m"
241 Type_Morphism_Poly -> "p"
243 -- | /PTS/ axioms for 'Sort':
245 -- * AXIOM: @⊦ *m : □m@
246 -- * AXIOM: @⊦ *p : □p@
247 sort_of_sort :: Sort -> Either Type_Error_Msg Sort
248 sort_of_sort (Type_Level_0, Type_Morphism_Mono)
249 = return (Type_Level_1, Type_Morphism_Mono)
251 -- The type of MONOMORPHIC types of terms,
252 -- is of type: the type of types of MONOMORPHIC types of terms
253 sort_of_sort (Type_Level_0, Type_Morphism_Poly)
254 = return (Type_Level_1, Type_Morphism_Poly)
256 -- The type of POLYMORPHIC types of terms,
257 -- is of type: the type of types of POLYMORPHIC types of terms
258 sort_of_sort s = Left $ Type_Error_Msg_No_sort_for_sort s
262 -- | A record to keep a same 'Term' (or 'Type')
263 -- in several forms (and avoid to 'normalize' it multiple times).
266 { form_given :: Term var
267 , form_normal :: Term var -- ^ 'normalize'-d version of 'form_given'.
268 } deriving (Functor, Show)
270 -- | Return a 'Form' from a given 'Term'.
271 form :: (Eq var, Ord var, Variable var, Typeable var) => Context var -> Term var -> Form var
272 form ctx te = Form te (normalize ctx te)
274 -- | Reduce given 'Term' (or 'Type') to /normal form/ (NF)
275 -- by recursively performing /β-reduction/ and /η-reduction/.
277 -- Note that any well-typed 'Term' (i.e. for which 'type_of' returns a 'Type')
278 -- is /strongly normalizing/ (i.e. 'normalize' always returns,
279 -- and its returned 'Term' is unique up to /α-equivalence/).
280 normalize :: (Eq var, Ord var, Variable var, Typeable var) => Context var -> Term var -> Term var
284 go_debug :: (Eq var, Ord var, Variable var, Typeable var)
289 go_debug args ctx te =
292 ++ "\n te = " ++ show te
293 ++ "\n args = " ++ show args
297 go :: (Eq var, Ord var, Variable var, Typeable var)
302 go args ctx (TeTy_Var ((form_normal <$>) . context_item_term <=< context_lookup ctx -> Just te))
303 -- NOTE: Replace variable mapped by the context
305 [] -> te -- NOTE: no need to normalize again
307 go args ctx (TeTy_App f x)
308 -- NOTE: Normalize and collect applied arguments,
309 -- this to normalize an argument only once for all patterns.
310 = go (go [] ctx x : args) ctx f
311 go [] ctx (Term_Abst x f_in f)
312 -- NOTE: η-reduce: Term_Abst _ (TeTy_App f (TeTy_Var (Var_Bound _)) ==> f
313 = (Term_Abst x (go [] ctx f_in) ||| id)
314 (abst_eta_reduce ctx f)
315 go (x:args) ctx (Term_Abst _ _ f)
316 -- NOTE: β-reduce: TeTy_App (Term_Abst _ _ f) x ==> f x
317 = go args ctx (const x `unabstract` f)
318 go args ctx (Type_Abst x f_in f_out)
319 -- NOTE: Recurse in Type_Abst fields
320 = term_apps (Type_Abst x (go [] ctx f_in) (go_scope ctx f_out)) args
321 go args ctx (TeTy_Axiom (flip (axiom_normalize ctx) args -> Just (r_te, r_args)))
322 -- NOTE: Normalize axiom
325 -- NOTE: Reapply remaining arguments, normalized
329 :: (Eq var, Eq bound, Ord var, Ord bound, Variable var, Variable bound, Typeable var, Typeable bound)
331 -> Abstraction bound (Term) var
332 -> Either (Abstraction bound (Term) var) -- could not η-reduce
333 (Term var) -- could η-reduce
334 abst_eta_reduce ctx =
336 let new_ctx = context_push_nothing ctx in
337 case go [] new_ctx abst_body of
338 te@(TeTy_App t (TeTy_Var (Var_Bound _{-Term_Abst's variable-}))) ->
341 Var_Free v -> Right v
342 -- NOTE: decrement the DeBruijn indexing by one
343 -- to reflect the removal of the Term_Abst.
344 Var_Bound _ -> Left $ abstract_generalize te
345 -- NOTE: cannot η-reduce because Term_Abst's variable
346 -- is also used within t.
348 te -> Left $ abstract_generalize te
353 :: (Eq var, Eq bound, Ord var, Ord bound, Variable var, Variable bound, Typeable var, Typeable bound)
355 -> Abstraction bound (Term) var
356 -> Abstraction bound (Term) var
358 abstract_generalize .
359 go [] (context_push_nothing ctx) .
362 -- | Reduce given 'Term' to /Weak Head Normal Form/ (WHNF).
366 -- * https://wiki.haskell.org/Weak_head_normal_form
367 whnf :: (Ord var, Variable var, Typeable var) => Context var -> Term var -> Term var
370 go :: (Ord var, Variable var, Typeable var) => [Term var] -> Context var -> Term var -> Term var
371 go args ctx (TeTy_Var ((form_given <$>) .
372 context_item_term <=< context_lookup ctx
374 -- NOTE: Replace any variable mapped by the context
376 go args ctx (TeTy_App f a)
377 -- NOTE: Collect applied arguments
379 go (x:args) ctx (Term_Abst _ _ f)
380 -- NOTE: β-reduce: TeTy_App (Term_Abst _ _ f) x ==> f x
381 = go args ctx (const x `unabstract` f)
382 go args ctx (TeTy_Axiom (flip (axiom_normalize ctx) args -> Just (r_te, r_args)))
383 -- NOTE: Normalize axiom
384 -- TODO: maybe introduce an 'axiom_whnf' instead of 'axiom_normalize'
387 -- NOTE: Reapply remaining arguments, normalized
390 -- | Apply multiple 'Term's to a 'Term',
391 -- useful to reconstruct a 'Term' while normalizing (see 'normalize' or 'whnf').
392 term_apps :: Term var -> [Term var] -> Term var
393 term_apps = foldl TeTy_App
395 -- | /α-equivalence relation/, synonym of @(==)@.
397 -- Return 'True' iif. both given 'Term's are the same,
398 -- up to renaming the /bound variables/ it contains (see instance 'Eq' of 'Suggest').
399 alpha_equiv :: (Eq var, Show var) => Term var -> Term var -> Bool
402 -- | /αβη-equivalence relation/.
403 equiv :: (Eq var, Ord var, Variable var, Typeable var) => Context var -> Term var -> Term var -> Bool
404 equiv ctx = (==) `on` normalize ctx
408 -- | 'Type' and 'Term' share the same data-type.
411 -- | Construct the 'Type' of the given 'Term',
412 -- effectively checking for the /well-formedness/
413 -- and /well-typedness/ of a 'Term' (or 'Type').
415 -- Note that a 'Type' is always to be considered
416 -- according to a given 'Context':
417 -- 'type_of' applied to the same 'Term'
418 -- but on different 'Context's
419 -- may return a different 'Type' or 'Type_Error'.
421 :: (Eq var, Ord var, Variable var, Typeable var)
424 -> Either Type_Error (Type var)
427 Type_Sort s -> (err +++ Type_Sort) $ sort_of_sort s
431 <$> context_lookup ctx v of
433 Nothing -> Left $ err $ Type_Error_Msg_Unbound_variable v
435 return $ axiom_type_of ctx ax
437 f_ty <- whnf ctx <$> type_of ctx f
440 Type_Abst _ i o -> return (i, o)
441 _ -> Left $ err $ Type_Error_Msg_Not_a_function f f_ty
442 x_ty <- type_of ctx x
443 case equiv ctx x_ty f_in of
444 True -> return $ const x `unabstract` f_out
445 False -> Left $ err $ Type_Error_Msg_Function_argument_mismatch f_in x_ty
446 Term_Abst (Suggest x) f_in f -> do
447 _ <- type_of ctx f_in
450 then context_push_nothing ctx
451 else context_push_type ctx (Suggest x) f_in
452 f_out <- type_of new_ctx (abstract_normalize f)
453 let abst_ty = Type_Abst (Suggest x) f_in (abstract_generalize f_out)
454 _ <- type_of ctx abst_ty
456 Type_Abst (Suggest x) f_in f -> do
457 f_in_ty <- type_of ctx f_in
458 f_in_so <- case whnf ctx f_in_ty of
459 Type_Sort s -> return s
460 f_in_ty_whnf -> Left $ err $ Type_Error_Msg_Invalid_input_type f_in_ty_whnf
463 then context_push_nothing ctx
464 else context_push_type ctx (Suggest x) f_in
465 f_out_ty <- type_of new_ctx (abstract_normalize f)
466 f_out_so <- case whnf new_ctx f_out_ty of
467 Type_Sort s -> return s
468 f_out_ty_whnf -> Left $ Type_Error ctx term $
469 Type_Error_Msg_Invalid_output_type f_out_ty_whnf (x, f_out_ty_whnf)
470 (err +++ Type_Sort) $
471 sort_of_type_abst f_in_so f_out_so
473 err = Type_Error ctx term
475 -- | Check that the given 'Term' has the given 'Type'.
477 :: (Eq var, Ord var, Variable var, Typeable var)
481 -> Either (Type_Error) ()
482 check ctx expect_ty te =
483 type_of ctx te >>= \actual_ty ->
484 if equiv ctx expect_ty actual_ty
486 else Left $ Type_Error
487 { type_error_ctx = ctx
488 , type_error_term = te
489 , type_error_msg = Type_Error_Msg_Type_mismatch expect_ty actual_ty (normalize ctx expect_ty) (normalize ctx actual_ty)
492 -- | Check that a 'Term' is closed, i.e. has no /unbound variables/.
493 close :: Term Var_Name -> Either Type_Error (Term ())
498 Type_Error context te $
499 Type_Error_Msg_Unbound_variable var
501 -- | Return the /unbound variables/ of given 'Term'.
502 unbound_vars :: Ord var => Term var -> Map var ()
503 unbound_vars = foldr (flip Map.insert ()) mempty
505 -- | /Dependent product/ rules: @s ↝ t : u@, i.e.
506 -- "abstracting something of type @s@ out of something of type @t@ gives something of type @u@".
508 -- Given two 'Sort': @s@ and @t@, return a 'Sort': @u@,
509 -- when ('Type_Abst' @s@ @t@) is ruled legal
510 -- and has 'Type': 'Type_Sort' ('Sort' @u@).
512 -- The usual /PTS/ rules for /λω/
513 -- (or equivalently /Type Assignment Systems/ (TAS) rules for /System Fω/)
516 -- * RULE: @⊦ * ↝ * : *@, aka. /simple types/:
517 -- "abstracting a term out of a term is valid and gives a term",
518 -- as in /PTS λ→/ or /TAS F1/.
519 -- * RULE: @⊦ □ ↝ * : *@, aka. /parametric polymorphism/:
520 -- "abstracting a type out of a term is valid and gives a term",
521 -- as in /PTS λ2/ or /TAS F2/ (aka. /System F/).
522 -- * RULE: @⊦ □ ↝ □ : □@, aka. /constructors of types/:
523 -- "abstracting a type out of a type is valid and gives a type",
524 -- as in /PTS λω/ or /TAS Fω/.
526 -- Note that the fourth usual rule is not ruled valid here:
528 -- * RULE: @⊦ * ↝ □ : □@, aka. /dependent types/:
529 -- "abstracting a term out of a type is valid and gives a type",
530 -- as in /PTS λPω/ or /TAS DFω/ (aka. /Calculus of constructions/).
532 -- However, to contain /impredicativity/ (see 'Axiom_MonoPoly')
533 -- the above /sort constants/ are split in two,
534 -- and the above rules adapted
535 -- to segregate between /monomorphic types/ (aka. /monotypes/)
536 -- and /polymorphic types/ (aka. /polytypes/):
538 -- * RULE: @⊦ *m ↝ *m : *m@, i.e. /simple types/, without /parametric polymorphism/.
539 -- * RULE: @⊦ *m ↝ *p : *p@, i.e. /simple types/, preserving /parametric polymorphism/ capture.
541 -- * RULE: @⊦ *p ↝ *m : *p@, i.e. /higher-rank polymorphism/, preserving /parametric polymorphism/ capture.
542 -- * RULE: @⊦ *p ↝ *p : *p@, i.e. /higher-rank polymorphism/, preserving /parametric polymorphism/ capture.
544 -- * RULE: @⊦ □m ↝ *m : *p@, i.e. /parametric polymorphism/, captured within @*p@ ('sort_star_poly').
545 -- * RULE: @⊦ □m ↝ *p : *p@, i.e. /parametric polymorphism/, preserving capture.
547 -- * RULE: @⊦ □m ↝ □m : □m@, i.e. /constructors of types/, without /parametric polymorphism/.
548 -- * RULE: @⊦ □m ↝ □p : □p@, i.e. /constructors of types/, preserving /parametric polymorphism/ capture.
550 -- Note that what is important here is
551 -- that there is no rule of the form: @⊦ □p ↝ _ : _@,
552 -- which forbids abstracting a /polymorphic type/ out of anything,
553 -- in particular the type @*p -> *m@ is forbidden,
554 -- though 'Axiom_MonoPoly'
555 -- is given to make it possible within it.
559 -- * /Henk: a typed intermediate language/,
560 -- Simon Peyton Jones, Erik Meijer, 20 May 1997,
561 -- https://research.microsoft.com/en-us/um/people/simonpj/papers/henk.ps.gz
565 -> Either Type_Error_Msg Sort
569 (Type_Level_0, Type_Morphism_Mono)
571 = return (Type_Level_0, m)
572 -- RULE: *m ↝ *m : *m
573 -- RULE: *m ↝ *p : *p
574 -- abstracting: a MONOMORPHIC term
575 -- out of : a MONOMORPHIC (resp. POLYMORPHIC) term
576 -- forms : a MONOMORPHIC (resp. POLYMORPHIC) term
580 (Type_Level_0, Type_Morphism_Poly)
582 = return (Type_Level_0, Type_Morphism_Poly)
583 -- RULE: *p ↝ *m : *p
584 -- RULE: *p ↝ *p : *p
585 -- abstracting: a POLYMORPHIC term
587 -- forms : a POLYMORPHIC term
591 (Type_Level_1, Type_Morphism_Mono)
593 = return (Type_Level_0, Type_Morphism_Poly)
594 -- RULE: □m ↝ *m : *p
595 -- RULE: □m ↝ *p : *p
596 -- abstracting: a MONOMORPHIC type of a term
598 -- forms : a POLYMORPHIC term
602 (Type_Level_1, Type_Morphism_Mono)
604 = return (Type_Level_1, m)
605 -- RULE: □m ↝ □m : □m
606 -- RULE: □m ↝ □p : □p
607 -- abstracting: a MONOMORPHIC type of a term
608 -- out of : a MONOMORPHIC (resp. POLYMORPHIC) type of a term
609 -- forms : a MONOMORPHIC (resp. POLYMORPHIC) type of a term
611 -- NOTE: □m ↝ □p : □p is useful for instance to build List_:
612 -- let List_ : (A:*m) -> *p = \(A:*m) -> (R:*m) -> (A -> R -> R) -> R -> R
613 -- let List : (A:*m) -> *m = \(A:*m) -> Monotype (List_ A)
619 (Type_Level_0, Type_Morphism_Mono)
621 = return (Type_Level_1, m)
622 -- RULE: *m ↝ □m : □m
623 -- RULE: *m ↝ □p : □p
624 -- abstracting: a MONOMORPHIC term
625 -- out of : a MONOMORPHIC (resp. POLYMORPHIC) type of a term
626 -- forms : a MONOMORPHIC (resp. POLYMORPHIC) type of a term
629 (Type_Level_0, Type_Morphism_Poly)
631 = return (Type_Level_1, Type_Morphism_Poly)
632 -- RULE: *p ↝ □m : □p
633 -- RULE: *p ↝ □p : □p
634 -- abstracting: a POLYMORPHIC term
635 -- out of : a type of a term
636 -- forms : a POLYMORPHIC type of a term
642 = Left $ Type_Error_Msg_Illegal_type_abstraction s t
643 -- RULE: * ↝ □ : Illegal
644 -- abstracting: a term
645 -- out of : a type of a term
648 -- No impredicativity (only allowed through 'Axiom_MonoPoly')
650 s@(Type_Level_1, Type_Morphism_Poly)
652 = Left $ Type_Error_Msg_Illegal_type_abstraction s t
653 -- RULE: □p ↝ _ : Illegal
654 -- abstracting: a POLYMORPHIC type of a term
658 -- ** Type 'Type_Error'
660 = forall var. (Ord var, Show var, Buildable var)
662 { type_error_ctx :: Context var
663 , type_error_term :: Term var
664 , type_error_msg :: Type_Error_Msg
666 deriving instance Show Type_Error
667 instance Buildable Type_Error where
668 build (Type_Error ctx te msg) =
670 <> "\n " <> build msg
671 <> "\n Term:" <> " " <> build te
677 (Map.fromList $ (, ()) <$> context_vars ctx) in
680 _ -> "\n Context:\n" <> build ctx{context_vars=vars}
683 -- ** Type 'Type_Error_Msg'
685 = Type_Error_Msg_No_sort_for_sort Sort
686 | Type_Error_Msg_Illegal_type_abstraction Sort Sort
687 | forall var. Variable var => Type_Error_Msg_Invalid_input_type (Type var)
688 | forall var. Variable var => Type_Error_Msg_Invalid_output_type (Type var) (Var_Name, Type var)
689 | forall var. Variable var => Type_Error_Msg_Not_a_function (Term var) (Type var)
690 | forall var. Variable var => Type_Error_Msg_Function_argument_mismatch (Type var) (Type var)
691 | forall var. Variable var => Type_Error_Msg_Unbound_variable var
692 | forall var. Variable var => Type_Error_Msg_Unbound_axiom var
693 | forall var. Variable var => Type_Error_Msg_Type_mismatch (Type var) (Type var) (Type var) (Type var)
694 deriving instance Show Type_Error_Msg
695 instance Buildable Type_Error_Msg where
698 Type_Error_Msg_No_sort_for_sort x ->
701 Type_Error_Msg_Illegal_type_abstraction x y ->
702 "Illegal_type_abstraction: "
703 <> build x <> " -> " <> build y
704 Type_Error_Msg_Invalid_input_type ty ->
705 "Invalid_input_type: "
707 Type_Error_Msg_Invalid_output_type f_out (x, f_in) ->
708 "Invalid_output_type: "
709 <> build f_out <> "\n"
710 <> " Input binding: "
711 <> "(" <> build x <> " : " <> build f_in <> ")"
712 Type_Error_Msg_Not_a_function f f_ty ->
717 Type_Error_Msg_Function_argument_mismatch f_in x_ty ->
718 "Function_argument_mismatch: \n"
719 <> " Function domain: " <> build f_in <> "\n"
720 <> " Argument type: " <> build x_ty
721 Type_Error_Msg_Unbound_variable var ->
724 Type_Error_Msg_Unbound_axiom var ->
727 Type_Error_Msg_Type_mismatch x y nx ny ->
729 <> " Expected type: " <> build x <> " == " <> build nx <> "\n"
730 <> " Actual type: " <> build y <> " == " <> build ny
734 -- | Map variables of type @var@
735 -- to their 'Type' and maybe also to their 'Term',
736 -- both in 'form_given' and 'form_normal'.
739 { context_vars :: [var]
740 -- ^ used to dump the 'Context'
741 , context_lookup :: var -> Maybe (Context_Item var)
742 -- ^ used to query the 'Context'
743 , context_lift :: Typeable var => Var_Name -> var
744 -- ^ used to promote a ('Term' 'Var_Name') to ('Term' @var@)
745 , context_unlift :: Typeable var => var -> Var_Name
746 -- ^ used to unpromote ('Term' @var@) to ('Term' 'Var_Name')
748 data Context_Item var
750 { context_item_term :: Maybe (Form var)
751 , context_item_type :: Form var
752 } deriving (Functor, Show)
754 instance Show var => Show (Context var) where
755 showsPrec n ctx@Context{context_vars=vars} =
757 showString "Context " .
759 (k, fromJust $ context_item_type
760 <$> context_lookup ctx k))
763 showsPrec n (catMaybes $ (\k ->
764 (k,) . form_given <$>
765 (context_item_term =<< context_lookup ctx k))
767 instance Buildable var => Buildable (Context var) where
768 build ctx@Context{context_vars=vars} =
771 <> maybe mempty (\ty -> " : " <> build (form_given ty))
772 (context_item_type <$> context_lookup ctx var)
774 <> maybe mempty (\te -> " = " <> build (form_given te))
775 (context_item_term =<< context_lookup ctx var)
780 context :: Context Var_Name
781 context = Context [] (const Nothing) id id
783 context_apply :: Context var -> Term var -> Term var
784 context_apply ctx te =
786 maybe (TeTy_Var var) id $ form_normal <$>
787 (context_item_term =<< context_lookup ctx var)
790 :: (Eq var, Ord var, Variable var, Typeable var)
794 -> Context (Var bound var)
796 ctx@(Context keys lookup var_lift var_unlift)
802 , context_lookup = \var ->
803 (Var_Free `fmap`) `fmap`
807 { context_item_term = Nothing
808 , context_item_type = form ctx ty
810 Var_Free v -> lookup v
811 , context_lift = Var_Free . var_lift
812 , context_unlift = \var ->
814 Var_Bound _ -> error "context_push_type: context_unlift"
815 Var_Free v -> var_unlift v
819 :: (Show bound, Buildable (Context var), Typeable var, Typeable bound)
821 -> Context (Var bound var)
823 (Context keys lookup var_lift var_unlift) =
825 { context_vars = Var_Free `fmap` keys
826 , context_lookup = \var ->
827 (Var_Free `fmap`) `fmap`
829 Var_Bound _ -> Nothing
830 Var_Free v -> lookup v
831 , context_lift = Var_Free . var_lift
832 , context_unlift = \var ->
834 -- DEBUG: Var_Bound (cast -> Just (Suggest b)) -> b
835 -- DEBUG: Var_Bound (cast -> Just b) -> b
836 Var_Bound b -> error $ "context_push_nothing: context_unlift: " ++ show b
837 Var_Free v -> var_unlift v
840 context_from_env :: Env -> Context Var_Name
841 context_from_env env =
843 { context_vars = Map.keys env
844 , context_lookup = \var ->
845 (\item -> Context_Item
846 { context_item_term = Just $ env_item_term item
847 , context_item_type = env_item_type item
848 }) <$> env_lookup env var
850 , context_unlift = id
853 context_relift :: forall from_var to_var.
860 context_relift from_ctx ty to_ctx =
861 ( context_lift to_ctx
862 . context_unlift from_ctx
866 context_from_list :: Eq var => [(var, Type var)] -> Context var
867 context_from_list l =
869 { context_vars = fst <$> l
870 , context_lookup_type = \var -> List.lookup var l
873 -- | Return /free term variables/ of an 'Abstraction'-ed 'Term'.
875 :: Abstraction bound (Term) var
876 -> Term (Var bound var)
877 ftv = abstract_normalize
882 = Map Var_Name Env_Item
885 { env_item_term :: Form Var_Name
886 , env_item_type :: Form Var_Name
895 { env_item_term = form ctx te
896 , env_item_type = form ctx ty
899 env_lookup :: Env -> Var_Name -> Maybe (Env_Item)
900 env_lookup env var = Map.lookup var env
902 env_insert :: Var_Name -> Term Var_Name -> Type Var_Name -> Env -> Env
903 env_insert var te ty env =
904 let ctx = context_from_env env in
905 Map.insert var (env_item ctx te ty) env
910 -- deriving instance Typeable Axiom
912 axiom_cast :: (Typeable a, Typeable b) => Axiom a -> Maybe (Axiom b)
916 -- | 'Axioms' are made of 'Axiom's injected in regular 'Env_Item's,
917 -- see 'env_item_from_axiom'.
921 :: ( Axiomable (Axiom ax)
923 => Context Var_Name -> Axiom ax -> Env_Item
924 env_item_from_axiom ctx ax =
926 { env_item_term = form ctx $ TeTy_Axiom ax
927 , env_item_type = form ctx $ axiom_type_of ctx ax
930 -- ** Class 'Axiomable'
932 -- class (Eq ax, Show ax, Buildable ax, Typeable ax) => Axiomable_Type_Of ax where
933 -- class (Eq ax, Show ax, Buildable ax, Typeable ax) => Axiomable_Normalize ax where
934 -- class (Eq ax, Show ax, Buildable ax, Typeable ax) => Axiomable_Eq ax where
936 -- | Instances of this class are 'Axiom's injectable in 'TeTy_Axiom', that is:
938 -- * they have a 'Type', given by 'axiom_type_of',
939 -- * and they can perform an optional reduction
940 -- within 'normalize' or 'whnf', given by 'axiom_normalize'.
942 ( Eq ax, Show ax, Buildable ax, Typeable ax
943 -- , Axiomable_Type_Of ax
944 -- , Axiomable_Normalize ax
946 ) => Axiomable ax where
948 :: forall var. Typeable var
949 => Context var -> ax -> Type var
950 -- ^ Return the 'Type' of the given 'Axiomable' instance.
952 :: forall var. (Typeable var, Ord var, Variable var)
953 => Context var -> ax -> [Term var] -> Maybe (Term var, [Term var])
954 -- ^ Custom-'normalize': given a typing 'Context',
955 -- an 'Axiomable' instance
956 -- and a list of arguments, return:
958 -- * 'Nothing': if the axiom performs no reduction,
959 -- * 'Just': with the reducted 'Term' and the arguments not used by the reduction.
961 -- Default: @\\_ctx _ax _args -> Nothing@
962 axiom_normalize _ctx _ax _args = Nothing
963 axiom_eq :: ax -> (forall ax'. Axiomable ax' => ax' -> Bool)
964 -- ^ Custom-bipolymorphic-@(==)@:
965 -- given an 'Axiomable' instance
966 -- return a function to test if any
967 -- other 'Axiomable' instance
968 -- is equal to the first instance given.
970 -- Default: @maybe False (x ==) (cast y)@
971 axiom_eq x y = maybe False (x ==) (cast y)
973 -- ** Class 'Axiom_Type'
975 -- | A class to embed an Haskell-type within an 'Axiom'.
976 class Axiom_Type h where
977 axiom_type :: Axiom h
978 -- ^ Construct (implicitely) an Haskell-term representing
979 -- the Haskell-type @h@.
980 axiom_Type :: Axiom h -> Type Var_Name
981 -- ^ Return a 'Type' representing the Haskell-type @h@,
982 -- given through its representation as an Haskell-term
983 -- (which is an 'Axiom' and thus has itself a 'Type',
984 -- given by its 'axiom_type_of').
987 :: (Axiom_Type h, Typeable h)
988 => h -> Axiom (Axiom_Term h)
990 Axiom_Term x $ \ctx ->
991 context_lift ctx <$> axiom_Type (axiom_type::Axiom h)
993 -- ** Type 'Axiom_Type_Assume'
994 -- | An instance to use 'Type' as an 'Axiom'.
995 data Axiom_Type_Assume
996 newtype instance Axiom (Axiom_Type_Assume)
997 = Axiom_Type_Assume (Type Var_Name)
999 instance Buildable (Axiom Axiom_Type_Assume) where
1000 build (Axiom_Type_Assume ty) = "(_:" <> build ty <> ")"
1001 instance Axiomable (Axiom Axiom_Type_Assume) where
1002 axiom_type_of ctx (Axiom_Type_Assume ty) =
1003 context_lift ctx <$> ty
1005 -- ** Type 'Axiom_MonoPoly'
1006 -- | Non-'Sort' constants for /boxed parametric polymorphism/.
1008 -- Used to embed /polymorphic types/ into first-class /monomorphic types/
1009 -- via explicit injection ('Axiom_Term_MonoPoly_Box') and projection ('Axiom_Term_MonoPoly_UnBox') functions.
1011 -- Special treatment of 'Axiom_MonoPoly' constructors is done in 'normalize' and 'whnf'
1012 -- to remove adjacent pairs of 'Axiom_Term_MonoPoly_Box' / 'Axiom_Term_MonoPoly_UnBox'
1013 -- or 'Axiom_Term_MonoPoly_UnBox' / 'Axiom_Term_MonoPoly_Box'.
1017 -- * /Recasting MLF/, Didier Le Botlan, Didier Rémy, June 2009,
1018 -- https://hal.inria.fr/inria-00156628
1020 data instance Axiom Axiom_MonoPoly
1021 = Axiom_Type_MonoPoly
1022 | Axiom_Term_MonoPoly_Box
1023 | Axiom_Term_MonoPoly_UnBox
1024 deriving (Eq, Ord, Show)
1025 instance Buildable (Axiom Axiom_MonoPoly) where
1026 build ax = case ax of
1027 Axiom_Type_MonoPoly -> "Monotype"
1028 Axiom_Term_MonoPoly_Box -> "monotype"
1029 Axiom_Term_MonoPoly_UnBox -> "polytype"
1030 instance Axiomable (Axiom Axiom_MonoPoly) where
1031 axiom_type_of ctx ax =
1033 Axiom_Type_MonoPoly ->
1034 -- Monotype : *p -> *m
1035 Type_Abst "" (Type_Sort sort_star_poly) $
1036 (const Nothing `abstract`) $
1037 Type_Sort sort_star_mono
1038 Axiom_Term_MonoPoly_Box ->
1039 -- monotype : (Polytype : *p) -> Polytype -> Monotype Polytype
1040 (context_lift ctx <$>) $
1041 Type_Abst "Polytype" (Type_Sort sort_star_poly) $
1042 (("Polytype" =?) `abstract`) $
1043 Type_Abst "" (TeTy_Var "Polytype") $
1044 (("" =?) `abstract`) $
1046 (TeTy_Axiom $ Axiom_Type_MonoPoly)
1047 (TeTy_Var "Polytype")
1048 Axiom_Term_MonoPoly_UnBox ->
1049 -- polytype : (Polytype : *p) -> Monotype Polytype -> Polytype
1050 (context_lift ctx <$>) $
1051 Type_Abst "Polytype" (Type_Sort sort_star_poly) $
1052 (("Polytype" =?) `abstract`) $
1055 (TeTy_Axiom $ Axiom_Type_MonoPoly)
1056 (TeTy_Var "Polytype")) $
1057 (("" =?) `abstract`) $
1059 axiom_normalize _ctx
1060 Axiom_Term_MonoPoly_UnBox
1061 (_ty:TeTy_App (TeTy_App (TeTy_Axiom (axiom_cast -> Just Axiom_Term_MonoPoly_Box)) _ty') te:args)
1062 -- NOTE: Remove adjacent Axiom_Term_MonoPoly_UnBox / Axiom_Term_MonoPoly_Box
1064 axiom_normalize _ctx
1065 Axiom_Term_MonoPoly_Box
1066 (_ty:TeTy_App (TeTy_App (TeTy_Axiom (axiom_cast -> Just Axiom_Term_MonoPoly_UnBox)) _ty') te:args)
1067 -- NOTE: Remove adjacent Axiom_Term_MonoPoly_Box / Axiom_Term_MonoPoly_UnBox
1069 axiom_normalize _ctx _ax _args = Nothing
1071 -- | /PTS/ axioms for 'Axiom_MonoPoly':
1073 -- * AXIOM: @⊦ Monotype : *p -> *m@
1074 -- * AXIOM: @⊦ monotype : (Polytype : *p) -> Polytype -> Monotype Polytype@
1075 -- * AXIOM: @⊦ polytype : (Polytype : *p) -> Monotype Polytype -> Polytype@
1076 axioms_monopoly :: Axioms
1079 [ ("Monotype", item Axiom_Type_MonoPoly)
1080 , ("monotype", item Axiom_Term_MonoPoly_Box)
1081 , ("polytype", item Axiom_Term_MonoPoly_UnBox)
1084 item = env_item_from_axiom ctx
1085 ctx = context_from_env mempty
1087 -- ** Type 'Axiom_Term'
1089 -- | Embed an Haskell-term of Haskell-type @h@ within an 'Axiom'
1091 data instance Axiom (Axiom_Term h)
1094 (forall var. Typeable var => Context var -> Type var)
1097 -- Instance 'Axiom' 'Integer'
1098 data instance Axiom Integer
1099 = Axiom_Type_Integer
1100 deriving (Eq, Ord, Show)
1101 instance Buildable (Axiom Integer) where
1102 build Axiom_Type_Integer = "Int"
1103 instance Axiomable (Axiom Integer) where
1104 axiom_type_of _ctx Axiom_Type_Integer =
1105 Type_Sort (Type_Level_0, Type_Morphism_Mono)
1107 instance Axiom_Type Integer where
1108 axiom_type = Axiom_Type_Integer
1109 axiom_Type = TeTy_Axiom
1110 instance Eq (Axiom (Axiom_Term Integer)) where
1111 Axiom_Term x _ == Axiom_Term y _ = x == y
1112 instance Ord (Axiom (Axiom_Term Integer)) where
1113 Axiom_Term x _ `compare` Axiom_Term y _ = x `compare` y
1114 instance Show (Axiom (Axiom_Term Integer)) where
1115 showsPrec n (Axiom_Term te ty) =
1116 showParen (n > 10) $
1117 showString "Axiom_Term " .
1120 showsPrec n (ty context)
1121 instance Buildable (Axiom (Axiom_Term Integer)) where
1122 build (Axiom_Term i _ty) = build i
1123 instance Axiomable (Axiom (Axiom_Term Integer)) where
1124 axiom_type_of _ctx (Axiom_Term _ _ty) =
1125 TeTy_Axiom Axiom_Type_Integer
1127 -- Instance 'Axiom' '()'
1128 data instance Axiom ()
1130 deriving (Eq, Ord, Show)
1131 instance Buildable (Axiom ()) where
1132 build (Axiom_Type_Unit) = "()"
1133 instance Axiomable (Axiom ()) where
1134 axiom_type_of _ctx Axiom_Type_Unit =
1135 Type_Sort (Type_Level_0, Type_Morphism_Mono)
1137 instance Axiom_Type () where
1138 axiom_type = Axiom_Type_Unit
1139 axiom_Type = TeTy_Axiom
1140 instance Eq (Axiom (Axiom_Term ())) where
1141 Axiom_Term x _ == Axiom_Term y _ = x == y
1142 instance Ord (Axiom (Axiom_Term ())) where
1143 Axiom_Term x _ `compare` Axiom_Term y _ = x `compare` y
1144 instance Show (Axiom (Axiom_Term ())) where
1145 showsPrec n (Axiom_Term te ty) =
1146 showParen (n > 10) $
1147 showString "Axiom_Term " .
1150 showsPrec n (ty context)
1151 instance Buildable (Axiom (Axiom_Term ())) where
1152 build (Axiom_Term _te _ty) = "()"
1153 instance Axiomable (Axiom (Axiom_Term ())) where
1154 axiom_type_of _ctx (Axiom_Term _te _ty) =
1155 TeTy_Axiom Axiom_Type_Unit
1157 -- Instance 'Axiom' 'Text'
1158 data instance Axiom Text
1160 deriving (Eq, Ord, Show)
1161 instance Buildable (Axiom Text) where
1162 build (Axiom_Type_Text) = "Text"
1163 instance Axiomable (Axiom Text) where
1164 axiom_type_of _ctx Axiom_Type_Text =
1165 Type_Sort (Type_Level_0, Type_Morphism_Mono)
1167 instance Axiom_Type Text where
1168 axiom_type = Axiom_Type_Text
1169 axiom_Type = TeTy_Axiom
1170 instance Eq (Axiom (Axiom_Term Text)) where
1171 Axiom_Term x _ == Axiom_Term y _ = x == y
1172 instance Ord (Axiom (Axiom_Term Text)) where
1173 Axiom_Term x _ `compare` Axiom_Term y _ = x `compare` y
1174 instance Show (Axiom (Axiom_Term Text)) where
1175 showsPrec n (Axiom_Term te ty) =
1176 showParen (n > 10) $
1177 showString "Axiom_Term " .
1180 showsPrec n (ty context)
1181 instance Buildable (Axiom (Axiom_Term Text)) where
1182 build (Axiom_Term t _) = build $ show t
1183 instance Axiomable (Axiom (Axiom_Term Text)) where
1184 axiom_type_of _ctx (Axiom_Term _te _ty) =
1185 TeTy_Axiom Axiom_Type_Text
1187 -- Instance 'Axiom' type variable
1189 -- ** Type 'Axiom_Type_Var'
1191 -- | Singleton type, whose constructors
1192 -- are bijectively mapped to Haskell types
1193 -- of kind 'Type_Var'.
1194 data Axiom_Type_Var (v::Type_Var) where
1195 Axiom_Type_Var_Zero :: Axiom_Type_Var 'Type_Var_Zero
1196 Axiom_Type_Var_Succ :: Axiom_Type_Var v -> Axiom_Type_Var ('Type_Var_Succ v)
1197 deriving instance Eq (Axiom_Type_Var v)
1198 deriving instance Ord (Axiom_Type_Var v)
1199 deriving instance Show (Axiom_Type_Var v)
1200 deriving instance Typeable Axiom_Type_Var
1201 instance Buildable (Axiom_Type_Var v) where
1202 build v = build $ type_var_string v
1204 -- *** Type 'Type_Var'
1206 -- | Natural numbers (aka. /Peano numbers/)
1207 -- promoted by @DataKinds@ to Haskell type-level.
1210 | Type_Var_Succ Type_Var
1211 deriving (Eq, Ord, Show, Typeable)
1213 type A = Axiom_Type_Var 'Type_Var_Zero
1214 type B = Axiom_Type_Var ('Type_Var_Succ 'Type_Var_Zero)
1215 type C = Axiom_Type_Var ('Type_Var_Succ ('Type_Var_Succ 'Type_Var_Zero))
1216 -- ^ …aliases only for the first few 'Axiom_Type_Var' used: extend on need.
1218 -- | Return the Haskell term-level 'Int' encoded by the given Haskell type-level @(v :: 'Type_Var')@.
1219 type_var_int :: Axiom_Type_Var v -> Int
1222 Axiom_Type_Var_Zero -> 0
1223 Axiom_Type_Var_Succ n -> 1 + type_var_int n
1225 -- | Return a readable 'String' encoding the given Haskell type-level @(v :: 'Type_Var')@.
1227 -- First 26 variables give: @\"A"@ to @\"Z"@,
1228 -- and followings give: @(\"A" ++ show n)@, where @n@ is a positive 'Int' starting at @0@.
1229 type_var_string :: Axiom_Type_Var v -> String
1231 case type_var_int v of
1232 x | 0 <= x && x < 26 -> [Char.chr (Char.ord 'A' + x)]
1233 x -> 'A' : show (x - 26)
1235 -- *** Class 'Type_Var_Implicit'
1236 class Type_Var_Implicit (v::Type_Var) where
1237 type_var :: Axiom_Type_Var v
1238 instance Type_Var_Implicit 'Type_Var_Zero where
1239 type_var = Axiom_Type_Var_Zero
1240 instance Type_Var_Implicit v => Type_Var_Implicit ('Type_Var_Succ v) where
1241 type_var = Axiom_Type_Var_Succ type_var
1243 data instance Axiom (Axiom_Type_Var (v::Type_Var))
1244 = Axiom_Type_Var (Axiom_Type_Var v)
1245 deriving (Eq, Ord, Show)
1246 instance Buildable (Axiom (Axiom_Type_Var (v::Type_Var))) where
1247 build (Axiom_Type_Var v) = build v
1248 instance (Typeable v) => Axiomable (Axiom (Axiom_Type_Var (v::Type_Var))) where
1249 axiom_type_of _ctx (Axiom_Type_Var _v) =
1250 Type_Sort (Type_Level_0, Type_Morphism_Mono)
1251 instance Type_Var_Implicit v => Axiom_Type (Axiom_Type_Var (v::Type_Var)) where
1252 axiom_type = Axiom_Type_Var (type_var::Axiom_Type_Var v)
1253 axiom_Type (Axiom_Type_Var v) = TeTy_Var $ Text.pack $ type_var_string v
1255 instance Eq (Axiom (Axiom_Term (Axiom_Type_Var (v::Type_Var)))) where
1256 Axiom_Term x _ == Axiom_Term y _ = x == y
1257 instance Ord (Axiom (Axiom_Term (Axiom_Type_Var (v::Type_Var)))) where
1258 Axiom_Term x _ `compare` Axiom_Term y _ = x `compare` y
1259 instance Show (Axiom (Axiom_Term (Axiom_Type_Var (v::Type_Var)))) where
1260 showsPrec n (Axiom_Term v ty) =
1261 showParen (n > 10) $
1262 showString "Axiom_Term " .
1263 (showParen (n > 10) $
1264 showString "Axiom_Type_Var " .
1267 (showParen (n > 10) $
1269 showsPrec n (ty context))
1270 instance Buildable (Axiom (Axiom_Term (Axiom_Type_Var (v::Type_Var)))) where
1271 build (Axiom_Term v _ty) = build v
1272 instance Typeable v => Axiomable (Axiom (Axiom_Term (Axiom_Type_Var (v::Type_Var)))) where
1273 axiom_type_of ctx (Axiom_Term _ ty) = ty ctx
1275 -- Instance 'Axiom' '->'
1276 data instance Axiom (i -> o)
1277 = Axiom_Term_Abst (Axiom i) (Axiom o)
1278 deriving instance (Eq (Axiom i), Eq (Axiom o)) => Eq (Axiom (i -> o))
1279 deriving instance (Ord (Axiom i), Ord (Axiom o)) => Ord (Axiom (i -> o))
1280 deriving instance (Show (Axiom i), Show (Axiom o)) => Show (Axiom (i -> o))
1281 instance (Buildable (Axiom i), Buildable (Axiom o)) => Buildable (Axiom (i -> o)) where
1282 build (Axiom_Term_Abst i o) =
1283 "(" <> build i <> " -> " <> build o <> ")"
1289 , Buildable (Axiom i)
1292 , Buildable (Axiom o)
1293 -- , Axiomable (Axiom i)
1294 -- , Axiomable (Axiom o)
1295 ) => Axiomable (Axiom (i -> o)) where
1296 axiom_type_of _ctx (Axiom_Term_Abst _i _o) =
1297 Type_Sort (Type_Level_0, Type_Morphism_Mono)
1299 instance (Axiom_Type i, Axiom_Type o) => Axiom_Type (i -> o) where
1304 axiom_Type (Axiom_Term_Abst i o) =
1307 (const Nothing `abstract`) $
1309 instance Eq (Axiom (Axiom_Term (i -> o))) where
1310 (==) = error "Eq Axiom: (==) on functions"
1311 instance Ord (Axiom (Axiom_Term (i -> o))) where
1312 compare = error "Eq Axiom: compare on functions"
1314 {-( Buildable (Axiom (i -> o))
1315 ) =>-} Show (Axiom (Axiom_Term (i -> o))) where
1316 showsPrec n (Axiom_Term _ ty) =
1317 showParen (n > 10) $
1318 showString "Axiom_Term " .
1323 Builder.toLazyText $
1328 {-( Buildable (Axiom i)
1329 , Buildable (Axiom o)
1330 ) =>-} Buildable (Axiom (Axiom_Term (i -> o))) where
1331 build (Axiom_Term _o ty) =
1332 "(_:" <> build (ty context) <> ")"
1335 ( Typeable (Term var)
1337 , Axiomable (Axiom (Axiom_Term o))
1338 -- , Axiomable (Axiom (Term var))
1339 -- , Axiomable (Axiom o)
1340 -- , Buildable (Axiom (Term var))
1341 -- , Show (Axiom (Axiom_Term (Term var)))
1342 -- , Show (Axiom (Axiom_Term o))
1343 ) => Axiomable (Axiom (Axiom_Term (Term var -> o))) where
1344 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1345 axiom_normalize (ctx::Context var_)
1346 {-ax@-}(Axiom_Term (cast -> Just (o::Term var_ -> o)) o_ty)
1349 trace ("axiom_normalize (i -> o): Term"
1353 Builder.toLazyText $
1355 ++ "\n ax=" ++ show ax
1356 ++ "\n ty(ax)=" ++ show (typeOf ax)
1357 ++ "\n arg=" ++ show (context_unlift ctx <$> arg)
1358 ++ "\n args=" ++ show ((context_unlift ctx <$>) <$> args)
1359 ++ "\n o=" ++ show (Axiom_Term (o arg) o_ty)
1362 case type_of ctx arg of
1365 Type_Abst _ _o_in o_out ->
1367 let oi_ty = const i_ty `unabstract` o_out in
1368 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1371 axiom_normalize _ctx _ax _args = Nothing
1374 ( Typeable (Term var -> io)
1377 , Axiomable (Axiom (Axiom_Term o))
1378 -- , Axiomable (Axiom (Term var -> io))
1379 -- , Axiomable (Axiom o)
1380 -- , Show (Axiom (Axiom_Term (Term var -> io)))
1381 -- , Show (Axiom (Axiom_Term o))
1382 ) => Axiomable (Axiom (Axiom_Term ((Term var -> io) -> o))) where
1383 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1386 {-ax@-}(Axiom_Term (cast -> Just (o::(Term var_ -> io) -> o)) o_ty)
1387 (arg@(Term_Abst _arg_v _arg_f_in arg_f):args) =
1388 case type_of ctx arg of
1391 Type_Abst _ _o_in o_out ->
1393 trace ("axiom_normalize (i -> o): Term ->"
1397 Builder.toLazyText $
1399 ++ "\n ax=" ++ show ax
1400 ++ "\n args=" ++ show ((context_unlift ctx <$>) <$> args)
1401 ++ "\n ty(args)=" ++ show (typeOf <$> args)
1402 ++ "\n ty(ax)=" ++ show (typeOf ax)
1403 ++ "\n i~" ++ show (typeOf (undefined::Term var -> io))
1404 ++ "\n o~" ++ show (typeOf (undefined::o))
1405 ++ "\n i=" ++ show (typeOf i)
1409 case normalize ctx (const te `unabstract` arg_f) of
1410 TeTy_Axiom (axiom_cast -> Just (Axiom_Term io _io_ty)) -> io
1411 _ -> error "axiom_normalize: Axiom_Term ((Term var -> io) -> o): cannot extract io"
1414 let oi_ty = const i_ty `unabstract` o_out in
1415 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1420 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1423 Type_Abst _ _o_in o_out ->
1425 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1427 trace ("axiom_normalize (i -> o): Term var -> io"
1431 Builder.toLazyText $
1432 build (context_unlift ctx <$> oi_ty))
1435 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1437 axiom_normalize _ctx _ax _args = Nothing
1440 ( Typeable (Axiom_Type_Var v -> io)
1442 , Axiomable (Axiom (Axiom_Type_Var v -> io))
1443 , Axiomable (Axiom o)
1444 , Axiomable (Axiom (Axiom_Term o))
1445 , Show (Axiom (Axiom_Term (Axiom_Type_Var v -> io)))
1446 , Show (Axiom (Axiom_Term o))
1447 ) => Axiomable (Axiom (Axiom_Term ((Axiom_Type_Var v -> io) -> o))) where
1448 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1453 , Axiomable (Axiom Integer)
1454 , Axiomable (Axiom o)
1455 , Axiomable (Axiom (Axiom_Term o))
1456 , Show (Axiom (Axiom_Term Integer))
1457 , Show (Axiom (Axiom_Term o))
1458 ) => Axiomable (Axiom (Axiom_Term (Integer -> o))) where
1459 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1462 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1465 Type_Abst _ _o_in o_out ->
1467 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1469 trace ("axiom_normalize (i -> o): "
1473 Builder.toLazyText $
1474 build (context_unlift ctx <$> oi_ty))
1477 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1479 axiom_normalize _ctx _ax _args = Nothing
1484 , Axiomable (Axiom Text)
1485 , Axiomable (Axiom o)
1486 , Axiomable (Axiom (Axiom_Term o))
1487 , Show (Axiom (Axiom_Term Text))
1488 , Show (Axiom (Axiom_Term o))
1489 ) => Axiomable (Axiom (Axiom_Term (Text -> o))) where
1490 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1493 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1496 Type_Abst _ _o_in o_out ->
1498 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1500 trace ("axiom_normalize (i -> o): "
1504 Builder.toLazyText $
1505 build (context_unlift ctx <$> oi_ty))
1508 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1510 axiom_normalize _ctx _ax _args = Nothing
1513 ( Typeable (Axiom_Type_Var v)
1515 , Axiomable (Axiom (Axiom_Type_Var v))
1516 , Axiomable (Axiom o)
1517 , Axiomable (Axiom (Axiom_Term o))
1518 , Show (Axiom (Axiom_Term (Axiom_Type_Var v)))
1519 , Show (Axiom (Axiom_Term o))
1520 ) => Axiomable (Axiom (Axiom_Term (Axiom_Type_Var v -> o))) where
1521 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1524 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1527 Type_Abst _ _o_in o_out ->
1529 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1531 trace ("axiom_normalize (i -> o): "
1535 Builder.toLazyText $
1536 build (context_unlift ctx <$> oi_ty))
1539 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1541 axiom_normalize _ctx _ax _args = Nothing
1547 , Axiomable (Axiom (Axiom_Term o))
1548 , Show (Axiom (Axiom_Term (IO a)))
1549 , Show (Axiom (Axiom_Term o))
1550 -- , Axiomable (Axiom (IO a))
1551 -- , Axiomable (Axiom o)
1552 ) => Axiomable (Axiom (Axiom_Term (IO a -> o))) where
1553 axiom_type_of ctx (Axiom_Term _o ty) = ty ctx
1556 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1559 Type_Abst _ _o_in o_out ->
1561 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1563 trace ("axiom_normalize (Axiom_Term ((IO a) -> o)): "
1567 Builder.toLazyText $
1568 build (context_unlift ctx <$> oi_ty))
1571 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1573 axiom_normalize (ctx::Context var)
1575 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term (i::IO (Term var)) i_ty)):args)
1578 Type_Abst _ _o_in o_out ->
1581 case normalize ctx te of
1582 TeTy_Axiom (axiom_cast -> Just (Axiom_Term io _io_ty)) -> io
1583 _ -> error "axiom_normalize: Axiom_Term ((Term var -> io) -> o): cannot extract io"
1585 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1586 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1588 axiom_normalize _ctx _ax _args = Nothing
1590 -- ** Type 'Axiom_Type_Abst'
1592 -- | Encode a @forall a.@ within an 'Axiom'.
1593 data Axiom_Type_Abst
1594 data instance Axiom (Axiom_Type_Abst)
1596 { axiom_type_abst_Var ::
1598 -- ^ A name for the variable inhabiting the abstracting 'Type'.
1599 , axiom_type_abst_Term ::
1600 (Type Var_Name -> Term Var_Name)
1601 -- ^ The abstracted 'Term', abstracted by a 'Type'.
1602 , axiom_type_abst_Type ::
1603 (Abstraction (Suggest Var_Name) Type Var_Name)
1604 -- ^ The 'Type' of the abstracted 'Term'
1605 -- (not exactly a 'Type', but just enough to build it with 'Type_Abst').
1608 instance Eq (Axiom (Axiom_Type_Abst)) where
1609 Axiom_Type_Abst{} == Axiom_Type_Abst{} =
1610 error "Eq Axiom_Type_Abst" -- maybe False (x ==) (cast y)
1611 instance Show (Axiom (Axiom_Type_Abst)) where
1612 show (Axiom_Type_Abst{}) = "Axiom_Type_Abst"
1613 instance Buildable (Axiom (Axiom_Type_Abst)) where
1614 build ax = "(_:" <> (build $ axiom_type_of context ax) <> ")"
1615 instance Axiomable (Axiom (Axiom_Type_Abst)) where
1616 axiom_type_of ctx (Axiom_Type_Abst v _o ty) =
1618 (Type_Sort (Type_Level_0, Type_Morphism_Mono)) $
1619 (context_lift ctx <$> ty)
1621 {-ax@-}(Axiom_Type_Abst _ o ty)
1624 let a = context_unlift ctx <$> arg in
1625 let ty_a = const a `unabstract` ty in
1628 trace ("axiom_normalize: Axiom_Type_Abst:"
1632 Builder.toLazyText $
1638 Builder.toLazyText $
1639 build (axiom_type_of context ax)
1644 Builder.toLazyText $
1652 Just (context_lift ctx <$> r, args)
1653 axiom_normalize _ctx _ax _args = Nothing
1655 -- Instance 'Axiom' 'IO'
1656 data instance Axiom (IO a)
1658 deriving (Eq, Ord, Show)
1659 instance Buildable (Axiom (IO a)) where
1661 instance (Typeable a) => Axiomable (Axiom (IO a)) where
1662 axiom_type_of _ctx ax =
1666 Type_Abst "" (Type_Sort sort_star_mono) $
1667 (const Nothing `abstract`) $
1668 Type_Sort sort_star_mono
1672 ( Typeable.splitTyConApp (typeOf x)
1673 , Typeable.splitTyConApp (typeOf y)
1675 ( (xc,[(Typeable.typeRepTyCon -> xc')])
1676 , (yc,[(Typeable.typeRepTyCon -> yc')])
1677 ) | xc == yc && xc' == yc' -> True
1679 error $ "Eq: Axiomable (Axiom (IO a)): "
1680 ++ "\n x : " ++ show (Typeable.splitTyConApp (typeOf x))
1681 ++ "\n y : " ++ show (Typeable.splitTyConApp (typeOf y))
1687 ) => Axiom_Type (IO a) where
1688 axiom_type = Axiom_Type_IO
1689 axiom_Type (Axiom_Type_IO) =
1691 (TeTy_Axiom (Axiom_Type_IO::Axiom (IO a)))
1692 (axiom_Type (axiom_type::Axiom a))
1694 instance Eq (Axiom (Axiom_Term (IO a))) where
1695 (==) = error "Eq Axiom: (==) on IO"
1696 instance Ord (Axiom (Axiom_Term (IO a))) where
1697 compare = error "Eq Axiom: compare on IO"
1699 {-( Buildable (Axiom a)
1700 ) =>-} Show (Axiom (Axiom_Term (IO a))) where
1701 showsPrec n (Axiom_Term _te ty) =
1702 showParen (n > 10) $
1703 showString "Axiom_Term " .
1708 Builder.toLazyText $
1709 build $ (ty context)
1713 {-( Buildable (Axiom a)
1714 ) =>-} Buildable (Axiom (Axiom_Term (IO a))) where
1715 build (Axiom_Term _a ty) =
1716 "(_:" <> build (ty context) <> ")"
1719 -- , Buildable (Axiom a)
1720 -- , Axiomable (Axiom a)
1721 -- , Axiomable (Axiom (Axiom_Term a))
1722 ) => Axiomable (Axiom (Axiom_Term (IO a))) where
1723 axiom_type_of ctx (Axiom_Term _a ty) = ty ctx