src/Provers/simp.ML
changeset 15531 08c8dad8e399
parent 14772 c52060b69a8c
child 15570 8d8c70b41bab
equal deleted inserted replaced
15530:6f43714517ee 15531:08c8dad8e399
   128       | mk(t::ts) = (thm RSN (2,t))  handle THM _  => mk ts
   128       | mk(t::ts) = (thm RSN (2,t))  handle THM _  => mk ts
   129 in mk trans_thms end;
   129 in mk trans_thms end;
   130 
   130 
   131 (*Applies tactic and returns the first resulting state, FAILS if none!*)
   131 (*Applies tactic and returns the first resulting state, FAILS if none!*)
   132 fun one_result(tac,thm) = case Seq.pull(tac thm) of
   132 fun one_result(tac,thm) = case Seq.pull(tac thm) of
   133 	Some(thm',_) => thm'
   133 	SOME(thm',_) => thm'
   134       | None => raise THM("Simplifier: could not continue", 0, [thm]);
   134       | NONE => raise THM("Simplifier: could not continue", 0, [thm]);
   135 
   135 
   136 fun res1(thm,thms,i) = one_result(resolve_tac thms i,thm);
   136 fun res1(thm,thms,i) = one_result(resolve_tac thms i,thm);
   137 
   137 
   138 
   138 
   139 (**** Adding "NORM" tags ****)
   139 (**** Adding "NORM" tags ****)
   172 		end
   172 		end
   173 	fun add_vars (tm,vars) = case tm of
   173 	fun add_vars (tm,vars) = case tm of
   174 		  Abs (_,_,body) => add_vars(body,vars)
   174 		  Abs (_,_,body) => add_vars(body,vars)
   175 		| r$s => (case head_of tm of
   175 		| r$s => (case head_of tm of
   176 			  Const(c,T) => (case assoc(new_asms,c) of
   176 			  Const(c,T) => (case assoc(new_asms,c) of
   177 				  None => add_vars(r,add_vars(s,vars))
   177 				  NONE => add_vars(r,add_vars(s,vars))
   178 				| Some(al) => add_list(tm,al,vars))
   178 				| SOME(al) => add_list(tm,al,vars))
   179 			| _ => add_vars(r,add_vars(s,vars)))
   179 			| _ => add_vars(r,add_vars(s,vars)))
   180 		| _ => vars
   180 		| _ => vars
   181     in add_vars end;
   181     in add_vars end;
   182 
   182 
   183 
   183 
   203 	  | Const _ => resolve_tac normI_thms 1 ORELSE
   203 	  | Const _ => resolve_tac normI_thms 1 ORELSE
   204 		       resolve_tac congs 1 ORELSE refl1_tac
   204 		       resolve_tac congs 1 ORELSE refl1_tac
   205 	  | Free _ => resolve_tac congs 1 ORELSE refl1_tac
   205 	  | Free _ => resolve_tac congs 1 ORELSE refl1_tac
   206 	  | _ => refl1_tac))
   206 	  | _ => refl1_tac))
   207     val add_norm_tac = DEPTH_FIRST (has_fewer_prems nops) norm_step_tac
   207     val add_norm_tac = DEPTH_FIRST (has_fewer_prems nops) norm_step_tac
   208     val Some(thm'',_) = Seq.pull(add_norm_tac thm')
   208     val SOME(thm'',_) = Seq.pull(add_norm_tac thm')
   209 in thm'' end;
   209 in thm'' end;
   210 
   210 
   211 fun add_norm_tags congs =
   211 fun add_norm_tags congs =
   212     let val ccs = map cong_const congs
   212     let val ccs = map cong_const congs
   213 	val new_asms = filter (exists not o #2)
   213 	val new_asms = filter (exists not o #2)
   442 
   442 
   443 fun simp_lhs(thm,ss,anet,ats,cs) =
   443 fun simp_lhs(thm,ss,anet,ats,cs) =
   444     if var_lhs(thm,i) then (ss,thm,anet,ats,cs) else
   444     if var_lhs(thm,i) then (ss,thm,anet,ats,cs) else
   445     if lhs_is_NORM(thm,i) then (ss, res1(thm,trans_norms,i), anet,ats,cs)
   445     if lhs_is_NORM(thm,i) then (ss, res1(thm,trans_norms,i), anet,ats,cs)
   446     else case Seq.pull(cong_tac i thm) of
   446     else case Seq.pull(cong_tac i thm) of
   447 	    Some(thm',_) =>
   447 	    SOME(thm',_) =>
   448 		    let val ps = prems_of thm and ps' = prems_of thm';
   448 		    let val ps = prems_of thm and ps' = prems_of thm';
   449 			val n = length(ps')-length(ps);
   449 			val n = length(ps')-length(ps);
   450 			val a = length(strip_assums_hyp(nth_elem(i-1,ps)))
   450 			val a = length(strip_assums_hyp(nth_elem(i-1,ps)))
   451 			val l = map (fn p => length(strip_assums_hyp(p)))
   451 			val l = map (fn p => length(strip_assums_hyp(p)))
   452 				    (take(n,drop(i-1,ps')));
   452 				    (take(n,drop(i-1,ps')));
   453 		    in (simp_refl(rev(l),a,REW::ss),thm',anet,ats,cs) end
   453 		    in (simp_refl(rev(l),a,REW::ss),thm',anet,ats,cs) end
   454 	  | None => (REW::ss,thm,anet,ats,cs);
   454 	  | NONE => (REW::ss,thm,anet,ats,cs);
   455 
   455 
   456 (*NB: the "Adding rewrites:" trace will look strange because assumptions
   456 (*NB: the "Adding rewrites:" trace will look strange because assumptions
   457       are represented by rules, generalized over their parameters*)
   457       are represented by rules, generalized over their parameters*)
   458 fun add_asms(ss,thm,a,anet,ats,cs) =
   458 fun add_asms(ss,thm,a,anet,ats,cs) =
   459     let val As = strip_varify(nth_subgoal i thm, a, []);
   459     let val As = strip_varify(nth_subgoal i thm, a, []);
   466 	else ();
   466 	else ();
   467 	(ss,thm,anet',anet::ats,cs) 
   467 	(ss,thm,anet',anet::ats,cs) 
   468     end;
   468     end;
   469 
   469 
   470 fun rew(seq,thm,ss,anet,ats,cs, more) = case Seq.pull seq of
   470 fun rew(seq,thm,ss,anet,ats,cs, more) = case Seq.pull seq of
   471       Some(thm',seq') =>
   471       SOME(thm',seq') =>
   472 	    let val n = (nprems_of thm') - (nprems_of thm)
   472 	    let val n = (nprems_of thm') - (nprems_of thm)
   473 	    in pr_rew(i,n,thm,thm',more);
   473 	    in pr_rew(i,n,thm,thm',more);
   474 	       if n=0 then (SIMP_LHS::ss, thm', anet, ats, cs)
   474 	       if n=0 then (SIMP_LHS::ss, thm', anet, ats, cs)
   475 	       else ((replicate n PROVE) @ (POP_CS::SIMP_LHS::ss),
   475 	       else ((replicate n PROVE) @ (POP_CS::SIMP_LHS::ss),
   476 		     thm', anet, ats, (ss,thm,anet,ats,seq',more)::cs)
   476 		     thm', anet, ats, (ss,thm,anet,ats,seq',more)::cs)
   477 	    end
   477 	    end
   478     | None => if more
   478     | NONE => if more
   479 	    then rew(tapply(lhs_net_tac anet i THEN assume_tac i,thm),
   479 	    then rew(tapply(lhs_net_tac anet i THEN assume_tac i,thm),
   480 		     thm,ss,anet,ats,cs,false)
   480 		     thm,ss,anet,ats,cs,false)
   481 	    else (ss,thm,anet,ats,cs);
   481 	    else (ss,thm,anet,ats,cs);
   482 
   482 
   483 fun try_true(thm,ss,anet,ats,cs) =
   483 fun try_true(thm,ss,anet,ats,cs) =
   484     case Seq.pull(auto_tac i thm) of
   484     case Seq.pull(auto_tac i thm) of
   485       Some(thm',_) => (ss,thm',anet,ats,cs)
   485       SOME(thm',_) => (ss,thm',anet,ats,cs)
   486     | None => let val (ss0,thm0,anet0,ats0,seq,more)::cs0 = cs
   486     | NONE => let val (ss0,thm0,anet0,ats0,seq,more)::cs0 = cs
   487 	      in if !tracing
   487 	      in if !tracing
   488 		 then (writeln"*** Failed to prove precondition. Normal form:";
   488 		 then (writeln"*** Failed to prove precondition. Normal form:";
   489 		       pr_goal_concl i thm;  writeln"")
   489 		       pr_goal_concl i thm;  writeln"")
   490 		 else ();
   490 		 else ();
   491 		 rew(seq,thm0,ss0,anet0,ats0,cs0,more)
   491 		 rew(seq,thm0,ss0,anet0,ats0,cs0,more)
   492 	      end;
   492 	      end;
   493 
   493 
   494 fun split(thm,ss,anet,ats,cs) =
   494 fun split(thm,ss,anet,ats,cs) =
   495 	case Seq.pull(tapply(split_tac
   495 	case Seq.pull(tapply(split_tac
   496                                   (cong_tac i,splits,split_consts) i,thm)) of
   496                                   (cong_tac i,splits,split_consts) i,thm)) of
   497 		Some(thm',_) => (SIMP_LHS::SPLIT::ss,thm',anet,ats,cs)
   497 		SOME(thm',_) => (SIMP_LHS::SPLIT::ss,thm',anet,ats,cs)
   498 	      | None => (ss,thm,anet,ats,cs);
   498 	      | NONE => (ss,thm,anet,ats,cs);
   499 
   499 
   500 fun step(s::ss, thm, anet, ats, cs) = case s of
   500 fun step(s::ss, thm, anet, ats, cs) = case s of
   501 	  MK_EQ => (ss, res1(thm,[red2],i), anet, ats, cs)
   501 	  MK_EQ => (ss, res1(thm,[red2],i), anet, ats, cs)
   502 	| ASMS(a) => add_asms(ss,thm,a,anet,ats,cs)
   502 	| ASMS(a) => add_asms(ss,thm,a,anet,ats,cs)
   503 	| SIMP_LHS => simp_lhs(thm,ss,anet,ats,cs)
   503 	| SIMP_LHS => simp_lhs(thm,ss,anet,ats,cs)
   573 fun find_subst tsig T =
   573 fun find_subst tsig T =
   574 let fun find (thm::thms) =
   574 let fun find (thm::thms) =
   575 	let val (Const(_,cT), va, vb) =	dest_red(hd(prems_of thm));
   575 	let val (Const(_,cT), va, vb) =	dest_red(hd(prems_of thm));
   576 	    val [P] = term_vars(concl_of thm) \\ [va,vb]
   576 	    val [P] = term_vars(concl_of thm) \\ [va,vb]
   577 	    val eqT::_ = binder_types cT
   577 	    val eqT::_ = binder_types cT
   578         in if Type.typ_instance tsig (T,eqT) then Some(thm,va,vb,P)
   578         in if Type.typ_instance tsig (T,eqT) then SOME(thm,va,vb,P)
   579 	   else find thms
   579 	   else find thms
   580 	end
   580 	end
   581       | find [] = None
   581       | find [] = NONE
   582 in find subst_thms end;
   582 in find subst_thms end;
   583 
   583 
   584 fun mk_cong sg (f,aTs,rT) (refl,eq) =
   584 fun mk_cong sg (f,aTs,rT) (refl,eq) =
   585 let val tsig = Sign.tsig_of sg;
   585 let val tsig = Sign.tsig_of sg;
   586     val k = length aTs;
   586     val k = length aTs;
   593 	    and cp = cterm_of sg (Pinst(f,rT,eq,k,i,T,yik,aTs))
   593 	    and cp = cterm_of sg (Pinst(f,rT,eq,k,i,T,yik,aTs))
   594 	in cterm_instantiate [(ca,cx),(cb,cy),(cP,cp)] subst end;
   594 	in cterm_instantiate [(ca,cx),(cb,cy),(cP,cp)] subst end;
   595     fun mk(c,T::Ts,i,yik) =
   595     fun mk(c,T::Ts,i,yik) =
   596 	let val si = radixstring(26,"a",i)
   596 	let val si = radixstring(26,"a",i)
   597 	in case find_subst tsig T of
   597 	in case find_subst tsig T of
   598 	     None => mk(c,Ts,i-1,eta_Var(("X"^si,0),T)::yik)
   598 	     NONE => mk(c,Ts,i-1,eta_Var(("X"^si,0),T)::yik)
   599 	   | Some s => let val c' = c RSN (2,ri(s,i,si,T,yik))
   599 	   | SOME s => let val c' = c RSN (2,ri(s,i,si,T,yik))
   600 		       in mk(c',Ts,i-1,eta_Var(("Y"^si,0),T)::yik) end
   600 		       in mk(c',Ts,i-1,eta_Var(("Y"^si,0),T)::yik) end
   601 	end
   601 	end
   602       | mk(c,[],_,_) = c;
   602       | mk(c,[],_,_) = c;
   603 in mk(refl,rev aTs,k-1,[]) end;
   603 in mk(refl,rev aTs,k-1,[]) end;
   604 
   604 
   606 let val (aTs,rT) = strip_type T;
   606 let val (aTs,rT) = strip_type T;
   607     val tsig = Sign.tsig_of sg;
   607     val tsig = Sign.tsig_of sg;
   608     fun find_refl(r::rs) =
   608     fun find_refl(r::rs) =
   609 	let val (Const(eq,eqT),_,_) = dest_red(concl_of r)
   609 	let val (Const(eq,eqT),_,_) = dest_red(concl_of r)
   610 	in if Type.typ_instance tsig (rT, hd(binder_types eqT))
   610 	in if Type.typ_instance tsig (rT, hd(binder_types eqT))
   611 	   then Some(r,(eq,body_type eqT)) else find_refl rs
   611 	   then SOME(r,(eq,body_type eqT)) else find_refl rs
   612 	end
   612 	end
   613       | find_refl([]) = None;
   613       | find_refl([]) = NONE;
   614 in case find_refl refl_thms of
   614 in case find_refl refl_thms of
   615      None => []  |  Some(refl) => [mk_cong sg (f,aTs,rT) refl]
   615      NONE => []  |  SOME(refl) => [mk_cong sg (f,aTs,rT) refl]
   616 end;
   616 end;
   617 
   617 
   618 fun mk_cong_thy thy f =
   618 fun mk_cong_thy thy f =
   619 let val sg = sign_of thy;
   619 let val sg = sign_of thy;
   620     val T = case Sign.const_type sg f of
   620     val T = case Sign.const_type sg f of
   621 		None => error(f^" not declared") | Some(T) => T;
   621 		NONE => error(f^" not declared") | SOME(T) => T;
   622     val T' = incr_tvar 9 T;
   622     val T' = incr_tvar 9 T;
   623 in mk_cong_type sg (Const(f,T'),T') end;
   623 in mk_cong_type sg (Const(f,T'),T') end;
   624 
   624 
   625 fun mk_congs thy = filter_out is_fact o flat o map (mk_cong_thy thy);
   625 fun mk_congs thy = filter_out is_fact o flat o map (mk_cong_thy thy);
   626 
   626 
   627 fun mk_typed_congs thy =
   627 fun mk_typed_congs thy =
   628 let val sg = sign_of thy;
   628 let val sg = sign_of thy;
   629     val S0 = Sign.defaultS sg;
   629     val S0 = Sign.defaultS sg;
   630     fun readfT(f,s) =
   630     fun readfT(f,s) =
   631 	let val T = incr_tvar 9 (Sign.read_typ(sg,K(Some(S0))) s);
   631 	let val T = incr_tvar 9 (Sign.read_typ(sg,K(SOME(S0))) s);
   632 	    val t = case Sign.const_type sg f of
   632 	    val t = case Sign.const_type sg f of
   633 		      Some(_) => Const(f,T) | None => Free(f,T)
   633 		      SOME(_) => Const(f,T) | NONE => Free(f,T)
   634 	in (t,T) end
   634 	in (t,T) end
   635 in flat o map (mk_cong_type sg o readfT) end;
   635 in flat o map (mk_cong_type sg o readfT) end;
   636 
   636 
   637 (* This code is fishy, esp the "let val T' = ..." 
   637 (* This code is fishy, esp the "let val T' = ..." 
   638 fun extract_free_congs() =
   638 fun extract_free_congs() =