src/Pure/logic.ML
changeset 9460 53d7ad5bec39
parent 5041 a1d0a6d555cd
child 9483 708a8a05497d
equal deleted inserted replaced
9459:259349bb8397 9460:53d7ad5bec39
     1 (*  Title: 	Pure/logic.ML
     1 (*  Title:      Pure/logic.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   Cambridge University 1992
     4     Copyright   Cambridge University 1992
     5 
     5 
     6 Supporting code for defining the abstract type "thm"
     6 Abstract syntax operations of the Pure meta-logic.
     7 *)
     7 *)
     8 
     8 
     9 infix occs;
     9 infix occs;
    10 
    10 
    11 signature LOGIC = 
    11 signature LOGIC =
    12 sig
    12 sig
    13   val assum_pairs	: term -> (term*term)list
       
    14   val auto_rename	: bool ref   
       
    15   val close_form	: term -> term   
       
    16   val count_prems	: term * int -> int
       
    17   val dest_equals	: term -> term * term
       
    18   val dest_flexpair	: term -> term * term
       
    19   val dest_implies	: term -> term * term
       
    20   val dest_inclass	: term -> typ * class
       
    21   val dest_type		: term -> typ
       
    22   val flatten_params	: int -> term -> term
       
    23   val incr_indexes	: typ list * int -> term -> term
       
    24   val is_all            : term -> bool
    13   val is_all            : term -> bool
       
    14   val mk_equals         : term * term -> term
       
    15   val dest_equals       : term -> term * term
    25   val is_equals         : term -> bool
    16   val is_equals         : term -> bool
       
    17   val mk_implies        : term * term -> term
       
    18   val dest_implies      : term -> term * term
    26   val is_implies        : term -> bool
    19   val is_implies        : term -> bool
    27   val lift_fns		: term * int -> (term -> term) * (term -> term)
    20   val list_implies      : term list * term -> term
    28   val list_flexpairs	: (term*term)list * term -> term
    21   val strip_imp_prems   : term -> term list
    29   val list_implies	: term list * term -> term
    22   val strip_imp_concl   : term -> term
       
    23   val strip_prems       : int * term list * term -> term list * term
       
    24   val count_prems       : term * int -> int
       
    25   val mk_flexpair       : term * term -> term
       
    26   val dest_flexpair     : term -> term * term
       
    27   val list_flexpairs    : (term*term)list * term -> term
       
    28   val rule_of           : (term*term)list * term list * term -> term
       
    29   val strip_flexpairs   : term -> (term*term)list * term
       
    30   val skip_flexpairs    : term -> term
       
    31   val strip_horn        : term -> (term*term)list * term list * term
       
    32   val mk_cond_defpair   : term list -> term * term -> string * term
       
    33   val mk_defpair        : term * term -> string * term
       
    34   val mk_type           : typ -> term
       
    35   val dest_type         : term -> typ
       
    36   val mk_inclass        : typ * class -> term
       
    37   val dest_inclass      : term -> typ * class
       
    38   val goal_const        : term
       
    39   val mk_goal           : term -> term
       
    40   val dest_goal         : term -> term
       
    41   val occs              : term * term -> bool
       
    42   val close_form        : term -> term
       
    43   val incr_indexes      : typ list * int -> term -> term
       
    44   val lift_fns          : term * int -> (term -> term) * (term -> term)
       
    45   val strip_assums_hyp  : term -> term list
       
    46   val strip_assums_concl: term -> term
       
    47   val strip_params      : term -> (string * typ) list
       
    48   val flatten_params    : int -> term -> term
       
    49   val auto_rename       : bool ref
       
    50   val set_rename_prefix : string -> unit
    30   val list_rename_params: string list * term -> term
    51   val list_rename_params: string list * term -> term
    31   val mk_cond_defpair	: term list -> term * term -> string * term
    52   val assum_pairs       : term -> (term*term)list
    32   val mk_defpair	: term * term -> string * term
    53   val varify            : term -> term
    33   val mk_equals		: term * term -> term
    54   val unvarify          : term -> term
    34   val mk_flexpair	: term * term -> term
       
    35   val mk_implies	: term * term -> term
       
    36   val mk_inclass	: typ * class -> term
       
    37   val mk_type		: typ -> term
       
    38   val occs		: term * term -> bool
       
    39   val rule_of		: (term*term)list * term list * term -> term
       
    40   val set_rename_prefix	: string -> unit   
       
    41   val skip_flexpairs	: term -> term
       
    42   val strip_assums_concl: term -> term
       
    43   val strip_assums_hyp	: term -> term list
       
    44   val strip_flexpairs	: term -> (term*term)list * term
       
    45   val strip_horn	: term -> (term*term)list * term list * term
       
    46   val strip_imp_concl	: term -> term
       
    47   val strip_imp_prems	: term -> term list
       
    48   val strip_params	: term -> (string * typ) list
       
    49   val strip_prems	: int * term list * term -> term list * term
       
    50   val unvarify		: term -> term
       
    51   val varify		: term -> term
       
    52 end;
    55 end;
    53 
    56 
    54 structure Logic : LOGIC =
    57 structure Logic : LOGIC =
    55 struct
    58 struct
    56 
    59 
    99 (* A1==>...An==>B  goes to B, where B is not an implication *)
   102 (* A1==>...An==>B  goes to B, where B is not an implication *)
   100 fun strip_imp_concl (Const("==>", _) $ A $ B) = strip_imp_concl B
   103 fun strip_imp_concl (Const("==>", _) $ A $ B) = strip_imp_concl B
   101   | strip_imp_concl A = A : term;
   104   | strip_imp_concl A = A : term;
   102 
   105 
   103 (*Strip and return premises: (i, [], A1==>...Ai==>B)
   106 (*Strip and return premises: (i, [], A1==>...Ai==>B)
   104     goes to   ([Ai, A(i-1),...,A1] , B) 	(REVERSED) 
   107     goes to   ([Ai, A(i-1),...,A1] , B)         (REVERSED)
   105   if  i<0 or else i too big then raises  TERM*)
   108   if  i<0 or else i too big then raises  TERM*)
   106 fun strip_prems (0, As, B) = (As, B) 
   109 fun strip_prems (0, As, B) = (As, B)
   107   | strip_prems (i, As, Const("==>", _) $ A $ B) = 
   110   | strip_prems (i, As, Const("==>", _) $ A $ B) =
   108 	strip_prems (i-1, A::As, B)
   111         strip_prems (i-1, A::As, B)
   109   | strip_prems (_, As, A) = raise TERM("strip_prems", A::As);
   112   | strip_prems (_, As, A) = raise TERM("strip_prems", A::As);
   110 
   113 
   111 (*Count premises -- quicker than (length ostrip_prems) *)
   114 (*Count premises -- quicker than (length ostrip_prems) *)
   112 fun count_prems (Const("==>", _) $ A $ B, n) = count_prems (B,n+1)
   115 fun count_prems (Const("==>", _) $ A $ B, n) = count_prems (B,n+1)
   113   | count_prems (_,n) = n;
   116   | count_prems (_,n) = n;
   123 
   126 
   124 (*make flexflex antecedents: ( [(a1,b1),...,(an,bn)] , C )
   127 (*make flexflex antecedents: ( [(a1,b1),...,(an,bn)] , C )
   125     goes to (a1=?=b1) ==>...(an=?=bn)==>C *)
   128     goes to (a1=?=b1) ==>...(an=?=bn)==>C *)
   126 fun list_flexpairs ([], A) = A
   129 fun list_flexpairs ([], A) = A
   127   | list_flexpairs ((t,u)::pairs, A) =
   130   | list_flexpairs ((t,u)::pairs, A) =
   128 	implies $ (mk_flexpair(t,u)) $ list_flexpairs(pairs,A);
   131         implies $ (mk_flexpair(t,u)) $ list_flexpairs(pairs,A);
   129 
   132 
   130 (*Make the object-rule tpairs==>As==>B   *)
   133 (*Make the object-rule tpairs==>As==>B   *)
   131 fun rule_of (tpairs, As, B) = list_flexpairs(tpairs, list_implies(As, B));
   134 fun rule_of (tpairs, As, B) = list_flexpairs(tpairs, list_implies(As, B));
   132 
   135 
   133 (*Remove and return flexflex pairs: 
   136 (*Remove and return flexflex pairs:
   134     (a1=?=b1)==>...(an=?=bn)==>C  to  ( [(a1,b1),...,(an,bn)] , C )	
   137     (a1=?=b1)==>...(an=?=bn)==>C  to  ( [(a1,b1),...,(an,bn)] , C )
   135   [Tail recursive in order to return a pair of results] *)
   138   [Tail recursive in order to return a pair of results] *)
   136 fun strip_flex_aux (pairs, Const("==>", _) $ (Const("=?=",_)$t$u) $ C) =
   139 fun strip_flex_aux (pairs, Const("==>", _) $ (Const("=?=",_)$t$u) $ C) =
   137         strip_flex_aux ((t,u)::pairs, C)
   140         strip_flex_aux ((t,u)::pairs, C)
   138   | strip_flex_aux (pairs,C) = (rev pairs, C);
   141   | strip_flex_aux (pairs,C) = (rev pairs, C);
   139 
   142 
   140 fun strip_flexpairs A = strip_flex_aux([], A);
   143 fun strip_flexpairs A = strip_flex_aux([], A);
   141 
   144 
   142 (*Discard flexflex pairs*)
   145 (*Discard flexflex pairs*)
   143 fun skip_flexpairs (Const("==>", _) $ (Const("=?=",_)$_$_) $ C) =
   146 fun skip_flexpairs (Const("==>", _) $ (Const("=?=",_)$_$_) $ C) =
   144 	skip_flexpairs C
   147         skip_flexpairs C
   145   | skip_flexpairs C = C;
   148   | skip_flexpairs C = C;
   146 
   149 
   147 (*strip a proof state (Horn clause): 
   150 (*strip a proof state (Horn clause):
   148    (a1==b1)==>...(am==bm)==>B1==>...Bn==>C
   151    (a1==b1)==>...(am==bm)==>B1==>...Bn==>C
   149     goes to   ( [(a1,b1),...,(am,bm)] , [B1,...,Bn] , C)    *)
   152     goes to   ( [(a1,b1),...,(am,bm)] , [B1,...,Bn] , C)    *)
   150 fun strip_horn A =
   153 fun strip_horn A =
   151   let val (tpairs,horn) = strip_flexpairs A 
   154   let val (tpairs,horn) = strip_flexpairs A
   152   in  (tpairs, strip_imp_prems horn, strip_imp_concl horn)   end;
   155   in  (tpairs, strip_imp_prems horn, strip_imp_concl horn)   end;
   153 
   156 
   154 
   157 
   155 (** definitions **)
   158 (** definitions **)
   156 
   159 
   180       ((dest_type ty, Sign.class_of_const c_class)
   183       ((dest_type ty, Sign.class_of_const c_class)
   181         handle TERM _ => raise TERM ("dest_inclass", [t]))
   184         handle TERM _ => raise TERM ("dest_inclass", [t]))
   182   | dest_inclass t = raise TERM ("dest_inclass", [t]);
   185   | dest_inclass t = raise TERM ("dest_inclass", [t]);
   183 
   186 
   184 
   187 
       
   188 (** atomic goals **)
       
   189 
       
   190 val goal_const = Const ("Goal", propT --> propT);
       
   191 fun mk_goal t = goal_const $ t;
       
   192 
       
   193 fun dest_goal (Const ("Goal", _) $ t) = t
       
   194   | dest_goal t = raise TERM ("dest_goal", [t]);
       
   195 
       
   196 
   185 (*** Low-level term operations ***)
   197 (*** Low-level term operations ***)
   186 
   198 
   187 (*Does t occur in u?  Or is alpha-convertible to u?
   199 (*Does t occur in u?  Or is alpha-convertible to u?
   188   The term t must contain no loose bound variables*)
   200   The term t must contain no loose bound variables*)
   189 fun t occs u = exists_subterm (fn s => t aconv s) u;
   201 fun t occs u = exists_subterm (fn s => t aconv s) u;
   195 
   207 
   196 (*** Specialized operations for resolution... ***)
   208 (*** Specialized operations for resolution... ***)
   197 
   209 
   198 (*For all variables in the term, increment indexnames and lift over the Us
   210 (*For all variables in the term, increment indexnames and lift over the Us
   199     result is ?Gidx(B.(lev+n-1),...,B.lev) where lev is abstraction level *)
   211     result is ?Gidx(B.(lev+n-1),...,B.lev) where lev is abstraction level *)
   200 fun incr_indexes (Us: typ list, inc:int) t = 
   212 fun incr_indexes (Us: typ list, inc:int) t =
   201   let fun incr (Var ((a,i), T), lev) = 
   213   let fun incr (Var ((a,i), T), lev) =
   202 		Unify.combound (Var((a, i+inc), Us---> incr_tvar inc T),
   214                 Unify.combound (Var((a, i+inc), Us---> incr_tvar inc T),
   203 				lev, length Us)
   215                                 lev, length Us)
   204 	| incr (Abs (a,T,body), lev) =
   216         | incr (Abs (a,T,body), lev) =
   205 		Abs (a, incr_tvar inc T, incr(body,lev+1))
   217                 Abs (a, incr_tvar inc T, incr(body,lev+1))
   206 	| incr (Const(a,T),_) = Const(a, incr_tvar inc T)
   218         | incr (Const(a,T),_) = Const(a, incr_tvar inc T)
   207 	| incr (Free(a,T),_) = Free(a, incr_tvar inc T)
   219         | incr (Free(a,T),_) = Free(a, incr_tvar inc T)
   208 	| incr (f$t, lev) = incr(f,lev) $ incr(t,lev)
   220         | incr (f$t, lev) = incr(f,lev) $ incr(t,lev)
   209 	| incr (t,lev) = t
   221         | incr (t,lev) = t
   210   in  incr(t,0)  end;
   222   in  incr(t,0)  end;
   211 
   223 
   212 (*Make lifting functions from subgoal and increment.
   224 (*Make lifting functions from subgoal and increment.
   213     lift_abs operates on tpairs (unification constraints)
   225     lift_abs operates on tpairs (unification constraints)
   214     lift_all operates on propositions     *)
   226     lift_all operates on propositions     *)
   215 fun lift_fns (B,inc) =
   227 fun lift_fns (B,inc) =
   216   let fun lift_abs (Us, Const("==>", _) $ _ $ B) u = lift_abs (Us,B) u
   228   let fun lift_abs (Us, Const("==>", _) $ _ $ B) u = lift_abs (Us,B) u
   217 	| lift_abs (Us, Const("all",_)$Abs(a,T,t)) u =
   229         | lift_abs (Us, Const("all",_)$Abs(a,T,t)) u =
   218 	      Abs(a, T, lift_abs (T::Us, t) u)
   230               Abs(a, T, lift_abs (T::Us, t) u)
   219 	| lift_abs (Us, _) u = incr_indexes(rev Us, inc) u
   231         | lift_abs (Us, _) u = incr_indexes(rev Us, inc) u
   220       fun lift_all (Us, Const("==>", _) $ A $ B) u =
   232       fun lift_all (Us, Const("==>", _) $ A $ B) u =
   221 	      implies $ A $ lift_all (Us,B) u
   233               implies $ A $ lift_all (Us,B) u
   222 	| lift_all (Us, Const("all",_)$Abs(a,T,t)) u = 
   234         | lift_all (Us, Const("all",_)$Abs(a,T,t)) u =
   223 	      all T $ Abs(a, T, lift_all (T::Us,t) u)
   235               all T $ Abs(a, T, lift_all (T::Us,t) u)
   224 	| lift_all (Us, _) u = incr_indexes(rev Us, inc) u;
   236         | lift_all (Us, _) u = incr_indexes(rev Us, inc) u;
   225   in  (lift_abs([],B), lift_all([],B))  end;
   237   in  (lift_abs([],B), lift_all([],B))  end;
   226 
   238 
   227 (*Strips assumptions in goal, yielding list of hypotheses.   *)
   239 (*Strips assumptions in goal, yielding list of hypotheses.   *)
   228 fun strip_assums_hyp (Const("==>", _) $ H $ B) = H :: strip_assums_hyp B
   240 fun strip_assums_hyp (Const("==>", _) $ H $ B) = H :: strip_assums_hyp B
   229   | strip_assums_hyp (Const("all",_)$Abs(a,T,t)) = strip_assums_hyp t
   241   | strip_assums_hyp (Const("all",_)$Abs(a,T,t)) = strip_assums_hyp t
   238 fun strip_params (Const("==>", _) $ H $ B) = strip_params B
   250 fun strip_params (Const("==>", _) $ H $ B) = strip_params B
   239   | strip_params (Const("all",_)$Abs(a,T,t)) = (a,T) :: strip_params t
   251   | strip_params (Const("all",_)$Abs(a,T,t)) = (a,T) :: strip_params t
   240   | strip_params B = [];
   252   | strip_params B = [];
   241 
   253 
   242 (*Removes the parameters from a subgoal and renumber bvars in hypotheses,
   254 (*Removes the parameters from a subgoal and renumber bvars in hypotheses,
   243     where j is the total number of parameters (precomputed) 
   255     where j is the total number of parameters (precomputed)
   244   If n>0 then deletes assumption n. *)
   256   If n>0 then deletes assumption n. *)
   245 fun remove_params j n A = 
   257 fun remove_params j n A =
   246     if j=0 andalso n<=0 then A  (*nothing left to do...*)
   258     if j=0 andalso n<=0 then A  (*nothing left to do...*)
   247     else case A of
   259     else case A of
   248         Const("==>", _) $ H $ B => 
   260         Const("==>", _) $ H $ B =>
   249 	  if n=1 then                           (remove_params j (n-1) B)
   261           if n=1 then                           (remove_params j (n-1) B)
   250 	  else implies $ (incr_boundvars j H) $ (remove_params j (n-1) B)
   262           else implies $ (incr_boundvars j H) $ (remove_params j (n-1) B)
   251       | Const("all",_)$Abs(a,T,t) => remove_params (j-1) n t
   263       | Const("all",_)$Abs(a,T,t) => remove_params (j-1) n t
   252       | _ => if n>0 then raise TERM("remove_params", [A])
   264       | _ => if n>0 then raise TERM("remove_params", [A])
   253              else A;
   265              else A;
   254 
   266 
   255 (** Auto-renaming of parameters in subgoals **)
   267 (** Auto-renaming of parameters in subgoals **)
   272 
   284 
   273 (*Move all parameters to the front of the subgoal, renaming them apart;
   285 (*Move all parameters to the front of the subgoal, renaming them apart;
   274   if n>0 then deletes assumption n. *)
   286   if n>0 then deletes assumption n. *)
   275 fun flatten_params n A =
   287 fun flatten_params n A =
   276     let val params = strip_params A;
   288     let val params = strip_params A;
   277 	val vars = if !auto_rename 
   289         val vars = if !auto_rename
   278 		   then rename_vars (!rename_prefix, params)
   290                    then rename_vars (!rename_prefix, params)
   279 		   else ListPair.zip (variantlist(map #1 params,[]),
   291                    else ListPair.zip (variantlist(map #1 params,[]),
   280 				      map #2 params)
   292                                       map #2 params)
   281     in  list_all (vars, remove_params (length vars) n A)
   293     in  list_all (vars, remove_params (length vars) n A)
   282     end;
   294     end;
   283 
   295 
   284 (*Makes parameters in a goal have the names supplied by the list cs.*)
   296 (*Makes parameters in a goal have the names supplied by the list cs.*)
   285 fun list_rename_params (cs, Const("==>", _) $ A $ B) =
   297 fun list_rename_params (cs, Const("==>", _) $ A $ B) =
   286       implies $ A $ list_rename_params (cs, B)
   298       implies $ A $ list_rename_params (cs, B)
   287   | list_rename_params (c::cs, Const("all",_)$Abs(_,T,t)) = 
   299   | list_rename_params (c::cs, Const("all",_)$Abs(_,T,t)) =
   288       all T $ Abs(c, T, list_rename_params (cs, t))
   300       all T $ Abs(c, T, list_rename_params (cs, t))
   289   | list_rename_params (cs, B) = B;
   301   | list_rename_params (cs, B) = B;
   290 
   302 
   291 (*Strips assumptions in goal yielding  ( [Hn,...,H1], [xm,...,x1], B )
   303 (*Strips assumptions in goal yielding  ( [Hn,...,H1], [xm,...,x1], B )
   292   where H1,...,Hn are the hypotheses and x1...xm are the parameters.   *)
   304   where H1,...,Hn are the hypotheses and x1...xm are the parameters.   *)
   293 fun strip_assums_aux (Hs, params, Const("==>", _) $ H $ B) = 
   305 fun strip_assums_aux (Hs, params, Const("==>", _) $ H $ B) =
   294 	strip_assums_aux (H::Hs, params, B)
   306         strip_assums_aux (H::Hs, params, B)
   295   | strip_assums_aux (Hs, params, Const("all",_)$Abs(a,T,t)) =
   307   | strip_assums_aux (Hs, params, Const("all",_)$Abs(a,T,t)) =
   296 	strip_assums_aux (Hs, (a,T)::params, t)
   308         strip_assums_aux (Hs, (a,T)::params, t)
   297   | strip_assums_aux (Hs, params, B) = (Hs, params, B);
   309   | strip_assums_aux (Hs, params, B) = (Hs, params, B);
   298 
   310 
   299 fun strip_assums A = strip_assums_aux ([],[],A);
   311 fun strip_assums A = strip_assums_aux ([],[],A);
   300 
   312 
   301 
   313 
   303   A is the first premise of the lifted rule, and thus has the form
   315   A is the first premise of the lifted rule, and thus has the form
   304     H1 ==> ... Hk ==> B   and the pairs are (H1,B),...,(Hk,B) *)
   316     H1 ==> ... Hk ==> B   and the pairs are (H1,B),...,(Hk,B) *)
   305 fun assum_pairs A =
   317 fun assum_pairs A =
   306   let val (Hs, params, B) = strip_assums A
   318   let val (Hs, params, B) = strip_assums A
   307       val D = Unify.rlist_abs(params, B)
   319       val D = Unify.rlist_abs(params, B)
   308       fun pairrev ([],pairs) = pairs  
   320       fun pairrev ([],pairs) = pairs
   309         | pairrev (H::Hs,pairs) = 
   321         | pairrev (H::Hs,pairs) =
   310 	    pairrev(Hs, (Unify.rlist_abs(params,H), D) :: pairs)
   322             pairrev(Hs, (Unify.rlist_abs(params,H), D) :: pairs)
   311   in  pairrev (Hs,[])   (*WAS:  map pair (rev Hs)  *)
   323   in  pairrev (Hs,[])   (*WAS:  map pair (rev Hs)  *)
   312   end;
   324   end;
   313 
   325 
   314 
   326 
   315 (*Converts Frees to Vars and TFrees to TVars so that axioms can be written
   327 (*Converts Frees to Vars and TFrees to TVars so that axioms can be written