- let match_term status ctx (wanted : cic_term) t =
- let rec aux ctx status t =
- let b, status = found status ctx t wanted in
- if b then
- let status, (_,_,t) =
- mk_meta status ~name:in_scope_tag (`Ctx ctx) (`Def (None,ctx,t))
- in
- status, t
- else NCicUntrusted.map_term_fold_a (fun e c -> e::c) ctx aux status t
- in
- aux ctx status t
- in
- let rec select status ctx pat cic =
- match pat, cic with
- | NCic.LetIn (_,t1,s1,b1), NCic.LetIn (n,t2,s2,b2) ->
- let status, t = select status ctx t1 t2 in
- let status, s = select status ctx s1 s2 in
- let ctx = (n, NCic.Def (s2,t2)) :: ctx in
- let status, b = select status ctx b1 b2 in
- status, NCic.LetIn (n,t,s,b)
- | NCic.Lambda (_,s1,t1), NCic.Lambda (n,s2,t2) ->
- let status, s = select status ctx s1 s2 in
- let ctx = (n, NCic.Decl s2) :: ctx in
- let status, t = select status ctx t1 t2 in
- status, NCic.Lambda (n,s,t)
- | NCic.Prod (_,s1,t1), NCic.Prod (n,s2,t2) ->
- let status, s = select status ctx s1 s2 in
- let ctx = (n, NCic.Decl s2) :: ctx in
- let status, t = select status ctx t1 t2 in
- status, NCic.Prod (n,s,t)
- | NCic.Appl l1, NCic.Appl l2 ->
- let status, l =
- List.fold_left2
- (fun (status,l) x y ->
- let status, x = select status ctx x y in
- status, x::l)
- (status,[]) l1 l2
- in
- status, NCic.Appl (List.rev l)
- | NCic.Match (_,ot1,t1,pl1), NCic.Match (u,ot2,t2,pl2) ->
- let status, t = select status ctx t1 t2 in
- let status, ot = select status ctx ot1 ot2 in
- let status, pl =
- List.fold_left2
- (fun (status,l) x y ->
- let status, x = select status ctx x y in
- status, x::l)
- (status,[]) pl1 pl2
- in
- status, NCic.Match (u,ot,t,List.rev pl)
- | NCic.Implicit `Hole, t ->
- (match wanted with
- | Some wanted ->
- let status, wanted = disambiguate status wanted None (`Ctx ctx) in
- match_term status ctx wanted t
- | None -> match_term status ctx (None,ctx,t) t)
- | NCic.Implicit _, t -> status, t
- | _,t ->
- fail (lazy ("malformed pattern: " ^ NCicPp.ppterm ~metasenv:[]
- ~context:[] ~subst:[] pat))