278 |
278 |
279 (*Recursion needed if any of the 'head variables' have been updated |
279 (*Recursion needed if any of the 'head variables' have been updated |
280 Clever would be to re-do just the affected dpairs*) |
280 Clever would be to re-do just the affected dpairs*) |
281 fun SIMPL thy (env,dpairs) : Envir.env * dpair list * dpair list = |
281 fun SIMPL thy (env,dpairs) : Envir.env * dpair list * dpair list = |
282 let val all as (env',flexflex,flexrigid) = |
282 let val all as (env',flexflex,flexrigid) = |
283 foldr (SIMPL0 thy) (env,[],[]) dpairs; |
283 List.foldr (SIMPL0 thy) (env,[],[]) dpairs; |
284 val dps = flexrigid@flexflex |
284 val dps = flexrigid@flexflex |
285 in if exists (fn ((_,t,u)) => changed(env',t) orelse changed(env',u)) dps |
285 in if exists (fn ((_,t,u)) => changed(env',t) orelse changed(env',u)) dps |
286 then SIMPL thy (env',dps) else all |
286 then SIMPL thy (env',dps) else all |
287 end; |
287 end; |
288 |
288 |
469 fun clean_term banned (env,t) = |
469 fun clean_term banned (env,t) = |
470 let val (Var(v,T), ts) = strip_comb t |
470 let val (Var(v,T), ts) = strip_comb t |
471 val (Ts,U) = strip_type env T |
471 val (Ts,U) = strip_type env T |
472 and js = length ts - 1 downto 0 |
472 and js = length ts - 1 downto 0 |
473 val args = sort (make_ord arg_less) |
473 val args = sort (make_ord arg_less) |
474 (foldr (change_arg banned) [] (flexargs (js,ts,Ts))) |
474 (List.foldr (change_arg banned) [] (flexargs (js,ts,Ts))) |
475 val ts' = map (#t) args |
475 val ts' = map (#t) args |
476 in |
476 in |
477 if decreasing (length Ts) args then (env, (list_comb(Var(v,T), ts'))) |
477 if decreasing (length Ts) args then (env, (list_comb(Var(v,T), ts'))) |
478 else let val (env',v') = Envir.genvar (#1v) (env, map (#T) args ---> U) |
478 else let val (env',v') = Envir.genvar (#1v) (env, map (#T) args ---> U) |
479 val body = list_comb(v', map (Bound o #j) args) |
479 val body = list_comb(v', map (Bound o #j) args) |
502 fun add_index (((a,T), j), (bnos, newbinder)) = |
502 fun add_index (((a,T), j), (bnos, newbinder)) = |
503 if member (op =) loot j andalso member (op =) loou j |
503 if member (op =) loot j andalso member (op =) loou j |
504 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
504 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
505 else (j::bnos, newbinder); (*remove*) |
505 else (j::bnos, newbinder); (*remove*) |
506 val indices = 0 upto (length rbinder - 1); |
506 val indices = 0 upto (length rbinder - 1); |
507 val (banned,rbin') = foldr add_index ([],[]) (rbinder~~indices); |
507 val (banned,rbin') = List.foldr add_index ([],[]) (rbinder~~indices); |
508 val (env', t') = clean_term banned (env, t); |
508 val (env', t') = clean_term banned (env, t); |
509 val (env'',u') = clean_term banned (env',u) |
509 val (env'',u') = clean_term banned (env',u) |
510 in (ff_assign thy (env'', rbin', t', u'), tpairs) |
510 in (ff_assign thy (env'', rbin', t', u'), tpairs) |
511 handle ASSIGN => (ff_assign thy (env'', rbin', u', t'), tpairs) |
511 handle ASSIGN => (ff_assign thy (env'', rbin', u', t'), tpairs) |
512 handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs)) |
512 handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs)) |
556 let val (env',flexflex,flexrigid) = |
556 let val (env',flexflex,flexrigid) = |
557 (if tdepth> !trace_bound andalso !trace_simp |
557 (if tdepth> !trace_bound andalso !trace_simp |
558 then print_dpairs thy "Enter SIMPL" (env,dpairs) else (); |
558 then print_dpairs thy "Enter SIMPL" (env,dpairs) else (); |
559 SIMPL thy (env,dpairs)) |
559 SIMPL thy (env,dpairs)) |
560 in case flexrigid of |
560 in case flexrigid of |
561 [] => SOME (foldr (add_ffpair thy) (env',[]) flexflex, reseq) |
561 [] => SOME (List.foldr (add_ffpair thy) (env',[]) flexflex, reseq) |
562 | dp::frigid' => |
562 | dp::frigid' => |
563 if tdepth > !search_bound then |
563 if tdepth > !search_bound then |
564 (warning "Unification bound exceeded"; Seq.pull reseq) |
564 (warning "Unification bound exceeded"; Seq.pull reseq) |
565 else |
565 else |
566 (if tdepth > !trace_bound then |
566 (if tdepth > !trace_bound then |
605 end; |
605 end; |
606 |
606 |
607 |
607 |
608 (*Smash all flex-flexpairs. Should allow selection of pairs by a predicate?*) |
608 (*Smash all flex-flexpairs. Should allow selection of pairs by a predicate?*) |
609 fun smash_flexflex (env,tpairs) : Envir.env = |
609 fun smash_flexflex (env,tpairs) : Envir.env = |
610 foldr smash_flexflex1 env tpairs; |
610 List.foldr smash_flexflex1 env tpairs; |
611 |
611 |
612 (*Returns unifiers with no remaining disagreement pairs*) |
612 (*Returns unifiers with no remaining disagreement pairs*) |
613 fun smash_unifiers thy tus env = |
613 fun smash_unifiers thy tus env = |
614 Seq.map smash_flexflex (unifiers(thy,env,tus)); |
614 Seq.map smash_flexflex (unifiers(thy,env,tus)); |
615 |
615 |