]> Git — Sourcephile - comptalang.git/blob - calculus/Calculus/Lambda/Omega/Explicit.hs
Correction : Calculus.Lambda.Omega.Explicit.REPL : broutille administrative.
[comptalang.git] / calculus / Calculus / Lambda / Omega / Explicit.hs
1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE DeriveFoldable #-}
3 {-# LANGUAGE DeriveFunctor #-}
4 {-# LANGUAGE DeriveTraversable #-}
5 {-# LANGUAGE EmptyDataDecls #-}
6 {-# LANGUAGE ExistentialQuantification #-}
7 {-# LANGUAGE FlexibleContexts #-}
8 {-# LANGUAGE FlexibleInstances #-}
9 {-# LANGUAGE GADTs #-}
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
22
23 import Control.Arrow
24 import Control.Monad
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
38 import Data.Bool
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)
52 import System.IO (IO)
53
54 -- import Debug.Trace
55
56 import Calculus.Abstraction.DeBruijn.Generalized
57
58 -- * Type 'Term'
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:
62 --
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'.
69 --
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.
73 --
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@: @(* *)@:
77 --
78 -- @
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' … )
83 -- @
84 --
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 :
88 --
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'.
92 --
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).
108 --
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'.
112 data Term var
113 = TeTy_Var var
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)
117 | Type_Sort Sort
118 | forall ax .
119 ( Axiomable (Axiom ax)
120 , Typeable 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
132 _ == _ = False
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 (==#) = (==)
141
142 instance Applicative (Term) where
143 pure = TeTy_Var
144 (<*>) = ap
145 -- | A 'Monad' instance capturing the notion of /variable substitution/ with /capture-avoiding/.
146 instance Monad (Term) where
147 return = pure
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
156 where
157 go :: forall v. (Buildable v)
158 => Bool -> Bool
159 -> Term v
160 -> Builder.Builder
161 go parenBind parenApp te =
162 case te of
163 Type_Sort s -> build s
164 TeTy_Axiom ax -> build ax
165 TeTy_Var v -> build v
166 TeTy_App f x ->
167 (if parenApp then "(" else "")
168 <> go True False f <> " " <> go True True x
169 <> (if parenApp then ")" else "")
170 Term_Abst _ _ _ ->
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 "")
175 <> (if x == ""
176 then go True False f_in
177 else "∀" <> "(" <> build x <> ":" <> go False False f_in <> ")" )
178 <> " -> "
179 <> go False False (abstract_normalize f_out)
180 <> (if parenBind then ")" else "")
181 go_abst :: forall v. (Buildable v)
182 => Bool -> Bool
183 -> Term v
184 -> Builder.Builder
185 go_abst parenBind parenApp te =
186 case te of
187 Term_Abst (Suggest x) f_in f ->
188 let body = abstract_normalize f in
189 case body of
190 Term_Abst _ _ _ ->
191 "(" <> go_var_def x <> ":" <> go False False f_in <> ")"
192 <> " " <> go_abst parenBind parenApp body
193 _ ->
194 "(" <> go_var_def x <> ":" <> go False False f_in <> ")"
195 <> " -> "
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
200
201 -- ** Type 'Sort'
202 -- | Four /PTS/ /sort constants/
203 -- are formed by combining
204 -- 'Type_Level' and 'Type_Morphism':
205 --
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
212 build x = case x of
213 (sort, morphism) -> build sort <> build morphism
214
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)
218
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)
222
223 -- *** Type 'Type_Level'
224 data 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
229 build x = case x of
230 Type_Level_0 -> "*"
231 Type_Level_1 -> "□"
232
233 -- *** Type 'Type_Morphism'
234 data Type_Morphism
235 = Type_Morphism_Mono
236 | Type_Morphism_Poly
237 deriving (Eq, Ord, Show)
238 instance Buildable Type_Morphism where
239 build x = case x of
240 Type_Morphism_Mono -> "" -- "m"
241 Type_Morphism_Poly -> "p"
242
243 -- | /PTS/ axioms for 'Sort':
244 --
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)
250 -- AXIOM: @*m : □m@
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)
255 -- AXIOM: @*p : □p@
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
259
260 -- * Type 'Form'
261
262 -- | A record to keep a same 'Term' (or 'Type')
263 -- in several forms (and avoid to 'normalize' it multiple times).
264 data Form var
265 = Form
266 { form_given :: Term var
267 , form_normal :: Term var -- ^ 'normalize'-d version of 'form_given'.
268 } deriving (Functor, Show)
269
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)
273
274 -- | Reduce given 'Term' (or 'Type') to /normal form/ (NF)
275 -- by recursively performing /β-reduction/ and /η-reduction/.
276 --
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
281 normalize = go []
282 where
283 {-
284 go_debug :: (Eq var, Ord var, Variable var, Typeable var)
285 => [Term var]
286 -> Context var
287 -> Term var
288 -> Term var
289 go_debug args ctx te =
290 go args ctx $
291 trace ("normalize: "
292 ++ "\n te = " ++ show te
293 ++ "\n args = " ++ show args
294 ) $ te
295 -}
296
297 go :: (Eq var, Ord var, Variable var, Typeable var)
298 => [Term var]
299 -> Context var
300 -> Term var
301 -> Term 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
304 = case args of
305 [] -> te -- NOTE: no need to normalize again
306 _ -> go args ctx te
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
323 = go r_args ctx r_te
324 go args _ctx te
325 -- NOTE: Reapply remaining arguments, normalized
326 = term_apps te args
327
328 abst_eta_reduce
329 :: (Eq var, Eq bound, Ord var, Ord bound, Variable var, Variable bound, Typeable var, Typeable bound)
330 => Context var
331 -> Abstraction bound (Term) var
332 -> Either (Abstraction bound (Term) var) -- could not η-reduce
333 (Term var) -- could η-reduce
334 abst_eta_reduce ctx =
335 (\abst_body ->
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-}))) ->
339 traverse (\var ->
340 case var of
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.
347 ) t
348 te -> Left $ abstract_generalize te
349 ) .
350 abstract_normalize
351
352 go_scope
353 :: (Eq var, Eq bound, Ord var, Ord bound, Variable var, Variable bound, Typeable var, Typeable bound)
354 => Context var
355 -> Abstraction bound (Term) var
356 -> Abstraction bound (Term) var
357 go_scope ctx =
358 abstract_generalize .
359 go [] (context_push_nothing ctx) .
360 abstract_normalize
361
362 -- | Reduce given 'Term' to /Weak Head Normal Form/ (WHNF).
363 --
364 -- __Ressources:__
365 --
366 -- * https://wiki.haskell.org/Weak_head_normal_form
367 whnf :: (Ord var, Variable var, Typeable var) => Context var -> Term var -> Term var
368 whnf = go []
369 where
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
373 -> Just te))
374 -- NOTE: Replace any variable mapped by the context
375 = go args ctx te
376 go args ctx (TeTy_App f a)
377 -- NOTE: Collect applied arguments
378 = go (a:args) ctx f
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'
385 = go r_args ctx r_te
386 go args _ctx te
387 -- NOTE: Reapply remaining arguments, normalized
388 = term_apps te args
389
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
394
395 -- | /α-equivalence relation/, synonym of @(==)@.
396 --
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
400 alpha_equiv = (==)
401
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
405
406 -- * Type 'Type'
407
408 -- | 'Type' and 'Term' share the same data-type.
409 type Type = Term
410
411 -- | Construct the 'Type' of the given 'Term',
412 -- effectively checking for the /well-formedness/
413 -- and /well-typedness/ of a 'Term' (or 'Type').
414 --
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'.
420 type_of
421 :: (Eq var, Ord var, Variable var, Typeable var)
422 => Context var
423 -> Term var
424 -> Either Type_Error (Type var)
425 type_of ctx term =
426 case term of
427 Type_Sort s -> (err +++ Type_Sort) $ sort_of_sort s
428 TeTy_Var v ->
429 case form_normal
430 . context_item_type
431 <$> context_lookup ctx v of
432 Just ty -> return ty
433 Nothing -> Left $ err $ Type_Error_Msg_Unbound_variable v
434 TeTy_Axiom ax ->
435 return $ axiom_type_of ctx ax
436 TeTy_App f x -> do
437 f_ty <- whnf ctx <$> type_of ctx f
438 (f_in, f_out) <-
439 case f_ty of
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
448 let new_ctx =
449 if x == ""
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
455 return 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
461 let new_ctx =
462 if x == ""
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
472 where
473 err = Type_Error ctx term
474
475 -- | Check that the given 'Term' has the given 'Type'.
476 check
477 :: (Eq var, Ord var, Variable var, Typeable var)
478 => Context var
479 -> Type var
480 -> Term 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
485 then Right ()
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)
490 }
491
492 -- | Check that a 'Term' is closed, i.e. has no /unbound variables/.
493 close :: Term Var_Name -> Either Type_Error (Term ())
494 close te =
495 traverse go te
496 where
497 go var = Left $
498 Type_Error context te $
499 Type_Error_Msg_Unbound_variable var
500
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
504
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@".
507 --
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@).
511 --
512 -- The usual /PTS/ rules for /λω/
513 -- (or equivalently /Type Assignment Systems/ (TAS) rules for /System Fω/)
514 -- are used here:
515 --
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ω/.
525 --
526 -- Note that the fourth usual rule is not ruled valid here:
527 --
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/).
531 --
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/):
537 --
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.
540 --
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.
543 --
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.
546 --
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.
549 --
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.
556 --
557 -- __Ressources:__
558 --
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
562 sort_of_type_abst
563 :: Sort
564 -> Sort
565 -> Either Type_Error_Msg Sort
566
567 -- Simple types
568 sort_of_type_abst
569 (Type_Level_0, Type_Morphism_Mono)
570 (Type_Level_0, m)
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
577
578 -- Higher-rank
579 sort_of_type_abst
580 (Type_Level_0, Type_Morphism_Poly)
581 (Type_Level_0, _)
582 = return (Type_Level_0, Type_Morphism_Poly)
583 -- RULE: *p ↝ *m : *p
584 -- RULE: *p ↝ *p : *p
585 -- abstracting: a POLYMORPHIC term
586 -- out of : a term
587 -- forms : a POLYMORPHIC term
588
589 -- Polymorphism
590 sort_of_type_abst
591 (Type_Level_1, Type_Morphism_Mono)
592 (Type_Level_0, _)
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
597 -- out of : a term
598 -- forms : a POLYMORPHIC term
599
600 -- Type constructors
601 sort_of_type_abst
602 (Type_Level_1, Type_Morphism_Mono)
603 (Type_Level_1, m)
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
610 --
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)
614
615 -- Dependent types
616
617 {-
618 sort_of_type_abst
619 (Type_Level_0, Type_Morphism_Mono)
620 (Type_Level_1, m)
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
627
628 sort_of_type_abst
629 (Type_Level_0, Type_Morphism_Poly)
630 (Type_Level_1, _)
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
637 -}
638
639 sort_of_type_abst
640 s@(Type_Level_0, _)
641 t@(Type_Level_1, _)
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
646 -- is illegal
647
648 -- No impredicativity (only allowed through 'Axiom_MonoPoly')
649 sort_of_type_abst
650 s@(Type_Level_1, Type_Morphism_Poly)
651 t@(_, _)
652 = Left $ Type_Error_Msg_Illegal_type_abstraction s t
653 -- RULE: □p ↝ _ : Illegal
654 -- abstracting: a POLYMORPHIC type of a term
655 -- out of : anything
656 -- is illegal
657
658 -- ** Type 'Type_Error'
659 data Type_Error
660 = forall var. (Ord var, Show var, Buildable var)
661 => Type_Error
662 { type_error_ctx :: Context var
663 , type_error_term :: Term var
664 , type_error_msg :: Type_Error_Msg
665 }
666 deriving instance Show Type_Error
667 instance Buildable Type_Error where
668 build (Type_Error ctx te msg) =
669 "Error: Type_Error"
670 <> "\n " <> build msg
671 <> "\n Term:" <> " " <> build te
672 <> (
673 let vars =
674 Map.keys $
675 Map.intersection
676 (unbound_vars te)
677 (Map.fromList $ (, ()) <$> context_vars ctx) in
678 case vars of
679 [] -> "\n"
680 _ -> "\n Context:\n" <> build ctx{context_vars=vars}
681 )
682
683 -- ** Type 'Type_Error_Msg'
684 data 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
696 build msg =
697 case msg of
698 Type_Error_Msg_No_sort_for_sort x ->
699 "No_sort_for_sort: "
700 <> build 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: "
706 <> build ty
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 ->
713 "Not_a_function: "
714 <> build f
715 <> " : "
716 <> build 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 ->
722 "Unbound_variable: "
723 <> build var
724 Type_Error_Msg_Unbound_axiom var ->
725 "Unbound_axiom: "
726 <> build var
727 Type_Error_Msg_Type_mismatch x y nx ny ->
728 "Type_mismatch: \n"
729 <> " Expected type: " <> build x <> " == " <> build nx <> "\n"
730 <> " Actual type: " <> build y <> " == " <> build ny
731
732 -- * Type 'Context'
733
734 -- | Map variables of type @var@
735 -- to their 'Type' and maybe also to their 'Term',
736 -- both in 'form_given' and 'form_normal'.
737 data Context var
738 = Context
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')
747 }
748 data Context_Item var
749 = Context_Item
750 { context_item_term :: Maybe (Form var)
751 , context_item_type :: Form var
752 } deriving (Functor, Show)
753
754 instance Show var => Show (Context var) where
755 showsPrec n ctx@Context{context_vars=vars} =
756 showParen (n > 10) $
757 showString "Context " .
758 showsPrec n ((\k ->
759 (k, fromJust $ context_item_type
760 <$> context_lookup ctx k))
761 <$> vars) .
762 showString " " .
763 showsPrec n (catMaybes $ (\k ->
764 (k,) . form_given <$>
765 (context_item_term =<< context_lookup ctx k))
766 <$> vars)
767 instance Buildable var => Buildable (Context var) where
768 build ctx@Context{context_vars=vars} =
769 foldMap (\var ->
770 " " <> build var
771 <> maybe mempty (\ty -> " : " <> build (form_given ty))
772 (context_item_type <$> context_lookup ctx var)
773 {-
774 <> maybe mempty (\te -> " = " <> build (form_given te))
775 (context_item_term =<< context_lookup ctx var)
776 -}
777 <> "\n"
778 ) vars
779
780 context :: Context Var_Name
781 context = Context [] (const Nothing) id id
782
783 context_apply :: Context var -> Term var -> Term var
784 context_apply ctx te =
785 te >>= \var ->
786 maybe (TeTy_Var var) id $ form_normal <$>
787 (context_item_term =<< context_lookup ctx var)
788
789 context_push_type
790 :: (Eq var, Ord var, Variable var, Typeable var)
791 => Context var
792 -> bound
793 -> Type var
794 -> Context (Var bound var)
795 context_push_type
796 ctx@(Context keys lookup var_lift var_unlift)
797 bound ty =
798 Context
799 { context_vars =
800 Var_Bound bound :
801 Var_Free `fmap` keys
802 , context_lookup = \var ->
803 (Var_Free `fmap`) `fmap`
804 case var of
805 Var_Bound _ ->
806 Just $ Context_Item
807 { context_item_term = Nothing
808 , context_item_type = form ctx ty
809 }
810 Var_Free v -> lookup v
811 , context_lift = Var_Free . var_lift
812 , context_unlift = \var ->
813 case var of
814 Var_Bound _ -> error "context_push_type: context_unlift"
815 Var_Free v -> var_unlift v
816 }
817
818 context_push_nothing
819 :: (Show bound, Buildable (Context var), Typeable var, Typeable bound)
820 => Context var
821 -> Context (Var bound var)
822 context_push_nothing
823 (Context keys lookup var_lift var_unlift) =
824 Context
825 { context_vars = Var_Free `fmap` keys
826 , context_lookup = \var ->
827 (Var_Free `fmap`) `fmap`
828 case var of
829 Var_Bound _ -> Nothing
830 Var_Free v -> lookup v
831 , context_lift = Var_Free . var_lift
832 , context_unlift = \var ->
833 case var of
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
838 }
839
840 context_from_env :: Env -> Context Var_Name
841 context_from_env env =
842 Context
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
849 , context_lift = id
850 , context_unlift = id
851 }
852
853 context_relift :: forall from_var to_var.
854 ( Typeable from_var
855 , Typeable to_var )
856 => Context from_var
857 -> Type from_var
858 -> Context to_var
859 -> Type to_var
860 context_relift from_ctx ty to_ctx =
861 ( context_lift to_ctx
862 . context_unlift from_ctx
863 ) <$> ty
864
865 {-
866 context_from_list :: Eq var => [(var, Type var)] -> Context var
867 context_from_list l =
868 Context
869 { context_vars = fst <$> l
870 , context_lookup_type = \var -> List.lookup var l
871 }
872
873 -- | Return /free term variables/ of an 'Abstraction'-ed 'Term'.
874 ftv
875 :: Abstraction bound (Term) var
876 -> Term (Var bound var)
877 ftv = abstract_normalize
878 -}
879
880 -- * Type 'Env'
881 type Env
882 = Map Var_Name Env_Item
883 data Env_Item
884 = Env_Item
885 { env_item_term :: Form Var_Name
886 , env_item_type :: Form Var_Name
887 }
888 env_item
889 :: Context Var_Name
890 -> Term Var_Name
891 -> Type Var_Name
892 -> Env_Item
893 env_item ctx te ty =
894 Env_Item
895 { env_item_term = form ctx te
896 , env_item_type = form ctx ty
897 }
898
899 env_lookup :: Env -> Var_Name -> Maybe (Env_Item)
900 env_lookup env var = Map.lookup var env
901
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
906
907 -- * Type 'Axiom'
908
909 data family Axiom r
910 -- deriving instance Typeable Axiom
911
912 axiom_cast :: (Typeable a, Typeable b) => Axiom a -> Maybe (Axiom b)
913 axiom_cast = cast
914
915 -- ** Type 'Axioms'
916 -- | 'Axioms' are made of 'Axiom's injected in regular 'Env_Item's,
917 -- see 'env_item_from_axiom'.
918 type Axioms = Env
919
920 env_item_from_axiom
921 :: ( Axiomable (Axiom ax)
922 , Typeable ax )
923 => Context Var_Name -> Axiom ax -> Env_Item
924 env_item_from_axiom ctx ax =
925 Env_Item
926 { env_item_term = form ctx $ TeTy_Axiom ax
927 , env_item_type = form ctx $ axiom_type_of ctx ax
928 }
929
930 -- ** Class 'Axiomable'
931
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
935
936 -- | Instances of this class are 'Axiom's injectable in 'TeTy_Axiom', that is:
937 --
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'.
941 class
942 ( Eq ax, Show ax, Buildable ax, Typeable ax
943 -- , Axiomable_Type_Of ax
944 -- , Axiomable_Normalize ax
945 -- , Axiomable_Eq ax
946 ) => Axiomable ax where
947 axiom_type_of
948 :: forall var. Typeable var
949 => Context var -> ax -> Type var
950 -- ^ Return the 'Type' of the given 'Axiomable' instance.
951 axiom_normalize
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:
957 --
958 -- * 'Nothing': if the axiom performs no reduction,
959 -- * 'Just': with the reducted 'Term' and the arguments not used by the reduction.
960 --
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.
969 --
970 -- Default: @maybe False (x ==) (cast y)@
971 axiom_eq x y = maybe False (x ==) (cast y)
972
973 -- ** Class 'Axiom_Type'
974
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').
985
986 axiom_term
987 :: (Axiom_Type h, Typeable h)
988 => h -> Axiom (Axiom_Term h)
989 axiom_term (x::h) =
990 Axiom_Term x $ \ctx ->
991 context_lift ctx <$> axiom_Type (axiom_type::Axiom h)
992
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)
998 deriving (Eq, Show)
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
1004
1005 -- ** Type 'Axiom_MonoPoly'
1006 -- | Non-'Sort' constants for /boxed parametric polymorphism/.
1007 --
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.
1010 --
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'.
1014 --
1015 -- __Ressources:__
1016 --
1017 -- * /Recasting MLF/, Didier Le Botlan, Didier Rémy, June 2009,
1018 -- https://hal.inria.fr/inria-00156628
1019 data Axiom_MonoPoly
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 =
1032 case ax of
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`) $
1045 TeTy_App
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`) $
1053 Type_Abst ""
1054 (TeTy_App
1055 (TeTy_Axiom $ Axiom_Type_MonoPoly)
1056 (TeTy_Var "Polytype")) $
1057 (("" =?) `abstract`) $
1058 TeTy_Var "Polytype"
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
1063 = Just (te, args)
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
1068 = Just (te, args)
1069 axiom_normalize _ctx _ax _args = Nothing
1070
1071 -- | /PTS/ axioms for 'Axiom_MonoPoly':
1072 --
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
1077 axioms_monopoly =
1078 Map.fromList $
1079 [ ("Monotype", item Axiom_Type_MonoPoly)
1080 , ("monotype", item Axiom_Term_MonoPoly_Box)
1081 , ("polytype", item Axiom_Term_MonoPoly_UnBox)
1082 ]
1083 where
1084 item = env_item_from_axiom ctx
1085 ctx = context_from_env mempty
1086
1087 -- ** Type 'Axiom_Term'
1088
1089 -- | Embed an Haskell-term of Haskell-type @h@ within an 'Axiom'
1090 data Axiom_Term h
1091 data instance Axiom (Axiom_Term h)
1092 = Typeable h
1093 => Axiom_Term h
1094 (forall var. Typeable var => Context var -> Type var)
1095 deriving (Typeable)
1096
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)
1106
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 " .
1118 showsPrec n te .
1119 showString " " .
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
1126
1127 -- Instance 'Axiom' '()'
1128 data instance Axiom ()
1129 = Axiom_Type_Unit
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)
1136
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 " .
1148 showsPrec n te .
1149 showString " " .
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
1156
1157 -- Instance 'Axiom' 'Text'
1158 data instance Axiom Text
1159 = Axiom_Type_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)
1166
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 " .
1178 showsPrec n te .
1179 showString " " .
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
1186
1187 -- Instance 'Axiom' type variable
1188
1189 -- ** Type 'Axiom_Type_Var'
1190
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
1203
1204 -- *** Type 'Type_Var'
1205
1206 -- | Natural numbers (aka. /Peano numbers/)
1207 -- promoted by @DataKinds@ to Haskell type-level.
1208 data Type_Var
1209 = Type_Var_Zero
1210 | Type_Var_Succ Type_Var
1211 deriving (Eq, Ord, Show, Typeable)
1212
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.
1217
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
1220 type_var_int v =
1221 case v of
1222 Axiom_Type_Var_Zero -> 0
1223 Axiom_Type_Var_Succ n -> 1 + type_var_int n
1224
1225 -- | Return a readable 'String' encoding the given Haskell type-level @(v :: 'Type_Var')@.
1226 --
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
1230 type_var_string v =
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)
1234
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
1242
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
1254
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 " .
1265 showsPrec n v) .
1266 showString " " .
1267 (showParen (n > 10) $
1268 showString " " .
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
1274
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 <> ")"
1284 instance
1285 ( Typeable i
1286 , Typeable o
1287 , Eq (Axiom i)
1288 , Show (Axiom i)
1289 , Buildable (Axiom i)
1290 , Eq (Axiom o)
1291 , Show (Axiom o)
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)
1298
1299 instance (Axiom_Type i, Axiom_Type o) => Axiom_Type (i -> o) where
1300 axiom_type =
1301 Axiom_Term_Abst
1302 axiom_type
1303 axiom_type
1304 axiom_Type (Axiom_Term_Abst i o) =
1305 Type_Abst ""
1306 (axiom_Type i) $
1307 (const Nothing `abstract`) $
1308 (axiom_Type o)
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"
1313 instance
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 " .
1319 showString "(_:" .
1320 showString (
1321 Text.unpack $
1322 TL.toStrict $
1323 Builder.toLazyText $
1324 build (ty context)
1325 ) .
1326 showString ")"
1327 instance
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) <> ")"
1333
1334 instance
1335 ( Typeable (Term var)
1336 , Typeable o
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)
1347 (arg:args) =
1348 {-
1349 trace ("axiom_normalize (i -> o): Term"
1350 ++ "\n ax=" ++
1351 (Text.unpack $
1352 TL.toStrict $
1353 Builder.toLazyText $
1354 build (ax))
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)
1360 ) $
1361 -}
1362 case type_of ctx arg of
1363 Right i_ty ->
1364 case o_ty ctx of
1365 Type_Abst _ _o_in o_out ->
1366 let oi = o arg in
1367 let oi_ty = const i_ty `unabstract` o_out in
1368 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1369 _ -> Nothing
1370 _ -> Nothing
1371 axiom_normalize _ctx _ax _args = Nothing
1372
1373 instance
1374 ( Typeable (Term var -> io)
1375 , Typeable o
1376 , Typeable 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
1384 axiom_normalize
1385 (ctx::Context var_)
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
1389 Right i_ty ->
1390 case o_ty ctx of
1391 Type_Abst _ _o_in o_out ->
1392 {-
1393 trace ("axiom_normalize (i -> o): Term ->"
1394 ++ "\n ax=" ++
1395 (Text.unpack $
1396 TL.toStrict $
1397 Builder.toLazyText $
1398 build (ax))
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)
1406 ) $
1407 -}
1408 let i te =
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"
1412 in
1413 let oi = o i in
1414 let oi_ty = const i_ty `unabstract` o_out in
1415 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1416 _ -> Nothing
1417 _ -> Nothing
1418 axiom_normalize ctx
1419 (Axiom_Term o o_ty)
1420 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1421 =
1422 case o_ty ctx of
1423 Type_Abst _ _o_in o_out ->
1424 let oi = o i in
1425 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1426 {-
1427 trace ("axiom_normalize (i -> o): Term var -> io"
1428 ++ (
1429 Text.unpack $
1430 TL.toStrict $
1431 Builder.toLazyText $
1432 build (context_unlift ctx <$> oi_ty))
1433 ) $
1434 -}
1435 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1436 _ -> Nothing
1437 axiom_normalize _ctx _ax _args = Nothing
1438
1439 instance
1440 ( Typeable (Axiom_Type_Var v -> io)
1441 , Typeable o
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
1449
1450 instance
1451 ( Typeable Integer
1452 , Typeable o
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
1460 axiom_normalize ctx
1461 (Axiom_Term o o_ty)
1462 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1463 =
1464 case o_ty ctx of
1465 Type_Abst _ _o_in o_out ->
1466 let oi = o i in
1467 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1468 {-
1469 trace ("axiom_normalize (i -> o): "
1470 ++ (
1471 Text.unpack $
1472 TL.toStrict $
1473 Builder.toLazyText $
1474 build (context_unlift ctx <$> oi_ty))
1475 ) $
1476 -}
1477 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1478 _ -> Nothing
1479 axiom_normalize _ctx _ax _args = Nothing
1480
1481 instance
1482 ( Typeable Text
1483 , Typeable o
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
1491 axiom_normalize ctx
1492 (Axiom_Term o o_ty)
1493 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1494 =
1495 case o_ty ctx of
1496 Type_Abst _ _o_in o_out ->
1497 let oi = o i in
1498 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1499 {-
1500 trace ("axiom_normalize (i -> o): "
1501 ++ (
1502 Text.unpack $
1503 TL.toStrict $
1504 Builder.toLazyText $
1505 build (context_unlift ctx <$> oi_ty))
1506 ) $
1507 -}
1508 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1509 _ -> Nothing
1510 axiom_normalize _ctx _ax _args = Nothing
1511
1512 instance
1513 ( Typeable (Axiom_Type_Var v)
1514 , Typeable o
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
1522 axiom_normalize ctx
1523 (Axiom_Term o o_ty)
1524 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1525 =
1526 case o_ty ctx of
1527 Type_Abst _ _o_in o_out ->
1528 let oi = o i in
1529 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1530 {-
1531 trace ("axiom_normalize (i -> o): "
1532 ++ (
1533 Text.unpack $
1534 TL.toStrict $
1535 Builder.toLazyText $
1536 build (context_unlift ctx <$> oi_ty))
1537 ) $
1538 -}
1539 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1540 _ -> Nothing
1541 axiom_normalize _ctx _ax _args = Nothing
1542
1543 instance
1544 ( Typeable (IO a)
1545 , Typeable o
1546 , Typeable a
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
1554 axiom_normalize ctx
1555 (Axiom_Term o o_ty)
1556 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term i i_ty)):args)
1557 =
1558 case o_ty ctx of
1559 Type_Abst _ _o_in o_out ->
1560 let oi = o i in
1561 let oi_ty = const (i_ty ctx) `unabstract` o_out in
1562 {-
1563 trace ("axiom_normalize (Axiom_Term ((IO a) -> o)): "
1564 ++ (
1565 Text.unpack $
1566 TL.toStrict $
1567 Builder.toLazyText $
1568 build (context_unlift ctx <$> oi_ty))
1569 ) $
1570 -}
1571 Just (TeTy_Axiom $ Axiom_Term oi (context_relift ctx oi_ty), args)
1572 _ -> Nothing
1573 axiom_normalize (ctx::Context var)
1574 (Axiom_Term o o_ty)
1575 (TeTy_Axiom (axiom_cast -> Just (Axiom_Term (i::IO (Term var)) i_ty)):args)
1576 =
1577 case o_ty ctx of
1578 Type_Abst _ _o_in o_out ->
1579 let oi = o $
1580 (\te ->
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"
1584 ) <$> i in
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)
1587 _ -> Nothing
1588 axiom_normalize _ctx _ax _args = Nothing
1589
1590 -- ** Type 'Axiom_Type_Abst'
1591
1592 -- | Encode a @forall a.@ within an 'Axiom'.
1593 data Axiom_Type_Abst
1594 data instance Axiom (Axiom_Type_Abst)
1595 = Axiom_Type_Abst
1596 { axiom_type_abst_Var ::
1597 (Suggest Var_Name)
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').
1606 }
1607 deriving (Typeable)
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) =
1617 Type_Abst v
1618 (Type_Sort (Type_Level_0, Type_Morphism_Mono)) $
1619 (context_lift ctx <$> ty)
1620 axiom_normalize ctx
1621 {-ax@-}(Axiom_Type_Abst _ o ty)
1622 (arg:args)
1623 =
1624 let a = context_unlift ctx <$> arg in
1625 let ty_a = const a `unabstract` ty in
1626 let r = o $ ty_a in
1627 {-
1628 trace ("axiom_normalize: Axiom_Type_Abst:"
1629 ++ "\n a=" ++
1630 (Text.unpack $
1631 TL.toStrict $
1632 Builder.toLazyText $
1633 build (a)
1634 )
1635 ++ "\n ty=" ++
1636 (Text.unpack $
1637 TL.toStrict $
1638 Builder.toLazyText $
1639 build (axiom_type_of context ax)
1640 )
1641 ++ "\n ty_a=" ++
1642 (Text.unpack $
1643 TL.toStrict $
1644 Builder.toLazyText $
1645 build (ty_a)
1646 )
1647 ++ "\n r=" ++
1648 (show r
1649 )
1650 ) $
1651 -}
1652 Just (context_lift ctx <$> r, args)
1653 axiom_normalize _ctx _ax _args = Nothing
1654
1655 -- Instance 'Axiom' 'IO'
1656 data instance Axiom (IO a)
1657 = Axiom_Type_IO
1658 deriving (Eq, Ord, Show)
1659 instance Buildable (Axiom (IO a)) where
1660 build _ = "IO"
1661 instance (Typeable a) => Axiomable (Axiom (IO a)) where
1662 axiom_type_of _ctx ax =
1663 case ax of
1664 Axiom_Type_IO ->
1665 -- IO : * -> *
1666 Type_Abst "" (Type_Sort sort_star_mono) $
1667 (const Nothing `abstract`) $
1668 Type_Sort sort_star_mono
1669 axiom_eq x y =
1670 maybe (
1671 case
1672 ( Typeable.splitTyConApp (typeOf x)
1673 , Typeable.splitTyConApp (typeOf y)
1674 ) of
1675 ( (xc,[(Typeable.typeRepTyCon -> xc')])
1676 , (yc,[(Typeable.typeRepTyCon -> yc')])
1677 ) | xc == yc && xc' == yc' -> True
1678 _ ->
1679 error $ "Eq: Axiomable (Axiom (IO a)): "
1680 ++ "\n x : " ++ show (Typeable.splitTyConApp (typeOf x))
1681 ++ "\n y : " ++ show (Typeable.splitTyConApp (typeOf y))
1682 ) (x ==) (cast y)
1683
1684 instance
1685 ( Typeable a
1686 , Axiom_Type a
1687 ) => Axiom_Type (IO a) where
1688 axiom_type = Axiom_Type_IO
1689 axiom_Type (Axiom_Type_IO) =
1690 TeTy_App
1691 (TeTy_Axiom (Axiom_Type_IO::Axiom (IO a)))
1692 (axiom_Type (axiom_type::Axiom a))
1693
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"
1698 instance
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 " .
1704 showString "(_:" .
1705 showString (
1706 Text.unpack $
1707 TL.toStrict $
1708 Builder.toLazyText $
1709 build $ (ty context)
1710 ) .
1711 showString ")"
1712 instance
1713 {-( Buildable (Axiom a)
1714 ) =>-} Buildable (Axiom (Axiom_Term (IO a))) where
1715 build (Axiom_Term _a ty) =
1716 "(_:" <> build (ty context) <> ")"
1717 instance
1718 ( Typeable a
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