-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simple coq lemmas #36
Changes from 9 commits
71e2150
f67c2c0
269f916
c1f94ef
9d10f7e
e7268c4
425b068
1bc88fe
15544d9
24e43ce
8b18f3d
e42511c
4cee296
b0b7ead
6fce7fa
3fcc4c7
14988a6
cb04df9
cbabefd
156c4f0
b1f959a
03339e5
fe58f29
69a793e
f39bb7f
8570aff
5f704cc
4d5f28b
4ec3023
553f94f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
build/**/*.vo | ||
build/**/*.vos | ||
build/**/*.vok | ||
build/**/*.glob | ||
build/**/*.aux | ||
Makefile.coq | ||
Makefile.coq.conf | ||
.Makefile.coq.d | ||
/build/.lia.cache |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
## Examples | ||
|
||
CN examples using lemmas that can be extracted to Coq. The examples are split into: | ||
|
||
- Trivial | ||
- Recursive | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought recursive definitions weren't working? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. These are examples of recursive definitions we want to work. The provided recursive examples pass the CN verification but fail to export. I'll add clarification. |
||
- Lists (WIP) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove WIP, as they don't seem to be included in this PR? |
||
- Advanced (WIP) | ||
|
||
## Generating Coq Lemmas | ||
|
||
To generate Coq lemma for a given `example-file.c` run | ||
|
||
``` | ||
cn --lemmata=build/theories/ExportedLemmas.v example-file.c | ||
``` | ||
|
||
File `build/theories/ExportedLemmas.v` should be generated with the | ||
right definitions. Each lemma is exported as a new definition and then | ||
added as a parameter in the module named `Lemma_Spec`. It should look | ||
something like this | ||
|
||
``` | ||
|
||
Module Defs (P : Parameters). | ||
|
||
Import Types P. | ||
Open Scope Z. | ||
|
||
|
||
Definition my_lemma_type : Prop := | ||
Is_true true. | ||
|
||
End Defs. | ||
|
||
|
||
Module Type Lemma_Spec (P : Parameters). | ||
|
||
Module D := Defs(P). | ||
Import D. | ||
|
||
Parameter my_lemma : my_lemma_type. | ||
|
||
End Lemma_Spec. | ||
``` | ||
|
||
## Prooving the Coq Lemmas | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: "Prove" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs some brief description what coq tools need to be installed to run the examples |
||
|
||
To prove the lemmas, instantiate a new module with type `Lemma_Spec` containing each of parameters as lemmas and their proofs. For the example above, the proofs look like this | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent line wrapping wrt above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This explanation isn't enough for me to know what to do. In which file does |
||
|
||
``` | ||
|
||
Module MyP: Parameters. | ||
End MyP. | ||
|
||
Module Proofs : Lemma_Spec MyP. | ||
Module D := Defs(MyP). | ||
Import D. | ||
|
||
Lemma just_arith2 : my_lemma_type. | ||
Proof. | ||
solve [hnf; trivial]. | ||
Qed. | ||
|
||
End Proofs. | ||
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/*@ | ||
lemma lem_bit_wise_and (u32 x) | ||
requires true; | ||
ensures x & x == x; | ||
@*/ | ||
|
||
void trivial() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/*@ | ||
lemma lem_bit_wise_or (u32 x) | ||
requires true; | ||
ensures x | x == x; | ||
@*/ | ||
|
||
void trivial() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what the purpose of this Makefile is - do I call it during the proof process? |
||
|
||
|
||
all: | ||
coq_makefile -f _CoqProject -o Makefile.coq | ||
cn ../../SantiagosExamples/trivial-lemma.c --lemmata theories/Gen_Spec.v | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect path |
||
make -f Makefile.coq | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
-Q theories CN_Lemmas | ||
|
||
theories/CN_Lib.v | ||
theories/ExportedLemmas.v | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
Require List. | ||
Require Import ZArith Bool. | ||
Require Import Lia. | ||
Require NArith. | ||
|
||
Definition wrapI (minInt : Z) (maxInt : Z) x := | ||
let delta := ((maxInt - minInt) + 1)%Z in | ||
let r := Z.modulo x delta in | ||
(if (r <=? maxInt) then r else r - delta)%Z. | ||
|
||
Lemma wrapI_idem: | ||
forall (minInt maxInt x : Z), | ||
(minInt <= x <= maxInt)%Z -> | ||
(minInt <= 0 < maxInt)%Z -> | ||
wrapI minInt maxInt x = x. | ||
Proof. | ||
Open Scope Z. | ||
intros. | ||
unfold wrapI. | ||
pose (delta := ((maxInt - minInt) + 1)). | ||
destruct (0 <=? x) eqn: x_neg. | ||
- rewrite Z.mod_small by lia. | ||
rewrite Zle_imp_le_bool by lia. | ||
reflexivity. | ||
- rewrite (Znumtheory.Zdivide_mod_minus _ _ (x + delta)). | ||
+ destruct (x + delta <=? maxInt) eqn: leb; lia. | ||
+ lia. | ||
+ exists (-1); lia. | ||
Qed. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(* build/theories/ExportedLemmas.v: generated lemma specifications from CN *) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this file going to be auto-generated by CN - why include a skeleton? |
||
|
||
Require Import ZArith Bool. | ||
Require CN_Lemmas.CN_Lib. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
(* theories/Gen_Spec.v: generated lemma specifications from CN *) | ||
|
||
Require Import ZArith Bool. | ||
Require CN_Lemmas.CN_Lib. | ||
|
||
|
||
Module Types. | ||
|
||
(* no type definitions required *) | ||
|
||
End Types. | ||
|
||
|
||
Module Type Parameters. | ||
Import Types. | ||
|
||
(* no parameters required *) | ||
|
||
End Parameters. | ||
|
||
|
||
Module Defs (P : Parameters). | ||
|
||
Import Types P. | ||
Open Scope Z. | ||
|
||
|
||
Definition lem_trivial_type : Prop := | ||
Is_true true. | ||
|
||
End Defs. | ||
|
||
|
||
Module Type Lemma_Spec (P : Parameters). | ||
|
||
Module D := Defs(P). | ||
Import D. | ||
|
||
Parameter lem_trivial : lem_trivial_type. | ||
|
||
End Lemma_Spec. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <stdbool.h> | ||
/*@ | ||
predicate (bool) MyCondition (u32 x){ | ||
if (x > 4294967295u32){ | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
@*/ | ||
|
||
void trivial() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include <stdbool.h> | ||
/*@ | ||
lemma my_lemma () | ||
requires true; | ||
ensures true; | ||
@*/ | ||
|
||
void trivial() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/*@ function [rec] (u32) my_spec(u32 n) { 42u32 } @*/ | ||
|
||
unsigned int factorial(unsigned int n) | ||
/*@ ensures return == my_spec(n); @*/ | ||
{ | ||
/*@ unfold my_spec(n); @*/ | ||
return 42; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/*@ | ||
function [rec] (u32) fact_spec(u32 n) | ||
{ | ||
if (n <= 0u32) { 1u32 } | ||
else { n * fact_spec(n - 1u32) } | ||
} | ||
@*/ | ||
|
||
|
||
/*@ | ||
lemma spec_lemma (u32 n) | ||
requires true; | ||
ensures fact_spec(n) == n * fact_spec(n-1u32); | ||
@*/ | ||
|
||
// Function to calculate the factorial of a number | ||
unsigned int factorial(unsigned int n) | ||
/*@ requires 0u32 <= n; n <= 4294967294u32; @*/ | ||
/*@ requires fact_spec(n) < 4294967295u32; @*/ | ||
/*@ ensures return == fact_spec(n); @*/ | ||
{ | ||
if (n <= 0) { | ||
/*@ unfold fact_spec(n); @*/ | ||
return 1; // Return 1 | ||
} | ||
|
||
unsigned result = 1; | ||
/*@ unfold fact_spec(1u32-1u32); @*/ | ||
for (unsigned int i = 1; i <= n; i++) | ||
/*@ inv {n}unchanged; @*/ | ||
/*@ inv 0u32 < n; i <= n+1u32; @*/ | ||
/*@ inv 0u32 < i; @*/ | ||
/*@ inv result == fact_spec(i-1u32); @*/ | ||
{ | ||
result *= i; | ||
/*@ apply spec_lemma((i+1u32)-1u32); @*/ | ||
} | ||
|
||
return result; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Fails to export becasue of recursive definition | ||
|
||
/*@ | ||
function [rec] (u32) fib_spec(u32 n) | ||
{ | ||
if (n <= 0u32) { | ||
1u32 | ||
} else { | ||
if (n == 1u32) { | ||
1u32 | ||
} else { | ||
fib_spec(n - 1u32) + fib_spec(n - 2u32) | ||
} | ||
} | ||
} | ||
@*/ | ||
|
||
|
||
/*@ | ||
lemma fib_lemma (u32 n) | ||
requires true; | ||
ensures fib_spec(n) == fib_spec(n - 1u32) + fib_spec(n - 2u32); | ||
@*/ | ||
|
||
// Function to calculate the factorial of a number | ||
unsigned int fibonacci(unsigned int n) | ||
/*@ requires 0u32 <= n; n <= 4294967294u32; @*/ | ||
/*@ requires fib_spec(n) < 4294967295u32; @*/ | ||
/*@ ensures return == fib_spec(n); @*/ | ||
{ | ||
if (n <= 1) { | ||
/*@ unfold fib_spec(n); @*/ | ||
return 1; // Return 1 | ||
} | ||
|
||
unsigned previous = 1; | ||
unsigned tmp = 1; | ||
unsigned result = 1; | ||
|
||
/*@ unfold fib_spec(1u32-1u32); @*/ | ||
/*@ unfold fib_spec(1u32); @*/ | ||
for (unsigned int i = 1; i < n; i++) | ||
/*@ inv {n}unchanged; @*/ | ||
/*@ inv 0u32 < n; i <= n; @*/ | ||
/*@ inv 0u32 < i; @*/ | ||
/*@ inv previous == fib_spec(i-1u32); @*/ | ||
/*@ inv result == fib_spec(i); @*/ | ||
{ | ||
tmp = previous; | ||
previous = result; | ||
result = tmp + previous; | ||
/*@ apply fib_lemma(i+1u32); @*/ | ||
} | ||
|
||
return result; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/*@ | ||
lemma lem_trivial () | ||
requires true; | ||
ensures true; | ||
@*/ | ||
|
||
void lemma_1() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/*@ | ||
lemma lem_impossible_in_coq (u32 x) | ||
requires true; | ||
ensures x <= 4294967295u32; | ||
@*/ | ||
|
||
void nothing() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/*@ | ||
lemma lem_ineq (u32 x, u32 y) | ||
requires x > 0u32; y > 0u32; | ||
ensures x > 0u32; y > 0u32; | ||
@*/ | ||
|
||
void trivial() | ||
{ | ||
; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/*@ | ||
lemma lem_impossible_in_Coq (u32 x) | ||
requires true; | ||
ensures (x + 1u32) - 1u32 == x; | ||
@*/ | ||
|
||
void trivial() | ||
{ | ||
; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this file should begin with instructions for running all the examples in batch, or individually. something like:
Something extremely idiot-proof