src/Provers/quasi.ML
changeset 15531 08c8dad8e399
parent 15103 79846e8792eb
child 15570 8d8c70b41bab
equal deleted inserted replaced
15530:6f43714517ee 15531:08c8dad8e399
    55 
    55 
    56   (* Additional theorem for goals of form x ~= y *)
    56   (* Additional theorem for goals of form x ~= y *)
    57   val less_imp_neq : thm (* x < y ==> x ~= y *)
    57   val less_imp_neq : thm (* x < y ==> x ~= y *)
    58 
    58 
    59   (* Analysis of premises and conclusion *)
    59   (* Analysis of premises and conclusion *)
    60   (* decomp_x (`x Rel y') should yield Some (x, Rel, y)
    60   (* decomp_x (`x Rel y') should yield SOME (x, Rel, y)
    61        where Rel is one of "<", "<=", "=" and "~=",
    61        where Rel is one of "<", "<=", "=" and "~=",
    62        other relation symbols cause an error message *)
    62        other relation symbols cause an error message *)
    63   (* decomp_trans is used by trans_tac, it may only return Rel = "<=" *)
    63   (* decomp_trans is used by trans_tac, it may only return Rel = "<=" *)
    64   val decomp_trans: Sign.sg -> term -> (term * string * term) option
    64   val decomp_trans: Sign.sg -> term -> (term * string * term) option
    65   (* decomp_quasi is used by quasi_tac *)
    65   (* decomp_quasi is used by quasi_tac *)
   125 (*                                                                          *)
   125 (*                                                                          *)
   126 (* ************************************************************************ *)
   126 (* ************************************************************************ *)
   127 
   127 
   128 fun mkasm_trans sign (t, n) =
   128 fun mkasm_trans sign (t, n) =
   129   case Less.decomp_trans sign t of
   129   case Less.decomp_trans sign t of
   130     Some (x, rel, y) => 
   130     SOME (x, rel, y) => 
   131     (case rel of
   131     (case rel of
   132      "<="  =>  [Le (x, y, Asm n)]
   132      "<="  =>  [Le (x, y, Asm n)]
   133     | _     => error ("trans_tac: unknown relation symbol ``" ^ rel ^
   133     | _     => error ("trans_tac: unknown relation symbol ``" ^ rel ^
   134                  "''returned by decomp_trans."))
   134                  "''returned by decomp_trans."))
   135   | None => [];
   135   | NONE => [];
   136   
   136   
   137 (* ************************************************************************ *)
   137 (* ************************************************************************ *)
   138 (*                                                                          *)
   138 (*                                                                          *)
   139 (* mkasm_quasi sign (t, n) : Sign.sg -> (Term.term * int) -> less           *)
   139 (* mkasm_quasi sign (t, n) : Sign.sg -> (Term.term * int) -> less           *)
   140 (*                                                                          *)
   140 (*                                                                          *)
   144 (*                                                                          *)
   144 (*                                                                          *)
   145 (* ************************************************************************ *)
   145 (* ************************************************************************ *)
   146 
   146 
   147 fun mkasm_quasi sign (t, n) =
   147 fun mkasm_quasi sign (t, n) =
   148   case Less.decomp_quasi sign t of
   148   case Less.decomp_quasi sign t of
   149     Some (x, rel, y) => (case rel of
   149     SOME (x, rel, y) => (case rel of
   150       "<"   => if (x aconv y) then raise Contr (Thm ([Asm n], Less.less_reflE)) 
   150       "<"   => if (x aconv y) then raise Contr (Thm ([Asm n], Less.less_reflE)) 
   151                else [Less (x, y, Asm n)]
   151                else [Less (x, y, Asm n)]
   152     | "<="  => [Le (x, y, Asm n)]
   152     | "<="  => [Le (x, y, Asm n)]
   153     | "="   => [Le (x, y, Thm ([Asm n], Less.eqD1)),
   153     | "="   => [Le (x, y, Thm ([Asm n], Less.eqD1)),
   154                 Le (y, x, Thm ([Asm n], Less.eqD2))]
   154                 Le (y, x, Thm ([Asm n], Less.eqD2))]
   156                   raise Contr (Thm ([(Thm ([(Thm ([], Less.le_refl)) ,(Asm n)], Less.le_neq_trans))], Less.less_reflE))
   156                   raise Contr (Thm ([(Thm ([(Thm ([], Less.le_refl)) ,(Asm n)], Less.le_neq_trans))], Less.less_reflE))
   157                else [ NotEq (x, y, Asm n),
   157                else [ NotEq (x, y, Asm n),
   158                       NotEq (y, x,Thm ( [Asm n], thm "not_sym"))] 
   158                       NotEq (y, x,Thm ( [Asm n], thm "not_sym"))] 
   159     | _     => error ("quasi_tac: unknown relation symbol ``" ^ rel ^
   159     | _     => error ("quasi_tac: unknown relation symbol ``" ^ rel ^
   160                  "''returned by decomp_quasi."))
   160                  "''returned by decomp_quasi."))
   161   | None => [];
   161   | NONE => [];
   162 
   162 
   163 
   163 
   164 (* ************************************************************************ *)
   164 (* ************************************************************************ *)
   165 (*                                                                          *)
   165 (*                                                                          *)
   166 (* mkconcl_trans sign t : Sign.sg -> Term.term -> less                      *)
   166 (* mkconcl_trans sign t : Sign.sg -> Term.term -> less                      *)
   171 (* ************************************************************************ *)
   171 (* ************************************************************************ *)
   172 
   172 
   173   
   173   
   174 fun mkconcl_trans sign t =
   174 fun mkconcl_trans sign t =
   175   case Less.decomp_trans sign t of
   175   case Less.decomp_trans sign t of
   176     Some (x, rel, y) => (case rel of
   176     SOME (x, rel, y) => (case rel of
   177      "<="  => (Le (x, y, Asm ~1), Asm 0) 
   177      "<="  => (Le (x, y, Asm ~1), Asm 0) 
   178     | _  => raise Cannot)
   178     | _  => raise Cannot)
   179   | None => raise Cannot;
   179   | NONE => raise Cannot;
   180   
   180   
   181   
   181   
   182 (* ************************************************************************ *)
   182 (* ************************************************************************ *)
   183 (*                                                                          *)
   183 (*                                                                          *)
   184 (* mkconcl_quasi sign t : Sign.sg -> Term.term -> less                      *)
   184 (* mkconcl_quasi sign t : Sign.sg -> Term.term -> less                      *)
   188 (*                                                                          *)
   188 (*                                                                          *)
   189 (* ************************************************************************ *)
   189 (* ************************************************************************ *)
   190 
   190 
   191 fun mkconcl_quasi sign t =
   191 fun mkconcl_quasi sign t =
   192   case Less.decomp_quasi sign t of
   192   case Less.decomp_quasi sign t of
   193     Some (x, rel, y) => (case rel of
   193     SOME (x, rel, y) => (case rel of
   194       "<"   => ([Less (x, y, Asm ~1)], Asm 0)
   194       "<"   => ([Less (x, y, Asm ~1)], Asm 0)
   195     | "<="  => ([Le (x, y, Asm ~1)], Asm 0)
   195     | "<="  => ([Le (x, y, Asm ~1)], Asm 0)
   196     | "~="  => ([NotEq (x,y, Asm ~1)], Asm 0)
   196     | "~="  => ([NotEq (x,y, Asm ~1)], Asm 0)
   197     | _  => raise Cannot)
   197     | _  => raise Cannot)
   198 | None => raise Cannot;
   198 | NONE => raise Cannot;
   199   
   199   
   200   
   200   
   201 (* ******************************************************************* *)
   201 (* ******************************************************************* *)
   202 (*                                                                     *)
   202 (*                                                                     *)
   203 (* mergeLess (less1,less2):  less * less -> less                       *)
   203 (* mergeLess (less1,less2):  less * less -> less                       *)
   264   | (NotEq(x,y,_)) subsumes (NotEq(x',y',_)) = x aconv x' andalso y aconv y' orelse x aconv y' andalso y aconv x'
   264   | (NotEq(x,y,_)) subsumes (NotEq(x',y',_)) = x aconv x' andalso y aconv y' orelse x aconv y' andalso y aconv x'
   265   | _ subsumes _ = false;
   265   | _ subsumes _ = false;
   266 
   266 
   267 (* ******************************************************************* *)
   267 (* ******************************************************************* *)
   268 (*                                                                     *)
   268 (*                                                                     *)
   269 (* triv_solv less1 : less ->  proof Library.option                     *)
   269 (* triv_solv less1 : less ->  proof option                     *)
   270 (*                                                                     *)
   270 (*                                                                     *)
   271 (* Solves trivial goal x <= x.                                         *)
   271 (* Solves trivial goal x <= x.                                         *)
   272 (*                                                                     *)
   272 (*                                                                     *)
   273 (* ******************************************************************* *)
   273 (* ******************************************************************* *)
   274 
   274 
   275 fun triv_solv (Le (x, x', _)) =
   275 fun triv_solv (Le (x, x', _)) =
   276     if x aconv x' then  Some (Thm ([], Less.le_refl)) 
   276     if x aconv x' then  SOME (Thm ([], Less.le_refl)) 
   277     else None
   277     else NONE
   278 |   triv_solv _ = None;
   278 |   triv_solv _ = NONE;
   279 
   279 
   280 (* ********************************************************************* *)
   280 (* ********************************************************************* *)
   281 (* Graph functions                                                       *)
   281 (* Graph functions                                                       *)
   282 (* ********************************************************************* *)
   282 (* ********************************************************************* *)
   283 
   283 
   461      in getprf Le_x_y end )
   461      in getprf Le_x_y end )
   462     else raise Cannot
   462     else raise Cannot
   463    end )
   463    end )
   464   | (Less (x,y,_))  => (
   464   | (Less (x,y,_))  => (
   465    let 
   465    let 
   466     fun findParallelNeq []  = None
   466     fun findParallelNeq []  = NONE
   467     |   findParallelNeq (e::es)  =
   467     |   findParallelNeq (e::es)  =
   468      if      (x aconv (lower e) andalso y aconv (upper e)) then Some e
   468      if      (x aconv (lower e) andalso y aconv (upper e)) then SOME e
   469      else if (y aconv (lower e) andalso x aconv (upper e)) then Some (NotEq (x,y, (Thm ([getprf e], thm "not_sym"))))
   469      else if (y aconv (lower e) andalso x aconv (upper e)) then SOME (NotEq (x,y, (Thm ([getprf e], thm "not_sym"))))
   470      else findParallelNeq es ;  
   470      else findParallelNeq es ;  
   471    in
   471    in
   472    (* test if there is a edge x ~= y respectivly  y ~= x and     *)
   472    (* test if there is a edge x ~= y respectivly  y ~= x and     *)
   473    (* if it possible to find a path x <= y in leG, thus we can conclude x < y *)
   473    (* if it possible to find a path x <= y in leG, thus we can conclude x < y *)
   474     (case findParallelNeq neqE of (Some e) => 
   474     (case findParallelNeq neqE of (SOME e) => 
   475       let 
   475       let 
   476        val (xyLeFound,xyLePath) = findPath x y leG 
   476        val (xyLeFound,xyLePath) = findPath x y leG 
   477       in
   477       in
   478        if xyLeFound then (
   478        if xyLeFound then (
   479         let 
   479         let 
   485     | _ => raise Cannot)    
   485     | _ => raise Cannot)    
   486    end )
   486    end )
   487  | (NotEq (x,y,_)) => 
   487  | (NotEq (x,y,_)) => 
   488   (* First check if a single premiss is sufficient *)
   488   (* First check if a single premiss is sufficient *)
   489   (case (Library.find_first (fn fact => fact subsumes subgoal) neqE, subgoal) of
   489   (case (Library.find_first (fn fact => fact subsumes subgoal) neqE, subgoal) of
   490     (Some (NotEq (x, y, p)), NotEq (x', y', _)) =>
   490     (SOME (NotEq (x, y, p)), NotEq (x', y', _)) =>
   491       if  (x aconv x' andalso y aconv y') then p 
   491       if  (x aconv x' andalso y aconv y') then p 
   492       else Thm ([p], thm "not_sym")
   492       else Thm ([p], thm "not_sym")
   493     | _  => raise Cannot 
   493     | _  => raise Cannot 
   494   )
   494   )
   495 
   495 
   538   val (leG, neqE) = mkQuasiGraph asms
   538   val (leG, neqE) = mkQuasiGraph asms
   539  in
   539  in
   540    let 
   540    let 
   541    val (subgoals, prf) = mkconcl_quasi sign concl
   541    val (subgoals, prf) = mkconcl_quasi sign concl
   542    fun solve facts less =
   542    fun solve facts less =
   543        (case triv_solv less of None => findQuasiProof (leG, neqE) less
   543        (case triv_solv less of NONE => findQuasiProof (leG, neqE) less
   544        | Some prf => prf )
   544        | SOME prf => prf )
   545   in   map (solve asms) subgoals end
   545   in   map (solve asms) subgoals end
   546  end;
   546  end;
   547 
   547 
   548 (* ************************************************************************ *) 
   548 (* ************************************************************************ *) 
   549 (*                                                                          *) 
   549 (*                                                                          *)