Coq compiler error: Impossible to unify "4" with "8". with VST make - verifiable-c

I have two questions:
First, if I write a C program with inline assembly, can I then verify the whole C program in VST? Or is it only pure C programs that can be verified?
Second, I tried to install the latest VST and Compcert as stated on http://vst.cs.princeton.edu/ on Ubuntu 12.04 but during some point an error occured during transformation of .v files to .vo files with a message of the form: 'Impossible to unify "2" with "8"'. I think this error occured during the make of compcert, but I'm not certain.
Then I tried to install VST on Ubuntu 14.04 using this guide: 'http://ninj4.net/2014/05/16/hello-vst-hello-verifiable-c.html'. I installed the same versions of Coq, OCaml and Menhir as the in the guide. Later when I ran make in the vst directory I got a similar problem as above. The following is what I got as output:
Makefile:289: .depend: No such file or directory
coqdep -slash -I msl -as msl -I sepcomp -as sepcomp'...
...
...
'COQC floyd/forward_lemmas.v
COQC floyd/array_lemmas.v
COQC floyd/data_at_lemmas.v
COQC floyd/globals_lemmas.v
File "/home/jhagl/verifiable-c/vst/floyd/data_at_lemmas.v", line 429, characters 49-60:
Error: Impossible to unify "4" with "8".
make: ** * [floyd/data_at_lemmas.vo] Error 1
make: *** Waiting for unfinished jobs....
The following is a snippet from data_at_lemmas.v of the lemma that fails (I have marked line 429):
Lemma align_chunk_alignof: forall t ch, access_mode t = By_value ch -> legal_alignas_type t = true -> alignof t = Memdata.align_chunk ch.
Proof.
Transparent alignof.
intros.
destruct t; inversion H.
- unfold legal_alignas_type in H0.
simpl in H0.
destruct i, s; inversion H2; simpl;
destruct (attr_alignas a); try inversion H0; reflexivity.
- unfold legal_alignas_type in H0.
simpl in H0.
destruct s; inversion H2; simpl;
destruct (attr_alignas a); try inversion H0; admit. (* Tlong uncompatible problem *)
- unfold legal_alignas_type in H0.
simpl in H0.
destruct f; inversion H2; simpl;
(\* Line 429 *) destruct (attr_alignas a); try inversion H0; reflexivity.
- unfold legal_alignas_type in H0.
simpl in H0.
inversion H2; simpl;
destruct (attr_alignas a); try inversion H0; reflexivity.
Opaque alignof.
Qed.
As an aside, i tried to run the following command in bash:
./configure -toolprefix arm-none-eabi- arm-eabi -no-runtime-lib
and got this error message:
./configure: 65: shift: can't shift that many
But ./configure -toolprefix arm-none-eabi- arm-eabi worked. This was not a problem since I changed Makefile.config.
Any suggestions for how to fix this? I don't know Coq yet (I have just read a guide "Coq in a Hurry", and have used HOL though). I have other fresh systems on which I can try to install VST on (if that is necessary), even though I have tried twice already.
Thanks in advance.

First: inline assembly. The recommended way to do inline assembly is to model it as a CompCert "inlineable external function call"; then you give a Verifiable C function specification for the function. CompCert will generate inline assembly, not a real function call. This is an advanced technique, I wouldn't suggest starting with it.
Second: build error. Was it VST 1.5 from the vst.cs.princeton.edu website? Was it an "internal compcert" (cd compcert; ./make), or an "external compcert"? If external,
do you have the right version of CompCert (2.1)?
Third, regarding "I don't know Coq yet." Verifiable C will be hard to use if you
have no Coq experience. I recommend Pierce et al's Software Foundations to learn Coq.

