@@ -294,14 +294,21 @@ data PDo' t = DoExp FC t
294294
295295type PDo = PDo' PTerm
296296
297−data PArg' t = PImp { lazyarg :: Bool, pname :: Name, getTm :: t }
298− | PExp { lazyarg :: Bool, getTm :: t }
299− | PConstraint { lazyarg :: Bool, getTm :: t }
297+-- The priority gives a hint as to elaboration order. Best to elaborate
298+-- things early which will help give a more concrete type to other
299+-- variables, e.g. a before (interpTy a).
300+
301+data PArg' t = PImp { priority :: Int,
302+ lazyarg :: Bool, pname :: Name, getTm :: t }
303+ | PExp { priority :: Int,
304+ lazyarg :: Bool, getTm :: t }
305+ | PConstraint { priority :: Int,
306+ lazyarg :: Bool, getTm :: t }
300307 deriving (Show, Eq, Functor)
301308
302−pimp = PImp False
303−pexp = PExp False
304−pconst = PConstraint False
309+pimp = PImp 0 False
310+pexp = PExp 0 False
311+pconst = PConstraint 0 False
305312
306313type PArg = PArg' PTerm
307314
@@ -370,17 +377,17 @@ showDImp impl (PDatadecl n ty cons)
370377
371378getImps :: [PArg] -> [(Name, PTerm)]
372379getImps [] = []
373−getImps (PImp _ n tm : xs) = (n, tm) : getImps xs
380+getImps (PImp _ _ n tm : xs) = (n, tm) : getImps xs
374381getImps (_ : xs) = getImps xs
375382
376383getExps :: [PArg] -> [PTerm]
377384getExps [] = []
378−getExps (PExp _ tm : xs) = tm : getExps xs
385+getExps (PExp _ _ tm : xs) = tm : getExps xs
379386getExps (_ : xs) = getExps xs
380387
381388getConsts :: [PArg] -> [PTerm]
382389getConsts [] = []
383−getConsts (PConstraint _ tm : xs) = tm : getConsts xs
390+getConsts (PConstraint _ _ tm : xs) = tm : getConsts xs
384391getConsts (_ : xs) = getConsts xs
385392
386393getAll :: [PArg] -> [PTerm]
@@ -420,10 +427,9 @@ showImp impl tm = se 10 tm where
420427 = let [l, r] = getExps args in
421428 bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
422429 se p (PApp _ f as)
423− = let (imps, cs, args) = (getImps as, getConsts as, getExps as) in
424− bracket p 1 $ se 1 f ++ concatMap scArg cs
425− ++ (if impl then concatMap siArg imps else "")
426− ++ concatMap seArg args
430+ = let args = getExps as in
431+ bracket p 1 $ se 1 f ++ if impl then concatMap sArg as
432+ else concatMap seArg args
427433 se p (PHidden tm) = "." ++ se 0 tm
428434 se p (PRefl _) = "refl"
429435 se p (PResolveTC _) = "resolvetc"
@@ -438,6 +444,10 @@ showImp impl tm = se 10 tm where
438444 se p (PMetavar n) = "?" ++ show n
439445 se p Placeholder = "_"
440446
447+ sArg (PImp _ _ n tm) = siArg (n, tm)
448+ sArg (PExp _ _ tm) = seArg tm
449+ sArg (PConstraint _ _ tm) = scArg tm
450+
441451 seArg arg = " " ++ se 0 arg
442452 siArg (n, val) = " {" ++ show n ++ " = " ++ se 10 val ++ "}"
443453 scArg val = " {{" ++ se 10 val ++ "}}"
@@ -592,6 +602,33 @@ expandParamsD dec ps ns (PClauses fc n cs)
592602 (map (expandParamsD dec ps ns) ds)
593603expandParamsD dec ps ns d = d
594604
605+-- Calculate a priority for a type, for deciding elaboration order
606+-- * if it's just a type variable or concrete type, do it early (0)
607+-- * if there's only type variables and injective constructors, do it next (1)
608+-- * if there's a function type, next (2)
609+-- * finally, everything else (3)
610+
611+getPriority :: IState -> PTerm -> Int
612+getPriority i tm = pri tm
613+ where
614+ pri (PRef _ n) =
615+ case lookupP n (tt_ctxt i) of
616+ Just (P (DCon _ _) _ _) -> 1
617+ Just (P (TCon _ _) _ _) -> 1
618+ Just (P Ref _ _) -> 3
619+ Nothing -> 0 -- must be locally bound, if it's not an error...
620+ pri (PPi _ _ x y) = max 4 (max (pri x) (pri y))
621+ pri (PTrue _) = 0
622+ pri (PFalse _) = 0
623+ pri (PRefl _) = 1
624+ pri (PEq _ l r) = max 1 (max (pri l) (pri r))
625+ pri (PApp _ f as) = max 1 (max (pri f) (foldr max 0 (map (pri.getTm) as)))
626+ pri (PPair _ l r) = max 1 (max (pri l) (pri r))
627+ pri (PDPair _ l r) = max 1 (max (pri l) (pri r))
628+ pri (PConstant _) = 0
629+ pri Placeholder = 1
630+ pri _ = 3
631+
595632-- Dealing with implicit arguments
596633
597634-- Add implicit Pi bindings for any names in the term which appear in an
@@ -631,7 +668,7 @@ implicitise syn ist tm
631668 imps top env (PPi (Imp l _) n ty sc)
632669 = do let isn = nub (namesIn ist ty) `dropAll` [n]
633670 (decls , ns) <- get
634− put (PImp l n ty : decls,
671+ put (PImp (getPriority ist ty) l n ty : decls,
635672 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
636673 imps True (n:env) sc
637674 imps top env (PPi (Exp l _) n ty sc)
@@ -639,7 +676,7 @@ implicitise syn ist tm
639676 (PRef _ x) -> namesIn ist sc `dropAll` [n]
640677 _ -> [])
641678 (decls, ns) <- get -- ignore decls in HO types
642− put (PExp l ty : decls,
679+ put (PExp (getPriority ist ty) l ty : decls,
643680 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
644681 imps True (n:env) sc
645682 imps top env (PPi (Constraint l _) n ty sc)
@@ -647,7 +684,7 @@ implicitise syn ist tm
647684 (PRef _ x) -> namesIn ist sc `dropAll` [n]
648685 _ -> [])
649686 (decls, ns) <- get -- ignore decls in HO types
650− put (PConstraint l ty : decls,
687+ put (PConstraint 10 l ty : decls,
651688 nub (ns ++ (isn `dropAll` (env ++ map fst (getImps decls)))))
652689 imps True (n:env) sc
653690 imps top env (PEq _ l r)
@@ -723,21 +760,21 @@ aiFn ist fc f as
723760 Nothing -> mkPApp fc 1 (PRef fc f) as
724761 where
725762 insertImpl :: [PArg] -> [PArg] -> [PArg]
726− insertImpl (PExp l ty : ps) (PExp _ tm : given) =
727− PExp l tm : insertImpl ps given
728− insertImpl (PConstraint l ty : ps) (PConstraint _ tm : given) =
729− PConstraint l tm : insertImpl ps given
730− insertImpl (PConstraint l ty : ps) given =
731− PConstraint l (PResolveTC fc) : insertImpl ps given
732− insertImpl (PImp l n ty : ps) given =
763+ insertImpl (PExp p l ty : ps) (PExp _ _ tm : given) =
764+ PExp p l tm : insertImpl ps given
765+ insertImpl (PConstraint p l ty : ps) (PConstraint _ _ tm : given) =
766+ PConstraint p l tm : insertImpl ps given
767+ insertImpl (PConstraint p l ty : ps) given =
768+ PConstraint p l (PResolveTC fc) : insertImpl ps given
769+ insertImpl (PImp p l n ty : ps) given =
733770 case find n given [] of
734− Just (tm, given') -> PImp l n tm : insertImpl ps given'
735− Nothing -> PImp l n Placeholder : insertImpl ps given
771+ Just (tm, given') -> PImp p l n tm : insertImpl ps given'
772+ Nothing -> PImp p l n Placeholder : insertImpl ps given
736773 insertImpl expected [] = []
737774 insertImpl [] given = given
738775
739776 find n [] acc = Nothing
740− find n (PImp _ n' t : gs) acc
777+ find n (PImp _ _ n' t : gs) acc
741778 | n == n' = Just (t, reverse acc ++ gs)
742779 find n (g : gs) acc = find n gs (g : acc)
743780