202 |
202 |
203 |
203 |
204 exception CANTUNIFY; (*Signals non-unifiability. Does not signal errors!*) |
204 exception CANTUNIFY; (*Signals non-unifiability. Does not signal errors!*) |
205 exception ASSIGN; (*Raised if not an assignment*) |
205 exception ASSIGN; (*Raised if not an assignment*) |
206 |
206 |
207 |
|
208 fun self_asgt (ix,(_,TVar (ix',_))) = (ix = ix') |
|
209 | self_asgt (ix, _) = false; |
|
210 |
|
211 fun check_tyenv msg tys tyenv = |
|
212 if Vartab.exists self_asgt tyenv |
|
213 then raise TYPE (msg ^ ": looping type envir!!", tys, []) |
|
214 else tyenv; |
|
215 |
207 |
216 fun unify_types thy (T, U, env) = |
208 fun unify_types thy (T, U, env) = |
217 if T = U then env |
209 if T = U then env |
218 else |
210 else |
219 let |
211 let |
470 |
462 |
471 (*Form the arguments into records for deletion/sorting.*) |
463 (*Form the arguments into records for deletion/sorting.*) |
472 fun flexargs ([], [], []) = [] : flarg list |
464 fun flexargs ([], [], []) = [] : flarg list |
473 | flexargs (j :: js, t :: ts, T :: Ts) = {j = j, t = t, T = T} :: flexargs (js, ts, Ts) |
465 | flexargs (j :: js, t :: ts, T :: Ts) = {j = j, t = t, T = T} :: flexargs (js, ts, Ts) |
474 | flexargs _ = raise CHANGE_FAIL; |
466 | flexargs _ = raise CHANGE_FAIL; |
475 (*We give up if we see a variable of function type not applied to a full list of |
467 (*We give up if we see a variable of function type not applied to a full list of |
476 arguments (remember, this code assumes that terms are fully eta-expanded). This situation |
468 arguments (remember, this code assumes that terms are fully eta-expanded). This situation |
477 can occur if a type variable is instantiated with a function type. |
469 can occur if a type variable is instantiated with a function type. |
478 *) |
470 *) |
479 |
471 |
480 (*Check whether the 'banned' bound var indices occur rigidly in t*) |
472 (*Check whether the 'banned' bound var indices occur rigidly in t*) |
481 fun rigid_bound (lev, banned) t = |
473 fun rigid_bound (lev, banned) t = |
525 fun clean_term banned (env,t) = |
517 fun clean_term banned (env,t) = |
526 let |
518 let |
527 val (Var (v, T), ts) = strip_comb t; |
519 val (Var (v, T), ts) = strip_comb t; |
528 val (Ts, U) = strip_type env T |
520 val (Ts, U) = strip_type env T |
529 and js = length ts - 1 downto 0; |
521 and js = length ts - 1 downto 0; |
530 val args = sort (make_ord arg_less) (List.foldr (change_arg banned) [] (flexargs (js, ts, Ts))) |
522 val args = sort (make_ord arg_less) (List.foldr (change_arg banned) [] (flexargs (js, ts, Ts))) |
531 val ts' = map #t args; |
523 val ts' = map #t args; |
532 in |
524 in |
533 if decreasing (length Ts) args then (env, (list_comb (Var (v, T), ts'))) |
525 if decreasing (length Ts) args then (env, (list_comb (Var (v, T), ts'))) |
534 else |
526 else |
535 let |
527 let |
688 fun first_order_matchers thy pairs (Envir.Envir {maxidx, tenv, tyenv}) = |
680 fun first_order_matchers thy pairs (Envir.Envir {maxidx, tenv, tyenv}) = |
689 let val (tyenv', tenv') = fold (Pattern.first_order_match thy) pairs (tyenv, tenv) |
681 let val (tyenv', tenv') = fold (Pattern.first_order_match thy) pairs (tyenv, tenv) |
690 in Seq.single (Envir.Envir {maxidx = maxidx, tenv = tenv', tyenv = tyenv'}) end |
682 in Seq.single (Envir.Envir {maxidx = maxidx, tenv = tenv', tyenv = tyenv'}) end |
691 handle Pattern.MATCH => Seq.empty; |
683 handle Pattern.MATCH => Seq.empty; |
692 |
684 |
693 (*General matching -- keeps variables disjoint*) |
685 (*General matching -- keep variables disjoint*) |
694 fun matchers _ [] = Seq.single (Envir.empty ~1) |
686 fun matchers _ [] = Seq.single (Envir.empty ~1) |
695 | matchers thy pairs = |
687 | matchers thy pairs = |
696 let |
688 let |
697 val maxidx = fold (Term.maxidx_term o #2) pairs ~1; |
689 val maxidx = fold (Term.maxidx_term o #2) pairs ~1; |
698 val offset = maxidx + 1; |
690 val offset = maxidx + 1; |
709 Term.map_types decr_indexesT #> |
701 Term.map_types decr_indexesT #> |
710 Term.map_aterms (fn t as Var ((x, i), T) => |
702 Term.map_aterms (fn t as Var ((x, i), T) => |
711 if i > maxidx then Var ((x, i - offset), T) else t | t => t); |
703 if i > maxidx then Var ((x, i - offset), T) else t | t => t); |
712 |
704 |
713 fun norm_tvar env ((x, i), S) = |
705 fun norm_tvar env ((x, i), S) = |
714 ((x, i - offset), |
706 let |
715 (S, decr_indexesT (Envir.norm_type (Envir.type_env env) (TVar ((x, i), S))))); |
707 val tyenv = Envir.type_env env; |
|
708 val T' = Envir.norm_type tyenv (TVar ((x, i), S)); |
|
709 in |
|
710 if (case T' of TVar (v, _) => v = (x, i) | _ => false) then NONE |
|
711 else SOME ((x, i - offset), (S, decr_indexesT T')) |
|
712 end; |
|
713 |
716 fun norm_var env ((x, i), T) = |
714 fun norm_var env ((x, i), T) = |
717 let |
715 let |
718 val tyenv = Envir.type_env env; |
716 val tyenv = Envir.type_env env; |
719 val T' = Envir.norm_type tyenv T; |
717 val T' = Envir.norm_type tyenv T; |
720 val t' = Envir.norm_term env (Var ((x, i), T')); |
718 val t' = Envir.norm_term env (Var ((x, i), T')); |
721 in ((x, i - offset), (decr_indexesT T', decr_indexes t')) end; |
719 in |
|
720 if (case t' of Var (v, _) => v = (x, i) | _ => false) then NONE |
|
721 else SOME ((x, i - offset), (decr_indexesT T', decr_indexes t')) |
|
722 end; |
722 |
723 |
723 fun result env = |
724 fun result env = |
724 if Envir.above env maxidx then (* FIXME proper handling of generated vars!? *) |
725 if Envir.above env maxidx then (* FIXME proper handling of generated vars!? *) |
725 SOME (Envir.Envir {maxidx = maxidx, |
726 SOME (Envir.Envir {maxidx = maxidx, |
726 tyenv = Vartab.make (filter_out self_asgt (map (norm_tvar env) pat_tvars)), |
727 tyenv = Vartab.make (map_filter (norm_tvar env) pat_tvars), |
727 tenv = Vartab.make (map (norm_var env) pat_vars)}) |
728 tenv = Vartab.make (map_filter (norm_var env) pat_vars)}) |
728 else NONE; |
729 else NONE; |
729 |
730 |
730 val empty = Envir.empty maxidx'; |
731 val empty = Envir.empty maxidx'; |
731 in |
732 in |
732 Seq.append |
733 Seq.append |