简体   繁体   中英

Coq: How to prove if statements involving strings?

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!

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.

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 ab , 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM