src/Pure/unify.ML
changeset 23178 07ba6b58b3d2
parent 20664 ffbc5a57191a
child 24178 4ff1dc2aa18d
equal deleted inserted replaced
23177:3004310c95b1 23178:07ba6b58b3d2
   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