tactics の選択
∀,∃を消去するには,仮定と結論を分離し,十分条件などに帰着させる方法が一般的です.
# g `(!x. &0<x ==> a<x )==> a<= &0` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `(!x. &0 < x ==> a < x) ==> a <= &0` # e( STRIP_TAC );; val it : goalstack = 1 subgoal (1 total) 0 [`!x. &0 < x ==> a < x`] `a <= &0` # e( POP_ASSUM (MP_TAC o (SPEC `a / &2`) ) );; val it : goalstack = 1 subgoal (1 total) `(&0 < a / &2 ==> a < a / &2) ==> a <= &0` # e( ARITH_TAC );; val it : goalstack = No subgoals # g `a<= &0==>(!x. &0<x ==> a<x)` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `a <= &0 ==> (!x. &0 < x ==> a < x)` # e( REPEAT STRIP_TAC );; val it : goalstack = 1 subgoal (1 total) 0 [`a <= &0`] 1 [`&0 < x`] `a < x` # e( REPEAT (POP_ASSUM MP_TAC));; val it : goalstack = 1 subgoal (1 total) `a <= &0 ==> &0 < x ==> a < x` # e( ARITH_TAC );; val it : goalstack = No subgoals # g `(?x. &0<x /\ x<a) ==> &0<a` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `(?x. &0 < x /\ x < a) ==> &0 < a` # e( REPEAT STRIP_TAC );; val it : goalstack = 1 subgoal (1 total) 0 [`&0 < x`] 1 [`x < a`] `&0 < a` # e( REPEAT (POP_ASSUM MP_TAC));; val it : goalstack = 1 subgoal (1 total) `&0 < x ==> x < a ==> &0 < a` # e( ARITH_TAC );; val it : goalstack = No subgoals # g `&0<a ==> (?x. &0<x /\ x<a)` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `&0 < a ==> (?x. &0 < x /\ x < a)` # e( STRIP_TAC );; val it : goalstack = 1 subgoal (1 total) 0 [`&0 < a`] `?x. &0 < x /\ x < a` # e( EXISTS_TAC `a / &2`);; val it : goalstack = 1 subgoal (1 total) 0 [`&0 < a`] `&0 < a / &2 /\ a / &2 < a` # e( POP_ASSUM MP_TAC );; val it : goalstack = 1 subgoal (1 total) `&0 < a ==> &0 < a / &2 /\ a / &2 < a` # e( ARITH_TAC );; val it : goalstack = No subgoals
一方,必要に応じてA,B|-CをA|-B⇒Cに UNDISCH_TAC して結論B⇒Cを
# search[name"LEFT_IMP"];; val it : (string * thm) list = [("LEFT_IMP_FORALL_THM", |- !P Q. (!x. P x) ==> Q <=> (?x. P x ==> Q)); ("LEFT_IMP_EXISTS_THM", |- !P Q. (?x. P x) ==> Q <=> (!x. P x ==> Q))] # search[name"RIGHT_IMP"];; val it : (string * thm) list = [("RIGHT_IMP_FORALL_THM", |- !P Q. P ==> (!x. Q x) <=> (!x. P ==> Q x)); ("RIGHT_IMP_EXISTS_THM", |- !P Q. P ==> (?x. Q x) <=> (?x. P ==> Q x))]
を参照して REWRITE_TAC し,結論全体の量化に書き換えれば,GEN_TAC,EXISTS_TAC で処理できます.
# g `(!x. &0<x ==> a<x )==> a<= &0` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `(!x. &0 < x ==> a < x) ==> a <= &0` # e( REWRITE_TAC [LEFT_IMP_FORALL_THM] );; val it : goalstack = 1 subgoal (1 total) `?x. (&0 < x ==> a < x) ==> a <= &0` # e( EXISTS_TAC `a / &2`);; val it : goalstack = 1 subgoal (1 total) `(&0 < a / &2 ==> a < a / &2) ==> a <= &0` # e( ARITH_TAC );; val it : goalstack = No subgoals # g `a<= &0==>(!x. &0<x ==> a<x)` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `a <= &0 ==> (!x. &0 < x ==> a < x)` # e( REWRITE_TAC [RIGHT_IMP_FORALL_THM] );; val it : goalstack = 1 subgoal (1 total) `!x. a <= &0 ==> &0 < x ==> a < x` # e( ARITH_TAC );; val it : goalstack = No subgoals # g `(?x. &0<x /\ x<a) ==> &0<a` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `(?x. &0 < x /\ x < a) ==> &0 < a` # e( REWRITE_TAC [LEFT_IMP_EXISTS_THM] );; val it : goalstack = 1 subgoal (1 total) `!x. &0 < x /\ x < a ==> &0 < a` # e( GEN_TAC );; val it : goalstack = 1 subgoal (1 total) `&0 < x /\ x < a ==> &0 < a` # e( ARITH_TAC );; val it : goalstack = No subgoals # g `&0<a ==> (?x. &0<x /\ x<a)` ;; Warning: Free variables in goal: a val it : goalstack = 1 subgoal (1 total) `&0 < a ==> (?x. &0 < x /\ x < a)` # e( REWRITE_TAC [RIGHT_IMP_EXISTS_THM] );; val it : goalstack = 1 subgoal (1 total) `?x. &0 < a ==> &0 < x /\ x < a` # e( EXISTS_TAC `a / &2`);; val it : goalstack = 1 subgoal (1 total) `&0 < a ==> &0 < a / &2 /\ a / &2 < a` # e( ARITH_TAC );; val it : goalstack = No subgoals