I had the same problem when installing VST 1.5 with CompCert 2.4. As a workaround I placed admit tactics at the problematic places. E. g. your lemma now looks like (pay attantion to the comment (*!!! ... *)):
Lemma align_chunk_alignof: forall t ch, access_mode t = By_value ch -> legal_alignas_type t = true -> alignof t = Memdata.align_chunk ch.
Proof.
Transparent alignof.
intros.
destruct t; inversion H.
- unfold legal_alignas_type in H0.
simpl in H0.
destruct i, s; inversion H2; simpl;
destruct (attr_alignas a); try inversion H0; reflexivity.
- unfold legal_alignas_type in H0.
simpl in H0.
destruct s; inversion H2; simpl;
destruct (attr_alignas a); try inversion H0; admit. (* Tlong uncompatible problem *)
- unfold legal_alignas_type in H0.
simpl in H0.
destruct f; inversion H2; simpl.
destruct (attr_alignas a). try inversion H0; reflexivity.
reflexivity.
destruct (attr_alignas a). (* try inversion H0. *)
inversion H0.
admit. (* !!! that didn't work out. I can't proove 4=8 *)
- unfold legal_alignas_type in H0.
simpl in H0.
inversion H2; simpl;
destruct (attr_alignas a); try inversion H0; reflexivity.
Opaque alignof.
Qed.

Based on your comment (that it was VST 1.4), one possibility is that you have an incompatible (too new) version of Coq. I suggest you might try VST 1.5, for two reasons:
VST 1.5 is compatible with more recent versions of Coq
(and with CompCert 2.4, by the way)
New in VST 1.5, the Makefile checks explicitly which version of Coq you have,
and gives a clear error message if you have an incompatible version.
So, there's no guarantee that this will solve the problem, but it might be a good start.

Related

How to prove logic equivalence in Coq?

I want to prove the following logic equivalence in Coq.
(p->q)->(~q->~p)
Here is what I attempted. How can I fix this?
Lemma work : (forall p q : Prop, (p->q)->(~q->~p)).
Proof.
intros p q.
intros p_implies_q not_q_implies_not_p.
refine (not_q_implies_not_p).
refine (p_implies_q).
Qed.
Two things that might help.
First, in your second intros, the second hypothesis is not not_q_implies_not_p, but rather, simply not_q. This is because the goal is (after intros p_implies_q) ~q -> ~p, so another invocation of intros only brings in the hypothesis of this goal: ~q, and leaves ~p as the new goal.
Second, remember that ~p simply means p -> False, which allows us to introduce another hypothesis from the goal of ~p. This also means that you can use a premise like ~p to prove False, assuming you know that p is true.
So your proof should start out something like
Lemma work : (forall p q : Prop, (p->q)->(~q->~p)).
Proof.
intros p q.
intros p_implies_q not_q.
intros p_true.

How to test for falsity in implications?

In a complex lemma which is basically an implication one may mistakenly form an antecedent that turns out to be falsity. Is there any support in Isabelle for avoiding this situation?
You can use quickcheck for that. In a proof where you suspect your antecedents don't hold, locally try to prove False:
lemma "P ∧ ¬ P ⟹ foobar"
proof -
have False
quickcheck
In case it's an antecedent that you need frequently, you can also do it like this:
context
assumes "P ∧ ¬ P"
begin
lemma False
nitpick
quickcheck
end
The context command opens a new unnamed context with local hypotheses. When you exit the context, the assumption gets added to all theorems. There, you can also use nitpick to find problems.

Inequality reasoning in Isabelle

