289 |
289 |
290 (*Recursion needed if any of the 'head variables' have been updated |
290 (*Recursion needed if any of the 'head variables' have been updated |
291 Clever would be to re-do just the affected dpairs*) |
291 Clever would be to re-do just the affected dpairs*) |
292 fun SIMPL (env,dpairs) : Envir.env * dpair list * dpair list = |
292 fun SIMPL (env,dpairs) : Envir.env * dpair list * dpair list = |
293 let val all as (env',flexflex,flexrigid) = |
293 let val all as (env',flexflex,flexrigid) = |
294 foldr SIMPL0 (dpairs, (env,[],[])); |
294 Library.foldr SIMPL0 (dpairs, (env,[],[])); |
295 val dps = flexrigid@flexflex |
295 val dps = flexrigid@flexflex |
296 in if exists (fn ((_,t,u)) => changed(env',t) orelse changed(env',u)) dps |
296 in if exists (fn ((_,t,u)) => changed(env',t) orelse changed(env',u)) dps |
297 then SIMPL(env',dps) else all |
297 then SIMPL(env',dps) else all |
298 end; |
298 end; |
299 |
299 |
456 fun change_bnos banned = |
456 fun change_bnos banned = |
457 let fun change lev (Bound i) = |
457 let fun change lev (Bound i) = |
458 if i<lev then Bound i |
458 if i<lev then Bound i |
459 else if (i-lev) mem_int banned |
459 else if (i-lev) mem_int banned |
460 then raise CHANGE_FAIL (**flexible occurrence: give up**) |
460 then raise CHANGE_FAIL (**flexible occurrence: give up**) |
461 else Bound (i - length (filter (fn j => j < i-lev) banned)) |
461 else Bound (i - length (List.filter (fn j => j < i-lev) banned)) |
462 | change lev (Abs (a,T,t)) = Abs (a, T, change(lev+1) t) |
462 | change lev (Abs (a,T,t)) = Abs (a, T, change(lev+1) t) |
463 | change lev (t$u) = change lev t $ change lev u |
463 | change lev (t$u) = change lev t $ change lev u |
464 | change lev t = t |
464 | change lev t = t |
465 in change 0 end; |
465 in change 0 end; |
466 |
466 |
486 fun clean_term banned (env,t) = |
486 fun clean_term banned (env,t) = |
487 let val (Var(v,T), ts) = strip_comb t |
487 let val (Var(v,T), ts) = strip_comb t |
488 val (Ts,U) = strip_type env T |
488 val (Ts,U) = strip_type env T |
489 and js = length ts - 1 downto 0 |
489 and js = length ts - 1 downto 0 |
490 val args = sort (make_ord arg_less) |
490 val args = sort (make_ord arg_less) |
491 (foldr (change_arg banned) (flexargs (js,ts,Ts), [])) |
491 (Library.foldr (change_arg banned) (flexargs (js,ts,Ts), [])) |
492 val ts' = map (#t) args |
492 val ts' = map (#t) args |
493 in |
493 in |
494 if decreasing (length Ts) args then (env, (list_comb(Var(v,T), ts'))) |
494 if decreasing (length Ts) args then (env, (list_comb(Var(v,T), ts'))) |
495 else let val (env',v') = Envir.genvar (#1v) (env, map (#T) args ---> U) |
495 else let val (env',v') = Envir.genvar (#1v) (env, map (#T) args ---> U) |
496 val body = list_comb(v', map (Bound o #j) args) |
496 val body = list_comb(v', map (Bound o #j) args) |
519 fun add_index (((a,T), j), (bnos, newbinder)) = |
519 fun add_index (((a,T), j), (bnos, newbinder)) = |
520 if j mem_int loot andalso j mem_int loou |
520 if j mem_int loot andalso j mem_int loou |
521 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
521 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
522 else (j::bnos, newbinder); (*remove*) |
522 else (j::bnos, newbinder); (*remove*) |
523 val indices = 0 upto (length rbinder - 1); |
523 val indices = 0 upto (length rbinder - 1); |
524 val (banned,rbin') = foldr add_index (rbinder~~indices, ([],[])); |
524 val (banned,rbin') = Library.foldr add_index (rbinder~~indices, ([],[])); |
525 val (env', t') = clean_term banned (env, t); |
525 val (env', t') = clean_term banned (env, t); |
526 val (env'',u') = clean_term banned (env',u) |
526 val (env'',u') = clean_term banned (env',u) |
527 in (ff_assign(env'', rbin', t', u'), tpairs) |
527 in (ff_assign(env'', rbin', t', u'), tpairs) |
528 handle ASSIGN => (ff_assign(env'', rbin', u', t'), tpairs) |
528 handle ASSIGN => (ff_assign(env'', rbin', u', t'), tpairs) |
529 handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs)) |
529 handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs)) |
558 let fun termT t = Sign.pretty_term (!sgr) |
558 let fun termT t = Sign.pretty_term (!sgr) |
559 (Envir.norm_term env (rlist_abs(rbinder,t))) |
559 (Envir.norm_term env (rlist_abs(rbinder,t))) |
560 val bsymbs = [termT u, Pretty.str" =?=", Pretty.brk 1, |
560 val bsymbs = [termT u, Pretty.str" =?=", Pretty.brk 1, |
561 termT t]; |
561 termT t]; |
562 in tracing(Pretty.string_of(Pretty.blk(0,bsymbs))) end; |
562 in tracing(Pretty.string_of(Pretty.blk(0,bsymbs))) end; |
563 in tracing msg; seq pdp dpairs end; |
563 in tracing msg; List.app pdp dpairs end; |
564 |
564 |
565 |
565 |
566 (*Unify the dpairs in the environment. |
566 (*Unify the dpairs in the environment. |
567 Returns flex-flex disagreement pairs NOT IN normal form. |
567 Returns flex-flex disagreement pairs NOT IN normal form. |
568 SIMPL may raise exception CANTUNIFY. *) |
568 SIMPL may raise exception CANTUNIFY. *) |
573 let val (env',flexflex,flexrigid) = |
573 let val (env',flexflex,flexrigid) = |
574 (if tdepth> !trace_bound andalso !trace_simp |
574 (if tdepth> !trace_bound andalso !trace_simp |
575 then print_dpairs "Enter SIMPL" (env,dpairs) else (); |
575 then print_dpairs "Enter SIMPL" (env,dpairs) else (); |
576 SIMPL (env,dpairs)) |
576 SIMPL (env,dpairs)) |
577 in case flexrigid of |
577 in case flexrigid of |
578 [] => SOME (foldr add_ffpair (flexflex, (env',[])), reseq) |
578 [] => SOME (Library.foldr add_ffpair (flexflex, (env',[])), reseq) |
579 | dp::frigid' => |
579 | dp::frigid' => |
580 if tdepth > !search_bound then |
580 if tdepth > !search_bound then |
581 (warning "Unification bound exceeded"; Seq.pull reseq) |
581 (warning "Unification bound exceeded"; Seq.pull reseq) |
582 else |
582 else |
583 (if tdepth > !trace_bound then |
583 (if tdepth > !trace_bound then |
624 end; |
624 end; |
625 |
625 |
626 |
626 |
627 (*Smash all flex-flexpairs. Should allow selection of pairs by a predicate?*) |
627 (*Smash all flex-flexpairs. Should allow selection of pairs by a predicate?*) |
628 fun smash_flexflex (env,tpairs) : Envir.env = |
628 fun smash_flexflex (env,tpairs) : Envir.env = |
629 foldr smash_flexflex1 (tpairs, env); |
629 Library.foldr smash_flexflex1 (tpairs, env); |
630 |
630 |
631 (*Returns unifiers with no remaining disagreement pairs*) |
631 (*Returns unifiers with no remaining disagreement pairs*) |
632 fun smash_unifiers (sg, env, tus) : Envir.env Seq.seq = |
632 fun smash_unifiers (sg, env, tus) : Envir.env Seq.seq = |
633 Seq.map smash_flexflex (unifiers(sg,env,tus)); |
633 Seq.map smash_flexflex (unifiers(sg,env,tus)); |
634 |
634 |