问题
I have a string a
and on comparison with string b
, if equals has an string c
, else has string x
. I know in the hypothesis that fun x <= fun c
. How do I prove this below statement? fun
is some function which takes in string
and returns nat
.
fun (if a == b then c else x) <= S (fun c)
The logic seems obvious but I am unable to split the if statements in coq. Any help would be appreciated.
Thanks!
回答1:
If you can write an if-then-else statement, it means that the test expression a == b
is in a type with two constructors (like bool
) or (sumbool
). I will first assume the type is bool
. In that case, the best approach during a proof is to enter the following command.
case_eq (a == b); intros hyp_ab.
This will generate two goals. In the first one, you will have an hypothesis
hyp_ab : a == b = true
that asserts that the test succeeds and the goal conclusion has the following shape (the if-then-else is replaced by the then branch):
fun c <= S (fun c)
In the second goal, you will have an hypothesis
hyp_ab : a == b = false
and the goal conclusion has the following shape (the if-then-else is replaced by the else branch).
fun x <= S (fun c)
You should be able to carry on from there.
On the other hand, the String
library from Coq has a function string_dec
with return type {a = b}+{a <> b}
. If your notation a == b
is a pretty notation for string_dec a b
, it is better to use the following tactic:
destruct (a == b) as [hyp_ab | hyp_ab].
The behavior will be quite close to what I described above, only easier to use.
Intuitively, when you reason on an if-then-else statement, you use a command like case_eq
, destruct
, or case
that leads you to studying separately the two executions paths, remember in an hypothesis why you took each of these executions paths.
回答2:
Let me complement Yves answer pointing out to a general "view" pattern that works well in many situations were case analysis is needed. I will use the built-in support in math-comp but the technique is not specific to it.
Let's assume your initial goal:
From mathcomp Require Import all_ssreflect.
Variables (T : eqType) (a b : T).
Lemma u : (if a == b then 0 else 1) = 2.
Proof.
now, you could use case_eq
+ simpl
to arrive to next step; however, you can also match using more specialized "view" lemmas. For example, you could use ifP
:
ifP : forall (A : Type) (b : bool) (vT vF : A),
if_spec b vT vF (b = false) b (if b then vT else vF)
where if_spec
is:
Inductive if_spec (A : Type) (b : bool) (vT vF : A) (not_b : Prop) : bool -> A -> Set :=
IfSpecTrue : b -> if_spec b vT vF not_b true vT
| IfSpecFalse : not_b -> if_spec b vT vF not_b false vF
That looks a bit confusing, the important bit is the parameters to the type family bool -> A -> Set
. The first exercise is "prove the ifP
lemma!".
Indeed, if we use ifP
in our proof, we get:
case: ifP.
Goal 1: (a == b) = true -> 0 = 2
Goal 2: (a == b) = false -> 1 = 2
Note that we didn't have to specify anything! Indeed, lemmas of the form { A
} + { B }
are just special cases of this view pattern. This trick works in many other situations, for example, you can also use eqP
, which has a spec relating the boolean equality with the propositional one. If you do:
case: eqP.
you'll get:
Goal 1: a = b -> 0 = 2
Goal 2: a <> b -> 1 = 2
which is very convenient. In fact, eqP
is basically a generic version of the type_dec
principle.
来源:https://stackoverflow.com/questions/46434503/coq-how-to-prove-if-statements-involving-strings