Tactician
HOL Light の g コマンドによる証明と prove コマンドによる証明との変換ツール Tactician のご紹介です.
http://www.proof-technologies.com/tactician/index.html
使い方は簡単で,HOL Light のディレクトリに
http://www.proof-technologies.com/tactician/hollight_tactician-2.2.tgz
を解凍して
#use "Tactician/main.ml";;
とロードして
promote_ml_values ();;
と初期化,何か証明した後にtop_thmの証明を表示するには
print_executed_proof ();;
それをTHENを用いない形に変換したものを表示するには
print_flat_proof ();;
それを1つのtacticにしたもの(つまり,proveタイプ)を表示するには
print_thenl_proof ();;
更にALL_TACを用いてTHENLのネストを避けたものを表示するには
print_packaged_proof ();;
とするだけです(なお,これをロードすると search が使えません).
例えば...
g `!a b s t. &0 <= a ==> &0 <= b ==> &0 <= s ==> &0 <= t ==> s + t = &1 ==> !n. (s * a + t * b) pow n <= s * a pow n + t * b pow n` ;; e( REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN INDUCT_TAC );; e( SIMP_TAC [pow] THEN ASM_REAL_ARITH_TAC );; e( SIMP_TAC [pow] );; e( MATCH_MP_TAC REAL_LE_TRANS );; e( EXISTS_TAC `(s * a + t * b) * (s * a pow n + t * b pow n)` );; e( CONJ_TAC );; e( ASM_SIMP_TAC [REAL_LE_ADD;REAL_LE_MUL;REAL_LE_LMUL] );; e( ONCE_REWRITE_TAC [GSYM REAL_SUB_LE] );; e( SIMP_TAC [UNDISCH(REAL_FIELD`s + t = &1 ==> (s * a * x + t * b * y) - (s * a + t * b) * (s * x + t * y) = (s * t) * (a - b) * (x - y)`)] );; e( MATCH_MP_TAC REAL_LE_MUL );; e( CONJ_TAC );; e( ASM_SIMP_TAC [REAL_LE_MUL] );; e( DISJ_CASES_THEN ASSUME_TAC (SPECL[`a:real`;`b:real`]REAL_LE_TOTAL) );; e( ONCE_REWRITE_TAC [GSYM REAL_NEG_MUL2] THEN SIMP_TAC [REAL_NEG_SUB] );; e( ASM_SIMP_TAC [REAL_LE_MUL;REAL_SUB_LE;POW_LE] );; e( ASM_SIMP_TAC [REAL_LE_MUL;REAL_SUB_LE;POW_LE] );;
に対しては
# print_executed_proof ();; g `!a b s t. &0 <= a ==> &0 <= b ==> &0 <= s ==> &0 <= t ==> s + t = &1 ==> !n. (s * a + t * b) pow n <= s * a pow n + t * b pow n`;; e (REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN INDUCT_TAC);; (* *** Subgoal 1 *** *) e (SIMP_TAC [pow] THEN ASM_REAL_ARITH_TAC);; (* *** Subgoal 2 *** *) e (SIMP_TAC [pow]);; e (MATCH_MP_TAC REAL_LE_TRANS);; e (EXISTS_TAC `(s * a + t * b) * (s * a pow n + t * b pow n)`);; e (CONJ_TAC);; (* *** Subgoal 2.1 *** *) e (ASM_SIMP_TAC [REAL_LE_ADD; REAL_LE_MUL; REAL_LE_LMUL]);; (* *** Subgoal 2.2 *** *) e (ONCE_REWRITE_TAC [GSYM REAL_SUB_LE]);; e (SIMP_TAC [UNDISCH (REAL_FIELD `s + t = &1 ==> (s * a * x + t * b * y) - (s * a + t * b) * (s * x + t * y) = (s * t) * (a - b) * (x - y)`)]);; e (MATCH_MP_TAC REAL_LE_MUL);; e (CONJ_TAC);; (* *** Subgoal 2.2.1 *** *) e (ASM_SIMP_TAC [REAL_LE_MUL]);; (* *** Subgoal 2.2.2 *** *) e (DISJ_CASES_THEN ASSUME_TAC (SPECL [`a:real`; `b:real`] REAL_LE_TOTAL));; (* *** Subgoal 2.2.2.1 *** *) e (ONCE_REWRITE_TAC [GSYM REAL_NEG_MUL2] THEN SIMP_TAC [REAL_NEG_SUB]);; e (ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]);; (* *** Subgoal 2.2.2.2 *** *) e (ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]);; val it : unit = () # print_flat_proof ();; g `!a b s t. &0 <= a ==> &0 <= b ==> &0 <= s ==> &0 <= t ==> s + t = &1 ==> !n. (s * a + t * b) pow n <= s * a pow n + t * b pow n`;; e (REPEAT GEN_TAC);; e (REPEAT DISCH_TAC);; e (INDUCT_TAC);; (* *** Subgoal 1 *** *) e (SIMP_TAC [pow]);; e (ASM_REAL_ARITH_TAC);; (* *** Subgoal 2 *** *) e (SIMP_TAC [pow]);; e (MATCH_MP_TAC REAL_LE_TRANS);; e (EXISTS_TAC `(s * a + t * b) * (s * a pow n + t * b pow n)`);; e (CONJ_TAC);; (* *** Subgoal 2.1 *** *) e (ASM_SIMP_TAC [REAL_LE_ADD; REAL_LE_MUL; REAL_LE_LMUL]);; (* *** Subgoal 2.2 *** *) e (ONCE_REWRITE_TAC [GSYM REAL_SUB_LE]);; e (SIMP_TAC [UNDISCH (REAL_FIELD `s + t = &1 ==> (s * a * x + t * b * y) - (s * a + t * b) * (s * x + t * y) = (s * t) * (a - b) * (x - y)`)]);; e (MATCH_MP_TAC REAL_LE_MUL);; e (CONJ_TAC);; (* *** Subgoal 2.2.1 *** *) e (ASM_SIMP_TAC [REAL_LE_MUL]);; (* *** Subgoal 2.2.2 *** *) e (DISJ_CASES_THEN ASSUME_TAC (SPECL [`a:real`; `b:real`] REAL_LE_TOTAL));; (* *** Subgoal 2.2.2.1 *** *) e (ONCE_REWRITE_TAC [GSYM REAL_NEG_MUL2]);; e (SIMP_TAC [REAL_NEG_SUB]);; e (ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]);; (* *** Subgoal 2.2.2.2 *** *) e (ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]);; val it : unit = () # print_thenl_proof ();; prove (`!a b s t. &0 <= a ==> &0 <= b ==> &0 <= s ==> &0 <= t ==> s + t = &1 ==> !n. (s * a + t * b) pow n <= s * a pow n + t * b pow n`, REPEAT GEN_TAC THEN (REPEAT DISCH_TAC THEN (INDUCT_TAC THENL [SIMP_TAC [pow] THEN ASM_REAL_ARITH_TAC; SIMP_TAC [pow] THEN (MATCH_MP_TAC REAL_LE_TRANS THEN (EXISTS_TAC `(s * a + t * b) * (s * a pow n + t * b pow n)` THEN (CONJ_TAC THENL [ASM_SIMP_TAC [REAL_LE_ADD; REAL_LE_MUL; REAL_LE_LMUL]; ONCE_REWRITE_TAC [GSYM REAL_SUB_LE] THEN (SIMP_TAC [UNDISCH (REAL_FIELD `s + t = &1 ==> (s * a * x + t * b * y) - (s * a + t * b) * (s * x + t * y) = (s * t) * (a - b) * (x - y)`)] THEN (MATCH_MP_TAC REAL_LE_MUL THEN (CONJ_TAC THENL [ASM_SIMP_TAC [REAL_LE_MUL]; DISJ_CASES_THEN ASSUME_TAC (SPECL [`a:real`; `b:real`] REAL_LE_TOTAL) THENL [ONCE_REWRITE_TAC [GSYM REAL_NEG_MUL2] THEN (SIMP_TAC [REAL_NEG_SUB] THEN ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]); ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]]])))])))])));; val it : unit = () # print_packaged_proof ();; prove (`!a b s t. &0 <= a ==> &0 <= b ==> &0 <= s ==> &0 <= t ==> s + t = &1 ==> !n. (s * a + t * b) pow n <= s * a pow n + t * b pow n`, REPEAT GEN_TAC THEN REPEAT DISCH_TAC THEN INDUCT_TAC THEN SIMP_TAC [pow] THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `(s * a + t * b) * (s * a pow n + t * b pow n)` THEN CONJ_TAC THENL [ASM_SIMP_TAC [REAL_LE_ADD; REAL_LE_MUL; REAL_LE_LMUL]; ALL_TAC] THEN ONCE_REWRITE_TAC [GSYM REAL_SUB_LE] THEN SIMP_TAC [UNDISCH (REAL_FIELD `s + t = &1 ==> (s * a * x + t * b * y) - (s * a + t * b) * (s * x + t * y) = (s * t) * (a - b) * (x - y)`)] THEN MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL [ASM_SIMP_TAC [REAL_LE_MUL]; ALL_TAC] THEN DISJ_CASES_THEN ASSUME_TAC (SPECL [`a:real`; `b:real`] REAL_LE_TOTAL) THENL [ONCE_REWRITE_TAC [GSYM REAL_NEG_MUL2] THEN SIMP_TAC [REAL_NEG_SUB]; ALL_TAC] THEN ASM_SIMP_TAC [REAL_LE_MUL; REAL_SUB_LE; POW_LE]);; val it : unit = ()
となります.
実のところ g タイプから prove タイプへの変換だけなら難しくなく,私もエディターのマクロで実装していますが,このツールは証明の構造を分析しており,非常に柔軟な処理が可能となっています.なお,print_thenl_proof は何故か上記のサイトで紹介されていません.また,より簡潔にした print_optimal_proof は http://proofgeneral.inf.ed.ac.uk/releases/ProofGeneral-4.2/hol-light/TacticRecording/INSTRUCTIONS に生き残っています.