~ubuntu-branches/ubuntu/raring/agda/raring-proposed

« back to all changes in this revision

Viewing changes to src/full/Agda/TypeChecking/Rules/LHS/Instantiate.hs

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane
  • Date: 2009-07-20 19:49:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090720194941-hcjy91vrn16csh7d
Tags: upstream-2.2.4+dfsg
Import upstream version 2.2.4+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
{-# LANGUAGE CPP #-}
 
2
 
 
3
module Agda.TypeChecking.Rules.LHS.Instantiate where
 
4
 
 
5
import Agda.Syntax.Common
 
6
import Agda.Syntax.Internal
 
7
import qualified Agda.Syntax.Abstract as A
 
8
 
 
9
import Agda.TypeChecking.Monad
 
10
import Agda.TypeChecking.Substitute
 
11
import Agda.TypeChecking.Free
 
12
import Agda.TypeChecking.Pretty
 
13
import Agda.TypeChecking.Reduce
 
14
import Agda.TypeChecking.Telescope
 
15
 
 
16
import Agda.TypeChecking.Rules.LHS.Problem
 
17
import Agda.TypeChecking.Rules.LHS.Split ( asView )
 
18
 
 
19
import Agda.Utils.Permutation
 
20
import Agda.Utils.Size
 
21
 
 
22
#include "../../../undefined.h"
 
23
import Agda.Utils.Impossible
 
24
 
 
25
-- | Instantiate a telescope with a substitution. Might reorder the telescope.
 
26
--   @instantiateTel (Γ : Tel)(σ : Γ --> Γ) = Γσ~@
 
27
--   Monadic only for debugging purposes.
 
28
instantiateTel :: MonadTCM tcm => Substitution -> Telescope -> tcm (Telescope, Permutation, [Term], [Type])
 
29
instantiateTel s tel = liftTCM $ do
 
30
 
 
31
  reportSDoc "tc.lhs.inst" 10 $ sep
 
32
    [ text "instantiateTel "
 
33
    , nest 2 $ fsep $ punctuate comma $ map (maybe (text "_") prettyTCM) s
 
34
    , nest 2 $ prettyTCM tel
 
35
    ]
 
36
 
 
37
  -- Shrinking permutation (removing Justs) (and its complement, and reverse)
 
38
  let ps  = Perm (size s) [ i | (i, Nothing) <- zip [0..] $ reverse s ]
 
39
      psR = reverseP ps
 
40
      psC = Perm (size s) [ i | (i, Just _)  <- zip [0..] $ reverse s ]
 
41
 
 
42
  reportS "tc.lhs.inst" 10 $ unlines
 
43
    [ "ps  = " ++ show ps
 
44
    , "psR = " ++ show psR
 
45
    , "psC = " ++ show psC
 
46
    ]
 
47
 
 
48
  -- s' : Substitution Γσ
 
49
  let s' = rename psR s
 
50
 
 
51
  reportSDoc "tc.lhs.inst" 15 $ nest 2 $
 
52
    text "s'   =" <+> fsep (punctuate comma $ map (maybe (text "_") prettyTCM) s')
 
53
 
 
54
  -- rho : [Tm Γσ]Γ
 
55
  let rho = mkSubst s'
 
56
 
 
57
  -- tel1 : [Type Γ]Γ
 
58
  let tel1   = flattenTel tel
 
59
      names1 = teleNames tel
 
60
 
 
61
  reportSDoc "tc.lhs.inst" 15 $ nest 2 $
 
62
    text "tel1 =" <+> brackets (fsep $ punctuate comma $ map prettyTCM tel1)
 
63
 
 
64
  -- tel2 : [Type Γσ]Γ
 
65
  let tel2 = substs rho tel1
 
66
 
 
67
  reportSDoc "tc.lhs.inst" 15 $ nest 2 $
 
68
    text "tel2 =" <+> brackets (fsep $ punctuate comma $ map prettyTCM tel2)
 
69
 
 
70
  -- tel3 : [Type Γσ]Γσ
 
71
  tel3 <- instantiateFull $ permute ps tel2
 
72
  let names3 = permute ps names1
 
73
 
 
74
  reportSDoc "tc.lhs.inst" 15 $ nest 2 $
 
75
    text "tel3 =" <+> brackets (fsep $ punctuate comma $ map prettyTCM tel3)
 
76
 
 
77
  -- p : Permutation (Γσ -> Γσ~)
 
78
  let p = reorderTel tel3
 
79
 
 
80
  reportSLn "tc.lhs.inst" 10 $ "p   = " ++ show p
 
81
 
 
82
  -- rho' : [Term Γσ~]Γσ
 
83
  let rho' = renaming (reverseP p)
 
84
 
 
85
  -- tel4 : [Type Γσ~]Γσ~
 
86
  let tel4   = substs rho' (permute p tel3)
 
87
      names4 = permute p names3
 
88
 
 
89
  reportSDoc "tc.lhs.inst" 15 $ nest 2 $
 
90
    text "tel4 =" <+> brackets (fsep $ punctuate comma $ map prettyTCM tel4)
 
91
 
 
92
  -- tel5 = Γσ~
 
93
  let tel5 = unflattenTel names4 tel4
 
94
 
 
95
  reportSDoc "tc.lhs.inst" 15 $ nest 2 $
 
96
    text "tel5 =" <+> prettyTCM tel5
 
97
 
 
98
  -- remember the types of the instantiations
 
99
  -- itypes : [Type Γσ~]Γ*
 
100
  let itypes = substs rho' $ permute psC $ map unArg tel2
 
101
 
 
102
  return (tel5, composeP p ps, substs rho' rho, itypes)
 
103
  where
 
104
 
 
105
    -- Turn a Substitution ([Maybe Term]) into a substitution ([Term])
 
106
    -- (The result is an infinite list)
 
107
    mkSubst :: [Maybe Term] -> [Term]
 
108
    mkSubst s = rho 0 s'
 
109
      where s'  = s ++ repeat Nothing
 
110
            rho i (Nothing : s) = Var i [] : rho (i + 1) s
 
111
            rho i (Just u  : s) = u : rho i s
 
112
            rho _ []            = __IMPOSSIBLE__
 
113
 
 
114
-- | Produce a nice error message when splitting failed
 
115
nothingToSplitError :: Problem -> TCM a
 
116
nothingToSplitError (Problem ps _ tel) = splitError ps tel
 
117
  where
 
118
    splitError []       EmptyTel    = __IMPOSSIBLE__
 
119
    splitError (_:_)    EmptyTel    = __IMPOSSIBLE__
 
120
    splitError []       ExtendTel{} = __IMPOSSIBLE__
 
121
    splitError (p : ps) (ExtendTel a tel)
 
122
      | isBad p   = traceCall (CheckPattern (strip p) EmptyTel (unArg a)) $ case strip p of
 
123
          A.DotP _ e -> typeError $ UninstantiatedDotPattern e
 
124
          p          -> typeError $ IlltypedPattern p (unArg a)
 
125
      | otherwise = underAbstraction a tel $ \tel -> splitError ps tel
 
126
      where
 
127
        strip = snd . asView . namedThing . unArg
 
128
        isBad p = case strip p of
 
129
          A.DotP _ _   -> True
 
130
          A.ConP _ _ _ -> True
 
131
          A.LitP _     -> True
 
132
          _            -> False
 
133