1 (* Copyright (C) 2000, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
28 exception UnificationFailure of string;;
29 exception Uncertain of string;;
30 exception AssertFailure of string;;
32 let debug_print = prerr_endline
34 let type_of_aux' metasenv subst context term ugraph =
36 CicTypeChecker.type_of_aux' ~subst metasenv context term ugraph
38 CicTypeChecker.TypeCheckerFailure msg ->
41 "Kernel Type checking error:
42 %s\n%s\ncontext=\n%s\nmetasenv=\n%s\nsubstitution=\n%s\nException:\n%s.\nToo bad."
43 (CicMetaSubst.ppterm subst term)
44 (CicMetaSubst.ppterm [] term)
45 (CicMetaSubst.ppcontext subst context)
46 (CicMetaSubst.ppmetasenv metasenv subst)
47 (CicMetaSubst.ppsubst subst) msg) in
48 raise (AssertFailure msg);;
51 List.exists (function Cic.Meta _ -> true | _ -> false) l
55 (Cic.Appl (Cic.Lambda (_,_,t)::he'::tl')) ->
56 let he'' = CicSubstitution.subst he' t in
60 beta_reduce (Cic.Appl(he''::tl'))
64 let snd (_,a,_) = a in
69 (CicSubstitution.subst_meta
70 l (snd (CicUtil.lookup_subst n subst)))
72 CicUtil.Subst_not_found _ -> t)
76 let rec deref subst t =
77 let snd (_,a,_) = a in
82 (CicSubstitution.subst_meta
83 l (snd (CicUtil.lookup_subst n subst)))
85 CicUtil.Subst_not_found _ -> t)
86 | Cic.Appl(Cic.Meta(n,l)::args) ->
87 (match deref subst (Cic.Meta(n,l)) with
88 | Cic.Lambda _ as t ->
89 deref subst (beta_reduce (Cic.Appl(t::args)))
90 | r -> Cic.Appl(r::args))
95 let rec beta_expand test_equality_only metasenv subst context t arg ugraph =
96 let module S = CicSubstitution in
98 let rec aux metasenv subst n context t' ugraph =
101 let subst,metasenv,ugraph1 =
102 fo_unif_subst test_equality_only subst context metasenv
103 (CicSubstitution.lift n arg) t' ugraph
106 subst,metasenv,C.Rel (1 + n),ugraph1
109 | UnificationFailure _ ->
111 | C.Rel m -> subst,metasenv,
112 (if m <= n then C.Rel m else C.Rel (m+1)),ugraph
113 | C.Var (uri,exp_named_subst) ->
114 let subst,metasenv,exp_named_subst',ugraph1 =
115 aux_exp_named_subst metasenv subst n context exp_named_subst ugraph
117 subst,metasenv,C.Var (uri,exp_named_subst'),ugraph1
119 (* andrea: in general, beta_expand can create badly typed
120 terms. This happens quite seldom in practice, UNLESS we
121 iterate on the local context. For this reason, we renounce
122 to iterate and just lift *)
126 Some t -> Some (CicSubstitution.lift 1 t)
128 subst, metasenv, C.Meta (i,l), ugraph
130 | C.Implicit _ as t -> subst,metasenv,t,ugraph
132 let subst,metasenv,te',ugraph1 =
133 aux metasenv subst n context te ugraph in
134 let subst,metasenv,ty',ugraph2 =
135 aux metasenv subst n context ty ugraph1 in
136 (* TASSI: sure this is in serial? *)
137 subst,metasenv,(C.Cast (te', ty')),ugraph2
139 let subst,metasenv,s',ugraph1 =
140 aux metasenv subst n context s ugraph in
141 let subst,metasenv,t',ugraph2 =
142 aux metasenv subst (n+1) ((Some (nn, C.Decl s))::context) t
145 (* TASSI: sure this is in serial? *)
146 subst,metasenv,(C.Prod (nn, s', t')),ugraph2
147 | C.Lambda (nn,s,t) ->
148 let subst,metasenv,s',ugraph1 =
149 aux metasenv subst n context s ugraph in
150 let subst,metasenv,t',ugraph2 =
151 aux metasenv subst (n+1) ((Some (nn, C.Decl s))::context) t ugraph1
153 (* TASSI: sure this is in serial? *)
154 subst,metasenv,(C.Lambda (nn, s', t')),ugraph2
155 | C.LetIn (nn,s,t) ->
156 let subst,metasenv,s',ugraph1 =
157 aux metasenv subst n context s ugraph in
158 let subst,metasenv,t',ugraph2 =
159 aux metasenv subst (n+1) ((Some (nn, C.Def (s,None)))::context) t
162 (* TASSI: sure this is in serial? *)
163 subst,metasenv,(C.LetIn (nn, s', t')),ugraph2
165 let subst,metasenv,revl',ugraph1 =
167 (fun (subst,metasenv,appl,ugraph) t ->
168 let subst,metasenv,t',ugraph1 =
169 aux metasenv subst n context t ugraph in
170 subst,metasenv,(t'::appl),ugraph1
171 ) (subst,metasenv,[],ugraph) l
173 subst,metasenv,(C.Appl (List.rev revl')),ugraph1
174 | C.Const (uri,exp_named_subst) ->
175 let subst,metasenv,exp_named_subst',ugraph1 =
176 aux_exp_named_subst metasenv subst n context exp_named_subst ugraph
178 subst,metasenv,(C.Const (uri,exp_named_subst')),ugraph1
179 | C.MutInd (uri,i,exp_named_subst) ->
180 let subst,metasenv,exp_named_subst',ugraph1 =
181 aux_exp_named_subst metasenv subst n context exp_named_subst ugraph
183 subst,metasenv,(C.MutInd (uri,i,exp_named_subst')),ugraph1
184 | C.MutConstruct (uri,i,j,exp_named_subst) ->
185 let subst,metasenv,exp_named_subst',ugraph1 =
186 aux_exp_named_subst metasenv subst n context exp_named_subst ugraph
188 subst,metasenv,(C.MutConstruct (uri,i,j,exp_named_subst')),ugraph1
189 | C.MutCase (sp,i,outt,t,pl) ->
190 let subst,metasenv,outt',ugraph1 =
191 aux metasenv subst n context outt ugraph in
192 let subst,metasenv,t',ugraph2 =
193 aux metasenv subst n context t ugraph1 in
194 let subst,metasenv,revpl',ugraph3 =
196 (fun (subst,metasenv,pl,ugraph) t ->
197 let subst,metasenv,t',ugraph1 =
198 aux metasenv subst n context t ugraph in
199 subst,metasenv,(t'::pl),ugraph1
200 ) (subst,metasenv,[],ugraph2) pl
202 subst,metasenv,(C.MutCase (sp,i,outt', t', List.rev revpl')),ugraph3
203 (* TASSI: not sure this is serial *)
205 (*CSC: not implemented
206 let tylen = List.length fl in
209 (fun (name,i,ty,bo) -> (name, i, aux n ty, aux (n+tylen) bo))
212 C.Fix (i, substitutedfl)
214 subst,metasenv,(CicSubstitution.lift 1 t' ),ugraph
216 (*CSC: not implemented
217 let tylen = List.length fl in
220 (fun (name,ty,bo) -> (name, aux n ty, aux (n+tylen) bo))
223 C.CoFix (i, substitutedfl)
226 subst,metasenv,(CicSubstitution.lift 1 t'), ugraph
228 and aux_exp_named_subst metasenv subst n context ens ugraph =
230 (fun (uri,t) (subst,metasenv,l,ugraph) ->
231 let subst,metasenv,t',ugraph1 = aux metasenv subst n context t ugraph in
232 subst,metasenv,((uri,t')::l),ugraph1) ens (subst,metasenv,[],ugraph)
234 let argty,ugraph1 = type_of_aux' metasenv subst context arg ugraph in
236 FreshNamesGenerator.mk_fresh_name ~subst
237 metasenv context (Cic.Name "Heta") ~typ:argty
239 let subst,metasenv,t',ugraph2 = aux metasenv subst 0 context t ugraph1 in
240 subst, metasenv, C.Lambda (fresh_name,argty,t'), ugraph2
243 and beta_expand_many test_equality_only metasenv subst context t args ugraph =
244 let subst,metasenv,hd,ugraph =
246 (fun arg (subst,metasenv,t,ugraph) ->
247 let subst,metasenv,t,ugraph1 =
248 beta_expand test_equality_only
249 metasenv subst context t arg ugraph
251 subst,metasenv,t,ugraph1
252 ) args (subst,metasenv,t,ugraph)
254 subst,metasenv,hd,ugraph
257 (* NUOVA UNIFICAZIONE *)
258 (* A substitution is a (int * Cic.term) list that associates a
259 metavariable i with its body.
260 A metaenv is a (int * Cic.term) list that associate a metavariable
262 fo_unif_new takes a metasenv, a context, two terms t1 and t2 and gives back
263 a new substitution which is _NOT_ unwinded. It must be unwinded before
266 and fo_unif_subst test_equality_only subst context metasenv t1 t2 ugraph =
267 let module C = Cic in
268 let module R = CicReduction in
269 let module S = CicSubstitution in
270 let t1 = deref subst t1 in
271 let t2 = deref subst t2 in
273 R.are_convertible ~subst ~metasenv context t1 t2 ugraph
276 subst, metasenv, ugraph
279 | (C.Meta (n,ln), C.Meta (m,lm)) when n=m ->
280 let _,subst,metasenv,ugraph1 =
283 (fun (j,subst,metasenv,ugraph) t1 t2 ->
286 | _,None -> j+1,subst,metasenv,ugraph
287 | Some t1', Some t2' ->
288 (* First possibility: restriction *)
289 (* Second possibility: unification *)
290 (* Third possibility: convertibility *)
293 ~subst ~metasenv context t1' t2' ugraph
296 j+1,subst,metasenv, ugraph1
299 let subst,metasenv,ugraph2 =
302 subst context metasenv t1' t2' ugraph
304 j+1,subst,metasenv,ugraph2
307 | UnificationFailure _ ->
308 prerr_endline ("restringo Meta n." ^ (string_of_int n) ^ "on variable n." ^ (string_of_int j));
309 let metasenv, subst =
310 CicMetaSubst.restrict
311 subst [(n,j)] metasenv in
312 j+1,subst,metasenv,ugraph1)
313 ) (1,subst,metasenv,ugraph) ln lm
317 (UnificationFailure "1")
320 "Error trying to unify %s with %s: the algorithm tried to check whether the two substitutions are convertible; if they are not, it tried to unify the two substitutions. No restriction was attempted."
321 (CicMetaSubst.ppterm subst t1)
322 (CicMetaSubst.ppterm subst t2))) *)
323 | Invalid_argument _ ->
325 (UnificationFailure "2"))
328 "Error trying to unify %s with %s: the lengths of the two local contexts do not match."
329 (CicMetaSubst.ppterm subst t1)
330 (CicMetaSubst.ppterm subst t2)))) *)
331 in subst,metasenv,ugraph1
332 | (C.Meta (n,_), C.Meta (m,_)) when n>m ->
333 fo_unif_subst test_equality_only subst context metasenv t2 t1 ugraph
335 | (t, C.Meta (n,l)) ->
338 C.Meta (n,_), C.Meta (m,_) when n < m -> false
339 | _, C.Meta _ -> false
342 let lower = fun x y -> if swap then y else x in
343 let upper = fun x y -> if swap then x else y in
344 let fo_unif_subst_ordered
345 test_equality_only subst context metasenv m1 m2 ugraph =
346 fo_unif_subst test_equality_only subst context metasenv
347 (lower m1 m2) (upper m1 m2) ugraph
350 let subst,metasenv,ugraph1 =
351 let (_,_,meta_type) = CicUtil.lookup_meta n metasenv in
354 type_of_aux' metasenv subst context t ugraph
358 subst context metasenv tyt (S.subst_meta l meta_type) ugraph1
360 UnificationFailure msg
362 prerr_endline msg;raise (UnificationFailure msg)
364 prerr_endline "siamo allo huge hack";
365 (* TODO huge hack!!!!
366 * we keep on unifying/refining in the hope that
367 * the problem will be eventually solved.
368 * In the meantime we're breaking a big invariant:
369 * the terms that we are unifying are no longer well
370 * typed in the current context (in the worst case
371 * we could even diverge) *)
372 (subst, metasenv,ugraph)) in
373 let t',metasenv,subst =
375 CicMetaSubst.delift n subst context metasenv l t
377 (CicMetaSubst.MetaSubstFailure msg)->
378 raise (UnificationFailure msg)
379 | (CicMetaSubst.Uncertain msg) -> raise (Uncertain msg)
383 C.Sort (C.Type u) when not test_equality_only ->
384 let u' = CicUniv.fresh () in
385 let s = C.Sort (C.Type u') in
387 CicUniv.add_ge (upper u u') (lower u u') ugraph1
392 (* Unifying the types may have already instantiated n. Let's check *)
394 let (_, oldt,_) = CicUtil.lookup_subst n subst in
395 let lifted_oldt = S.subst_meta l oldt in
396 fo_unif_subst_ordered
397 test_equality_only subst context metasenv t lifted_oldt ugraph2
399 CicUtil.Subst_not_found _ ->
400 let (_, context, ty) = CicUtil.lookup_meta n metasenv in
401 let subst = (n, (context, t'',ty)) :: subst in
403 List.filter (fun (m,_,_) -> not (n = m)) metasenv in
404 subst, metasenv, ugraph2
406 | (C.Var (uri1,exp_named_subst1),C.Var (uri2,exp_named_subst2))
407 | (C.Const (uri1,exp_named_subst1),C.Const (uri2,exp_named_subst2)) ->
408 if UriManager.eq uri1 uri2 then
409 fo_unif_subst_exp_named_subst test_equality_only subst context metasenv
410 exp_named_subst1 exp_named_subst2 ugraph
412 raise (UnificationFailure "3")
414 "Can't unify %s with %s due to different constants"
415 (CicMetaSubst.ppterm subst t1)
416 (CicMetaSubst.ppterm subst t2))) *)
417 | C.MutInd (uri1,i1,exp_named_subst1),C.MutInd (uri2,i2,exp_named_subst2) ->
418 if UriManager.eq uri1 uri2 && i1 = i2 then
419 fo_unif_subst_exp_named_subst
421 subst context metasenv exp_named_subst1 exp_named_subst2 ugraph
423 raise (UnificationFailure "4")
425 "Can't unify %s with %s due to different inductive principles"
426 (CicMetaSubst.ppterm subst t1)
427 (CicMetaSubst.ppterm subst t2))) *)
428 | C.MutConstruct (uri1,i1,j1,exp_named_subst1),
429 C.MutConstruct (uri2,i2,j2,exp_named_subst2) ->
430 if UriManager.eq uri1 uri2 && i1 = i2 && j1 = j2 then
431 fo_unif_subst_exp_named_subst
433 subst context metasenv exp_named_subst1 exp_named_subst2 ugraph
435 raise (UnificationFailure "5")
437 "Can't unify %s with %s due to different inductive constructors"
438 (CicMetaSubst.ppterm subst t1)
439 (CicMetaSubst.ppterm subst t2))) *)
440 | (C.Implicit _, _) | (_, C.Implicit _) -> assert false
441 | (C.Cast (te,ty), t2) -> fo_unif_subst test_equality_only
442 subst context metasenv te t2 ugraph
443 | (t1, C.Cast (te,ty)) -> fo_unif_subst test_equality_only
444 subst context metasenv t1 te ugraph
445 | (C.Prod (n1,s1,t1), C.Prod (_,s2,t2)) ->
446 let subst',metasenv',ugraph1 =
447 fo_unif_subst true subst context metasenv s1 s2 ugraph
449 fo_unif_subst test_equality_only
450 subst' ((Some (n1,(C.Decl s1)))::context) metasenv' t1 t2 ugraph1
451 | (C.Lambda (n1,s1,t1), C.Lambda (_,s2,t2)) ->
452 let subst',metasenv',ugraph1 =
453 fo_unif_subst test_equality_only subst context metasenv s1 s2 ugraph
455 fo_unif_subst test_equality_only
456 subst' ((Some (n1,(C.Decl s1)))::context) metasenv' t1 t2 ugraph1
457 | (C.LetIn (_,s1,t1), t2)
458 | (t2, C.LetIn (_,s1,t1)) ->
460 test_equality_only subst context metasenv t2 (S.subst s1 t1) ugraph
461 | (C.Appl l1, C.Appl l2) ->
462 (* andrea: this case should be probably rewritten in the
465 | C.Meta (i,_)::args1, C.Meta (j,_)::args2 when i = j ->
468 (fun (subst,metasenv,ugraph) t1 t2 ->
470 test_equality_only subst context metasenv t1 t2 ugraph)
471 (subst,metasenv,ugraph) l1 l2
472 with (Invalid_argument msg) ->
473 raise (UnificationFailure msg))
474 | C.Meta (i,l)::args, _ when not(exists_a_meta args) ->
475 (* we verify that none of the args is a Meta,
476 since beta expanding with respoect to a metavariable
480 let (_,t,_) = CicUtil.lookup_subst i subst in
481 let lifted = S.subst_meta l t in
482 let reduced = beta_reduce (Cic.Appl (lifted::args)) in
485 subst context metasenv reduced t2 ugraph
486 with CicUtil.Subst_not_found _ -> *)
487 let subst,metasenv,beta_expanded,ugraph1 =
489 test_equality_only metasenv subst context t2 args ugraph
491 fo_unif_subst test_equality_only subst context metasenv
492 (C.Meta (i,l)) beta_expanded ugraph1
493 | _, C.Meta (i,l)::args when not(exists_a_meta args) ->
495 let (_,t,_) = CicUtil.lookup_subst i subst in
496 let lifted = S.subst_meta l t in
497 let reduced = beta_reduce (Cic.Appl (lifted::args)) in
500 subst context metasenv t1 reduced ugraph
501 with CicUtil.Subst_not_found _ -> *)
502 let subst,metasenv,beta_expanded,ugraph1 =
505 metasenv subst context t1 args ugraph in
506 fo_unif_subst test_equality_only subst context metasenv
507 (C.Meta (i,l)) beta_expanded ugraph1
509 let lr1 = List.rev l1 in
510 let lr2 = List.rev l2 in
512 fo_unif_l test_equality_only subst metasenv (l1,l2) ugraph =
515 | _,[] -> assert false
518 test_equality_only subst context metasenv h1 h2 ugraph
521 fo_unif_subst test_equality_only subst context metasenv
522 h (C.Appl (List.rev l)) ugraph
523 | ((h1::l1),(h2::l2)) ->
524 let subst', metasenv',ugraph1 =
527 subst context metasenv h1 h2 ugraph
530 test_equality_only subst' metasenv' (l1,l2) ugraph1
533 test_equality_only subst metasenv (lr1, lr2) ugraph)
534 | (C.MutCase (_,_,outt1,t1',pl1), C.MutCase (_,_,outt2,t2',pl2))->
535 let subst', metasenv',ugraph1 =
536 fo_unif_subst test_equality_only subst context metasenv outt1 outt2
538 let subst'',metasenv'',ugraph2 =
539 fo_unif_subst test_equality_only subst' context metasenv' t1' t2'
543 (fun (subst,metasenv,ugraph) t1 t2 ->
545 test_equality_only subst context metasenv t1 t2 ugraph
546 ) (subst'',metasenv'',ugraph2) pl1 pl2
548 Invalid_argument _ ->
549 raise (UnificationFailure "6"))
551 "Error trying to unify %s with %s: the number of branches is not the same."
552 (CicMetaSubst.ppterm subst t1)
553 (CicMetaSubst.ppterm subst t2)))) *)
554 | (C.Rel _, _) | (_, C.Rel _) ->
556 subst, metasenv,ugraph
558 raise (UnificationFailure "6")
560 "Can't unify %s with %s because they are not convertible"
561 (CicMetaSubst.ppterm subst t1)
562 (CicMetaSubst.ppterm subst t2))) *)
563 | (C.Sort _ ,_) | (_, C.Sort _)
564 | (C.Const _, _) | (_, C.Const _)
565 | (C.MutInd _, _) | (_, C.MutInd _)
566 | (C.MutConstruct _, _) | (_, C.MutConstruct _)
567 | (C.Fix _, _) | (_, C.Fix _)
568 | (C.CoFix _, _) | (_, C.CoFix _) ->
570 subst, metasenv, ugraph
573 R.are_convertible ~subst ~metasenv context t1 t2 ugraph
576 subst, metasenv, ugraph1
578 raise (* (UnificationFailure "7") *)
579 (UnificationFailure (sprintf
580 "Can't unify %s with %s because they are not convertible"
581 (CicMetaSubst.ppterm subst t1)
582 (CicMetaSubst.ppterm subst t2)))
583 | (C.Appl (C.Meta(i,l)::args),t2) when not(exists_a_meta args) ->
584 let subst,metasenv,beta_expanded,ugraph1 =
586 test_equality_only metasenv subst context t2 args ugraph
588 fo_unif_subst test_equality_only subst context metasenv
589 (C.Meta (i,l)) beta_expanded ugraph1
590 | (t1,C.Appl (C.Meta(i,l)::args)) when not(exists_a_meta args) ->
591 let subst,metasenv,beta_expanded,ugraph1 =
593 test_equality_only metasenv subst context t1 args ugraph
595 fo_unif_subst test_equality_only subst context metasenv
596 beta_expanded (C.Meta (i,l)) ugraph1
598 let t2' = R.whd ~subst context t2 in
601 fo_unif_subst test_equality_only
602 subst context metasenv t1 t2' ugraph
603 | _ -> raise (UnificationFailure "8"))
605 let t1' = R.whd ~subst context t1 in
608 fo_unif_subst test_equality_only
609 subst context metasenv t1' t2 ugraph
610 | _ -> (* raise (UnificationFailure "9")) *)
612 (UnificationFailure (sprintf
613 "Can't unify %s with %s because they are not convertible"
614 (CicMetaSubst.ppterm subst t1)
615 (CicMetaSubst.ppterm subst t2))))
618 R.are_convertible ~subst ~metasenv context t1 t2 ugraph
621 subst, metasenv, ugraph1
623 raise (UnificationFailure "10")
625 "Can't unify %s with %s because they are not convertible"
626 (CicMetaSubst.ppterm subst t1)
627 (CicMetaSubst.ppterm subst t2))) *)
629 and fo_unif_subst_exp_named_subst test_equality_only subst context metasenv
630 exp_named_subst1 exp_named_subst2 ugraph
634 (fun (subst,metasenv,ugraph) (uri1,t1) (uri2,t2) ->
636 fo_unif_subst test_equality_only subst context metasenv t1 t2 ugraph
637 ) (subst,metasenv,ugraph) exp_named_subst1 exp_named_subst2
639 Invalid_argument _ ->
644 UriManager.string_of_uri uri ^ " := " ^ (CicMetaSubst.ppterm subst t)
647 raise (UnificationFailure (sprintf
648 "Error trying to unify the two explicit named substitutions (local contexts) %s and %s: their lengths is different." (print_ens exp_named_subst1) (print_ens exp_named_subst2)))
650 (* A substitution is a (int * Cic.term) list that associates a *)
651 (* metavariable i with its body. *)
652 (* metasenv is of type Cic.metasenv *)
653 (* fo_unif takes a metasenv, a context, two terms t1 and t2 and gives back *)
654 (* a new substitution which is already unwinded and ready to be applied and *)
655 (* a new metasenv in which some hypothesis in the contexts of the *)
656 (* metavariables may have been restricted. *)
657 let fo_unif metasenv context t1 t2 ugraph =
658 fo_unif_subst false [] context metasenv t1 t2 ugraph ;;
660 let fo_unif_subst subst context metasenv t1 t2 ugraph =
661 let enrich_msg msg = (* "bella roba" *)
662 sprintf "Unification error unifying %s of type %s with %s of type %s in context\n%s\nand metasenv\n%s\nand substitution\n%s\nbecause %s"
663 (CicMetaSubst.ppterm subst t1)
665 let ty_t1,_ = type_of_aux' metasenv subst context t1 ugraph in
667 with _ -> "MALFORMED")
668 (CicMetaSubst.ppterm subst t2)
670 let ty_t2,_ = type_of_aux' metasenv subst context t2 ugraph in
672 with _ -> "MALFORMED")
673 (CicMetaSubst.ppcontext subst context)
674 (CicMetaSubst.ppmetasenv metasenv subst)
675 (CicMetaSubst.ppsubst subst) msg
678 fo_unif_subst false subst context metasenv t1 t2 ugraph
680 | AssertFailure msg -> raise (AssertFailure (enrich_msg msg))
681 | UnificationFailure msg -> raise (UnificationFailure (enrich_msg msg))