lh-l4v/lib/Monads/Strengthen_Demo.thy

132 lines
4.6 KiB
Plaintext
Raw Normal View History

2017-12-19 05:13:59 +00:00
(*
2020-03-09 06:18:30 +00:00
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
2017-12-19 05:13:59 +00:00
*
2020-03-09 06:18:30 +00:00
* SPDX-License-Identifier: BSD-2-Clause
2017-12-19 05:13:59 +00:00
*)
theory Strengthen_Demo
imports "Strengthen"
begin
2019-06-05 10:18:48 +00:00
text \<open>Here's a complicated predicate transformer. You don't need
to understand this, it just makes it easy to set up some complicated
2019-06-05 10:18:48 +00:00
example goals below.\<close>
2017-12-19 05:13:59 +00:00
definition
"predt f g h P x y = (\<exists>x'. (\<exists>y' \<in> f y. x' \<in> g y' ` h y) \<and> P x x')"
2019-06-05 10:18:48 +00:00
text \<open>Strengthen performs the same kinds of steps as
intro/elim rules, but it can perform them within complex
conclusions. Here's an example where we replace Q with P
2019-06-05 10:18:48 +00:00
(strengthening the goal) deep within some quantifiers.\<close>
2017-12-19 05:13:59 +00:00
lemma predt_double_mono:
assumes PQ: "\<And>x y. P x y \<longrightarrow> Q x y"
2017-12-19 05:13:59 +00:00
assumes P: "predt f g h (predt f g h' P) x y"
shows "predt f g h (predt f g h' Q) x y"
using P
apply (simp add: predt_def)
apply (strengthen PQ)
2017-12-19 05:13:59 +00:00
apply assumption
done
2019-06-05 10:18:48 +00:00
text \<open>Here's a more conventional monotonicity proof.
Once the clarsimp has finished, the goal becomes a bit
difficult to prove. Let's use some fancy strengthen
features to address this. The rest of this demo will
explain what the attribute and fancy features are doing,
2019-06-05 10:18:48 +00:00
and thus how this proof works.\<close>
2017-12-19 05:13:59 +00:00
lemma predt_double_mono2:
assumes PQ: "\<And>x y. P x y \<longrightarrow> Q x y"
2017-12-19 05:13:59 +00:00
assumes P: "predt f g h (predt f g' h P) x y"
shows "predt f g h (predt f g' h Q) x y"
using P
apply (clarsimp simp: predt_def)
apply (strengthen bexI[mk_strg I _ A])
apply (strengthen image_eqI[mk_strg I _ A])
apply simp
apply (strengthen bexI[mk_strg I _ O], assumption)
apply (strengthen image_eqI[mk_strg I _ E])
apply simp
apply (simp add: PQ)
2017-12-19 05:13:59 +00:00
done
2019-06-05 10:18:48 +00:00
text \<open>The @{attribute mk_strg} controls the way that
2017-12-19 05:13:59 +00:00
strengthen applies a rule. By default, strengthen will
use a rule as an introduction rule, trying to replace
the rule's conclusion with its premises.
Once the @{attribute mk_strg} attribute has applied, the
rule is formatted showing how strengthen will try to
transform components of a goal. The syntax of the
second theorem is reversed, showing that strengthen will
attempt to replace instances of the subset predicate
with instances of the proper subset predicate.
2019-06-05 10:18:48 +00:00
\<close>
2017-12-19 05:13:59 +00:00
thm psubset_imp_subset psubset_imp_subset[mk_strg]
2019-06-05 10:18:48 +00:00
text \<open>Rules can have any number of premises, or none,
and still be used as strengthen rules.\<close>
2017-12-19 05:13:59 +00:00
thm subset_UNIV subset_UNIV[mk_strg]
equalityI equalityI[mk_strg]
2019-06-05 10:18:48 +00:00
text \<open>Rules which would introduce schematics are
adjusted by @{attribute mk_strg} to introduce quantifiers
instead. The argument I to mk_strg prevents this step.
2019-06-05 10:18:48 +00:00
\<close>
2017-12-19 05:13:59 +00:00
thm subsetD subsetD[mk_strg I] subsetD[mk_strg]
2019-06-05 10:18:48 +00:00
text \<open>The first argument to mk_strg controls the way
2017-12-19 05:13:59 +00:00
the rule will be applied.
I: use rule in introduction style, matching its conclusion.
D: use rule in destruction (forward) style, matching its first premise.
I': like I, replace new schematics with existential quantifiers.
D': like D, replace new schematics with universal quantifiers.
The default is I'.
2019-06-05 10:18:48 +00:00
\<close>
2017-12-19 05:13:59 +00:00
thm subsetD subsetD[mk_strg I] subsetD[mk_strg I']
subsetD[mk_strg D] subsetD[mk_strg D']
2019-06-05 10:18:48 +00:00
text \<open>Note that I and D rules will be applicable at different
sites.\<close>
2017-12-19 05:13:59 +00:00
lemma
assumes PQ: "P \<Longrightarrow> Q"
shows "{x. Suc 0 < x \<and> P} \<subseteq> {x. Suc 0 < x \<and> Q}"
(* adjust Q into P on rhs *)
apply (strengthen PQ[mk_strg I])
(* adjust P into Q on lhs *)
apply (strengthen PQ[mk_strg D])
(* oops, overdid it *)
oops
2019-06-05 10:18:48 +00:00
text \<open>Subsequent arguments to mk_strg capture premises for
2017-12-19 05:13:59 +00:00
special treatment. The 'A' argument (synonym 'E') specifies that
a premise should be solved by assumption. Our fancy proof above
used a strengthen rule bexI[mk_strg I _ A], which tells strengthen
to do approximately the same thing as
2017-12-19 05:13:59 +00:00
\<open>apply (rule bexI) prefer 2 apply assumption\<close>
This is a useful way to apply a rule, picking the premise which
will cause unknowns to be instantiated correctly.
2019-06-05 10:18:48 +00:00
\<close>
2017-12-19 05:13:59 +00:00
thm eq_mem_trans eq_mem_trans[mk_strg I _ _] eq_mem_trans[mk_strg I A _]
eq_mem_trans[mk_strg I _ A] eq_mem_trans[mk_strg I A A]
2019-06-05 10:18:48 +00:00
text \<open>The 'O' argument ("obligation") picks out premises of
2017-12-19 05:13:59 +00:00
a rule for immediate attention as new subgoals.
The step
\<open>apply (strengthen bexI[mk_strg I _ O], assumption)\<close>
in our proof above had the same effect as strengthening with
@{thm bexI[mk_strg I _ A]}.
This option suits special cases where a particular premise is best
handled by a specialised method.
2019-06-05 10:18:48 +00:00
\<close>
2017-12-19 05:13:59 +00:00
thm eq_mem_trans eq_mem_trans[mk_strg I _ _] eq_mem_trans[mk_strg I O _]
eq_mem_trans[mk_strg I _ O] eq_mem_trans[mk_strg I O O]
end