I have the following simple proof:
lemma
fixes a b n :: nat
assumes a: "a > n" "b > n"
shows "a*b > n*n"
proof -
from assms show "a*b > n*n" by(simp_all add: field_simps) ERROR
qed
In the proof state, Isabelle says:
Successful attempt to solve goal by exported rule:
n * n < a * b
But then:
Failed to apply initial proof method⌂: using this:
n < a
n < b goal (1 subgoal):
1. n * n < a * b
What is the problem?. Actually im interested in the actual single steps to do the proff, so i tought isabelle could show me the way.
field_simps is good for rearranging terms, but not so good for this kind of reasoning. When you want to prove something like this, you typically need a good rule for it; in this case something about (strict) inequalities and multiplication.
If you have something that looks trivial but you don't know how to prove it exactly and/or you don't know what the relevant facts are called in Isabelle, sledgehammer is often helpful:
from assms show "a*b > n*n"
sledgehammer
> Sledgehammering...
> Proof found...
> "cvc4": Try this:
> by (metis (no_types, lifting) dual_order.strict_trans gr_implies_not_zero
> linorder_neqE_nat mult.commute nat_0_less_mult_iff
> nat_mult_less_cancel1) (796 ms)
The problem with proofs found by sledgehammer is that, as you can see, they are frequently lengthy, slow, and not very illuminating. On the maintenance side of things, they are also somewhat fragile w.r.t. changes in the background theory. Still, it's a good place to start and you can often read relevant facts for your proof from the sledgehammer proofs (e.g. nat_mult_less_cancel1 here).
Another way to find relevant facts is the find_theorems command or, equivalently, the Query panel in the Isabelle/jEdit IDE. If you do
find_theorems "_ * _ > _ * _"
or, equivalently, enter _ * _ > _ * _ into the Query panel, you get a lot of output to read through, but some relevant facts hide at the end of that output, e.g. mult_strict_mono':
thm mult_strict_mono'
> ?a < ?b ⟹ ?c < ?d ⟹ 0 ≤ ?a ⟹ 0 ≤ ?c ⟹ ?a * ?c < ?b * ?d
Your proof then looks like this:
from assms show "a*b > n*n"
by (rule mult_strict_mono') simp_all
The simp_all just discharges the remaining proof obligations n ≥ 0.
Oh and by the way: The fact that you get a Successful attempt to solve goal but then an error message is a consequence of the non-linear nature of interactive Isabelle: When you write a by, the proof attempt is forked to the background and the processing of the proof document afterwards proceeds as if the proof had succeeded. This is in order to allow for parallelisation and to allow users to continue working on documents even if some proofs are broken.
The Successful attempt message comes from the part of Isabelle that is invoked after a show, and that part sees a successful (but still pending) proof of a*b > n*n. However, you then immediately get an error message from the by (simp_all …) saying that the proof method failed. In batch processing mode, failures such as this are more drastic (and more obvious).

Isabelle: prove that this set notation of a matrice results in a finite set

I am using the development version of Isabelle from the repository. I hope it is a good decicion. Sledgehammer is again greatly improved! The isabelle developpers are really great! The reason for the dev version is that Isabelle2013-2 was crashing too often.
How can I prove this lemma:
lemma finite_f_A:
fixes A :: "('a::comm_ring_1 poly)^'n∷finite^'n∷finite"
and f :: "('a::comm_ring_1 poly) ⇒ nat"
shows "finite {f (A $ i $ j) | i j. True }"
sorry
My old proof that is no longer working with the development version of Isabelle is this:
proof-
have "⋀ K. finite ((λ (i, j). f (A $ i $ j)) ` K)" using finite_imageI by simp
from this show ?thesis by simp
qed
The simplification procedure finite_Collect has been deactivated after the Isabelle2013-2 release in changeset 31afce809794, because it sometimes behaves surprisingly or crashes. You can reactivate it with using [[simproc add: finite_Collect]] between the lemma statement and the start of your proof. Then, your former proof works again.
By the way, it is in general not a good idea to use the repository version for your work unless you desparately need a new feature or want to participate in the Isabelle development process.

Need proof for meta-logic conjunction elimination rule

Here, I ask for a proof of a Isabelle meta-logic conjunction elimination rule.
The source below contains comments of mine which explain a little of what I'm doing. In the theory, there are two pairs of a meta-false definition and conjunction elimination rule. The two pairs are the following:
falseH, andH_E1, and
falseM, andM_E1.
The form of my andM conjunction is (P ==> Q ==> falseM) ==> falseM), and it's this form for which I cannot get an easy proof.
In the future, I plan on duplicating the HOL.thy natural deduction rules using meta-logic operators which will be similar to the andM above. As part of that, the operator ==> will be treated as a primitive operator. Because the Pure operator !! is also primitive in the same sense as ==>, I'm guessing that I may not be able to develop rules which will help me with the meta-false definition, !!P. PROP P, as I use it below. I could be wrong, though.
It's not like I have to have the falseM I try to use below, because falseH is conducive to the simp magic that already works in conjunction with HOL, pun not intended. Though I don't have to have it, having it would be good.
theory i131210a__SO_question_andM_elim
imports Complex_Main
begin
(*This is conjunct1 from HOL.thy, line 426. Someday, I'll get rules to
use by duplicating the HOL rules as meta-logic rules, but my question
here is about proving andM_E1 below with what's already available.*)
lemma conjunct1_from_HOL:
"[| P & Q |] ==> P"
by(unfold and_def, iprover intro: impI dest: spec mp)
(*Using bool for falseH allows the auto magic to work for andH_E1.*)
definition falseH :: "prop" ("falseH") where
"falseH == (!!P. P::bool)"
theorem andH_E1:
"((P ==> Q ==> falseH) ==> falseH) ==> P"
by(unfold falseH_def, auto)
(*Using Pure &&&, auto-tools work too, but I want a different meta-and.*)
theorem mand_E1:
"(P &&& Q) ==> P"
by(linarith)
(*Here I define a pure meta-false. That's what I want, if I can get it.*)
definition falseM :: "prop" ("falseM") where
"falseM == (!!P. PROP P)"
(*But here, I need an IsaMagician to do what may be easy, or may be hard.
A proof for this might give me a good template to follow.*)
theorem andM_E1:
"((P ==> Q ==> falseM) ==> falseM) ==> P"
apply(unfold falseM_def)
oops
end
Update (131211)
I update this with three things, where two of them are related to Andreas' answer that an axiom of excluded middle is needed. What I say below is not really an answer to anything, and it's open to more comments, since I can be wrong on simple things.
I put my lengthy comments in here to consolidate some ideas related to the core idea of my question, which is how to use a meta-logic false to define meta-logic operators.
I show how I think I would add a meta-logic axiom of excluded middle in a locale.
I show what led to me understanding what form of an axiom of excluded middle I need. Most all the literature will say that an excluded middle is P or not P, which is deceptive, since I rarely think about an excluded middle, because it is ingrained my thinking.
I note that "(P &&& Q) ==> P is proved by conjunctionD1 in conjunction.ML, and an unfolded version is proved using meta_allE. I wonder why andM, with !! on the inside rather than outside, can't be manipulated so that it can be proved.
Putting a Meta-Logic Excluded Middle in a Locale
So Adreas saved me many months, probably at least a year, and possibly many years of fruitless scheming by pointing out that Isabelle/Pure doesn't have an excluded middle, and that I need it. This has helped answer related questions I had, and helps make more sense to me what Isabelle/Pure is.
If using the HOL excluded middle is forced on me, I would just use False, instead of (!!P. P::bool).
If I want a meta-false, I think I would add a meta-logic excluded middle in a locale like this:
abbreviation (input) trueM :: "prop" ("trueM") where
"trueM == (falseM ==> falseM)"
locale pure_with_em =
assumes t_or_f: "((P == trueM) ==> falseM) ==> (P == falseM)"
begin
theorem andM_E1:
"((P ==> Q ==> falseM) ==> falseM) ==> P"
unfolding falseM_def
oops
end
Like I said, this is not an answer because I would have to work it out.
From the proof that Andreas provided, there is classical from HOL:
lemma classical:
assumes prem: "~P ==> P" shows "P"
apply (rule True_or_False [THEN disjE, THEN eqTrueE])
...
The proof steps of HOL theorems like this tell me what I need for meta-logic versions. I did the easy part by providing the locale axiom t_or_f. The rest is just plain ole work.
Isabelle/Pure Not Having an Excluded Middle
Here, I don't talk just to talk, which I do at times, but I put in what I worked through to see that == is needed as part of an excluded middle. I could need to look at all this again, so maybe it won't be held against me.
First, jumping ahead of what I say next about the HOL lemma excluded_middle, a person, me in particular, would also want to be thinking about this
HOL.thy axiom, line 171:
True_or_False: "(P = True) | (P = False)".
Andreas points out that the law of excluded middle is needed, and that Pure does not provide it. This is the HOL.thy theorem named
excluded_middle, line 604:
lemma excluded_middle: "~P | P" by (iprover intro: disjCI)
Analogously, I state this as a meta-logic theorem using falseM, where my meta-or is (P ==> falseM) ==> Q, and meta-not is P ==> falseM.
theorem
"(P ==> falseM) ==> (P ==> falseM)"
by(simp)
If meta-or notation is defined to obscure what it actually is, a logical novice (not me of course) might not recognize this as "if P is false then P is false", rather than what's needed, "if P is not false, then it must be true".
Update (131213): I put this in because I can forget why I did something, then when I try to work back through the logic, I think I messed up big time, when I didn't, though my logical awareness may not have been complete.
I didn't actually implement a meta-logic version of ~P | P, but of P | ~P. If it's not obvious, which it probably is, I'm using a truth table based definition of implication along with DeMorgan's laws, and using the basic theorems of logic, which ultimately must be true for me.
However, I'm now working with hindsight in regards to the axiom of excluded middle, which makes the fact that I used P | ~P less acceptable, since it becomes "((P ==> falseM) ==> falseM) ==> P", which involves double negation, which I vaguely remember is related to all this. Until now, I've never in my life ever had to concern myself with the excluded middle. That's supposed to be what constructivists think about.
It's actually fortuitous that I made the switch, because that took me to seeing the significance of = in True_or_False.
A meaningful theorem would be "not (P and not P)" (or would it?).
So I substitute (P ==> falseM) for Q in the meta-and expression
(P ==> Q ==> falseM) ==> falseM.
theorem
"((P ==> (P ==> falseM) ==> falseM) ==> falseM) ==> falseM"
by(auto,assumption)
This has gone into full play-the-logical-fool red alert, because falseM
didn't have to be expanded. Now, I state the same theorem, but without
bool variables and without falseM, to make explicit that it has nothing
to do with falseM or bool.
theorem
"((PROP P ==> (PROP P ==> PROP Q) ==> PROP Q) ==> PROP Q) ==> PROP Q"
by(erule Pure.cut_rl Pure.meta_impE Pure.meta_mp, assumption)
Back to what I jumped ahead to at the beginning, I see now that a key
difference is that operator = is being used in True_or_False.
Now, I state a meta-logic form of True_or_False which uses operator ==,
with meta-or as (P ==> falseM) ==> Q, the true part as (P == (falseM ==> falseM)), and the false part as (P == falseM).
theorem
"((P == (falseM ==> falseM)) ==> falseM) ==> (P == falseM)"
apply(unfold falseM_def)
oops
This finally got me a meaningful meta-logic statement of the excluded
middle, in which falseM needs to be expanded. I can't prove this, which
means nothing in itself, or disprove it, which means I could be totally
confused.
This demonstrates why I have to study a lot of low-level logic to work
with theorem assistants, when my end goal is high-level mathematics,
which traditionally doesn't require this kind of knowledge.
Not having a good understanding of the significance of no excluded middle
ended up killing me, among other things.
Why Can "(P &&& Q) ==> P" Be Proved Above?
There is still the significance that (P &&& Q) ==> P can be proved by
the methods linarith and presburger above, where &&& in pure_thy.ML is this:
"(A &&& B) == (!!C::prop. (A ==> B ==> C) ==> C)"
My meta-and, using falseM, actually just moves the use of !! from the
outside to the inside, once falseM has been expanded.
Here, I prove expanded terms of meta-and elimination, and prove an unexpanded version of it using Pure.conjunctiond1.
theorem
"(PROP P &&& PROP Q) ==> PROP P"
apply(unfold Pure.conjunction_def)
by(erule Pure.meta_allE, assumption)
theorem expanded_and_1:
"(!!R. (PROP P ==> PROP Q ==> PROP R) ==> PROP R) ==> PROP P"
by(erule Pure.meta_allE, assumption)
theorem
"(PROP P &&& PROP Q) ==> PROP P"
by(erule Pure.conjunctionD1)
The rule conjunctionD1 is in conjunction.ML, and it appears that forall_elim_vars
is taking care of the operator !!, which I suppose is just doing the same thing as meta_allE.
I Could Use the Standard Meta-And, but Meta-And Is Not the Goal
I compare two expanded versions of the conjunction elimination rule. The first term uses the standard &&&, and the second term uses my andM.
term "(!!R. (P ==> Q ==> PROP R) ==> PROP R) ==> P"
term "((P ==> Q ==> (!!P. PROP P)) ==> (!!P. PROP P)) ==> P"
Using &&& allows the first term to be proved easily with meta_allE, as shown above.
It seems to me, I should be able to manipulate the second term into the form of the first term, but I wouldn't know. If that's true, then I don't need to add an axiom of excluded middle for this theorem. I'll know after studying a lot of natural deduction, like I need to.
If my goal was just meta-logic operators, I'd use &&&, but that's not my goal. My goal is to define a meta-false to use to abbreviate meta-logic operators. I'm trying to slightly expand the natural deduction framework of Isabelle/Pure, not duplicate all of HOL.
The main value I've gotten from this question is that I now know I need to be on the lookout for the need for an axiom of excluded middle. If I want a meta-false, then it seems I will need an axiom of excluded middle.
This is where I leave off. Thanks for the help, and please pardon the lengthy additions.
As a first step, you can prove the HOL version andH_E1 without using any proof tools, just plain rule, subst, and assumption. Then, you should be able to see whether you can translate your proof to andM_E1 and how to do so. I found the following proof for andH_E1:
theorem andH_E1: "((P ==> Q ==> falseH) ==> falseH) ==> P"
unfolding falseH_def
apply(rule classical)
apply(erule meta_allE)
apply(erule meta_impE)
apply(erule notE)
apply assumption
apply assumption
done
As you can see, the first step applies the rule classical, i.e., my proof works only in classical logic. However, Pure is weaker than classical logic, because there is no axiom of excluded middle. Hence, you will not be able to transfer this proof to andM_E1. You can try to find a proof of andH_E1 that does not rely on the classical axioms, but I doubt that you will find one; at least iprover does not. Otherwise, you cannot prove this theorem with Pure means only unless you introduce the axiom of excluded middle to Pure.
As excluded middle is equivalent to the classical axiom (you can derive the one from the other), the easiest way to go is probably to add the classical axiom directly, e.g., in a locale as you suggested. Then, the proof goes as follows, where I write Pure negation as _ ==> falseM.
locale classical =
assumes pure_classical: "((PROP P ==> falseM) ==> PROP P) ==> PROP P"
begin
theorem andM_E1:
"((PROP P ==> PROP Q ==> falseM) ==> falseM) ==> PROP P"
unfolding falseM_def
apply(rule pure_classical)
apply(erule meta_allE)
apply(erule meta_impE) back
apply(erule (1) meta_impE)
apply(unfold falseM_def)
apply(assumption)
apply(assumption)
done
end

Resources