@@ -10,6 +10,9 @@ import Idris.AbsSyntax
1010import Idris.Delaborate
1111import Idris.Error
1212
13+import Control.Monad
14+import Debug.Trace
15+
1316-- Pass in a term elaborator to avoid a cyclic dependency with ElabTerm
1417
1518trivial :: (PTerm -> ElabD ()) -> IState -> ElabD ()
@@ -31,8 +34,38 @@ trivial elab ist = try' (do elab (PRefl (fileFC "prf") Placeholder)
3134 else tryAll xs
3235
3336proofSearch :: (PTerm -> ElabD ()) -> Name -> IState -> ElabD ()
34−proofSearch elab nroot ist
35− = try (trivial elab ist)
36− (do attack; defer nroot; solve)
37+proofSearch elab nroot ist = psRec 10 where
38+ psRec 0 = fail "Maximum depth reached"
39+ psRec d = try' (trivial elab ist)
40+ (try' (resolveByCon (d - 1))
41+ -- if all else fails, make a new metavariable
42+ (do attack; defer nroot; solve) True) True
3743
44+ resolveByCon d
45+ = do t <- goal
46+ let (f, _) = unApply t
47+ case f of
48+ P _ n _ -> case lookupCtxt n (idris_datatypes ist) of
49+ [t] -> tryCons d (con_names t)
50+ _ -> fail "Not a data type"
51+ _ -> fail "Not a data type"
3852
53+ tryCons d [] = fail "Constructors failed"
54+ tryCons d (c : cs) = try' (tryCon d c) (tryCons d cs) True
55+
56+ -- Like type class resolution, but searching with constructors
57+ tryCon d n
58+ = do let imps = case lookupCtxtName n (idris_implicits ist) of
59+ [] -> []
60+ [args] -> map isImp (snd args)
61+ ps <- get_probs
62+ args <- apply (Var n) imps
63+ ps' <- get_probs
64+ when (length ps < length ps') $ fail "Can't apply constructor"
65+ mapM_ (\ (_, h) -> do focus h
66+ psRec d)
67+ (filter (\ (x, y) -> not x) (zip (map fst imps) args))
68+ solve
69+
70+ isImp (PImp p _ _ _ _ _) = (True, p)
71+ isImp arg = (False, priority arg)