How to use retval-postcondition on a variable holding the return value? - verifiable-c

My simple program is vars.c:
int pure0 ()
{
return 0;
}
int get0(int* arr)
{
int z = pure0();
return z;
}
I started proof (file verif_vars.c):
Require Import floyd.proofauto.
Require Import vars.
Local Open Scope logic.
Local Open Scope Z.
Definition get0_spec :=
DECLARE _get0
WITH sh : share, arr : Z->val, varr : val
PRE [_arr OF (tptr tint)]
PROP ()
LOCAL (`(eq varr) (eval_id _arr);
`isptr (eval_id _arr))
SEP (`(array_at tint sh arr 0 100) (eval_id _arr))
POST [tint] `(array_at tint sh arr 0 100 varr) &&
local(`(eq (Vint (Int.repr 0))) retval).
Definition pure0_spec :=
DECLARE _pure0
WITH sh : share
PRE []
PROP ()
LOCAL ()
SEP ()
POST [tint] local(`(eq (Vint (Int.repr 0))) retval).
Definition Vprog : varspecs := nil.
Definition Gprog : funspecs := get0_spec :: pure0_spec ::nil.
Lemma body_pure0: semax_body Vprog Gprog f_pure0 pure0_spec.
Proof.
start_function.
forward.
Qed.
Lemma body_get0: semax_body Vprog Gprog f_get0 get0_spec.
Proof.
start_function.
name arrarg _arr.
name zloc _z.
name zloc' _z'.
forward_call (sh).
entailer!.
auto with closed.
after_call.
forward.
entailer!.
And ended up with two subgoals:
Espec : OracleKind
sh : share
arr : Z -> val
Struct_env := abbreviate : type_id_env.type_id_env
Delta := abbreviate : tycontext
zloc0 : val
arrarg : val
zloc : int
TC : is_pointer_or_null arrarg
Parrarg : isptr arrarg
============================
Int.repr 0 = zloc
subgoal 2 (ID 1273) is:
!!(Int.repr 0 = zloc) |-- emp
First one follows directly from pure0_spec postcondition. But how can I tell it to Coq?
The second goal can be simplified (by admit. entailer.) to TT |-- emp. Which seems again trivial, and still how could one prove it (SearchAbout derives and SearchAbout emp don't show any general lemmas)?
I use: VST 1.5 (6834P at 2014-10-02), CompCert 2.4, Coq 8.4pl3(Jan'14) with OCaml 4.01.0.

First: offhand, without attempting to reproduce this myself-- is it possible that using entailer! is too "risky", because (as documented) entailer! can sometimes turn a provable goal into an unprovable one. Try with entailer without the bang, and see if it looks better.
Second, TT |-- emp is not true. TT applies to any heap, and emp applies only to empty heaps. You can fix this by changing the postcondition the pure function to,
POST [tint] local(`(eq (Vint (Int.repr 0))) retval) && emp.

Related

how can I repeat monadic instructions inside kind's monads?

I know that I can run monadic instructions sequentially inside monads in Kind language, like this:
Test: _
IO {
IO.print(Nat.show(2))
IO.print(Nat.show(3))
IO.print(Nat.show(4))
}
output:
2
3
4
But is it possible to run monadic instructions repeatedly, like this below?
Test: _
a = [2,1,3,4,5]
IO {
for num in a:
IO.print(Nat.show(num))
}
If it is possible how can I do it correctly?
Monads are usually represented by only two operators :
return :: a -> m(a) // that encapulapse the value inside a effectful monad
>>= :: m a -> (a -> m b) -> m b
// the monadic laws are omitted
Notice, the bind operator is naturally recursive, once it can compose two monads or even discard the value of one and the return can be thought of as a "base case".
m >>= (\a -> ... >>= (\b -> ~ i have a and b, compose or discard? ~) >>= fixpoint)
You just have to produce that sequence, which is pretty straightforward. For example, in Kind we represent monads as a pair which takes a type-for-type value and encapluse a polymorphic type.
type Monad <M: Type -> Type> {
new(
bind: <A: Type, B: Type> M<A> -> (A -> M<B>) -> M<B>
pure: <A: Type> A -> M<A>
)
}
In your example, we just have to trigger the effect and discard the value, a recursive definition is enough :
action (x : List<String>): IO(Unit)
case x {
nil : IO.end!(Unit.new) // base case but we are not worried about values here, just the effects
cons : IO {
IO.print(x.head) // print and discard the value
action(x.tail) // fixpoint
}
}
test : IO(Unit)
IO {
let ls = ["2", "1", "3", "4", "5"]
action(ls)
}
The IO as you know it will be desugared by a sequence of binds!
Normally in case of list it can be generalized like the mapM function of haskell library :
Monadic.forM(A : Type -> Type, B : Type,
C : Type, m : Monad<A>, b : A(C), f : B -> A(C), x : List<A(B)>): A(C)
case x {
nil : b
cons :
open m
let k = App.Kaelin.App.mapM!!!(m, b, f, x.tail)
let ac = m.bind!!(x.head, f)
m.bind!!(ac, (c) k) // the >> operator
}
It naturally discard the value and finally we can do it :
action2 (ls : List<String>): IO(Unit)
let ls = [IO.end!(2), IO.end!(1), IO.end!(3), IO.end!(4), IO.end!(5)]
Monadic.forM!!!(IO.monad, IO.end!(Unit.new), (b) IO.print(Nat.show(b)), ls)
So, action2 do the same thing of action, but in one line!.
When you need compose the values you can represent as monadic fold :
Monadic.foldM(A : Type -> Type, B : Type,
C : Type, m : Monad<A>, b : A(C), f : B -> C -> A(C), x : List<A(B)>): A(C)
case x {
nil : b
cons :
open m
let k = Monadic.foldM!!!(m, b, f, x.tail)
m.bind!!(x.head, (b) m.bind!!(k, (c) f(b, c)))
}
For example, suppose that you want to sum a sequence of numbers that you ask for the user in a loop, you just have to call foldM and compose with a simple function :
Monad.action3 : IO(Nat)
let ls = [IO.get_line, IO.get_line, IO.get_line]
Monadic.foldM!!!(IO.monad, IO.end!(0),
(b, c) IO {
IO.end!(Nat.add(Nat.read(b), c))
},
ls)
test : IO(Unit)
IO {
get total = action3
IO.print(Nat.show(total))
}
For now, Kind do not support typeclass so it make the things a little more verbose, but i think a new support to forM loops syntax can be thought in the future. We hope so :)

Writing variable patterns in Isabelle/ML

I was studying ways to trasnlate:
apply(rewrite in "_ / ⌑" some_theorem)
into ML, and I came up with the following:
apply(tactic ‹
let
val pat = [
Rewrite.In,
Rewrite.Term (#{const divide(real)} $ Var (("c", 0), \<^typ>‹real›) $
Rewrite.mk_hole 1 (\<^typ>‹real›), []),
Rewrite.In
]
val to = NONE
in
CCONVERSION (Rewrite.rewrite_conv #{context} (pat, to) #{thms juanito_def}) 1
end
›)
here I am saying "please pattern match with any subterm of the term in the quotient". You may see previous edits of the question to see interesting patterns.
Some interesting conclusions of having used the library are
at : allows to select a subterm in which to pattern match
in : allows to specify all the subterms of a term
terms will be pattern-matched with the resulting patterns.
Not understood
Could you give an explanation of what the following tactic is doing?
lemma
assumes "Q (λb :: int. P (λa. a + b) (λa. a + b))"
shows "Q (λb :: int. P (λa. a + b) (λa. b + a))"
apply (tactic ‹
let
val (x, ctxt) = yield_singleton Variable.add_fixes "x" \<^context>
val pat = [
Rewrite.Concl,
Rewrite.In,
Rewrite.Term (Free ("Q", (\<^typ>‹int› --> TVar (("'b",0), [])) --> \<^typ>‹bool›)
$ Abs ("x", \<^typ>‹int›, Rewrite.mk_hole 1 (\<^typ>‹int› --> TVar (("'b",0), [])) $ Bound 0), [(x, \<^typ>‹int›)]),
Rewrite.In,
Rewrite.Term (#{const plus(int)} $ Free (x, \<^typ>‹int›) $ Var (("c", 0), \<^typ>‹int›), [])
]
val to = NONE
in CCONVERSION (Rewrite.rewrite_conv ctxt (pat, to) #{thms add.commute}) 1 end
›)
apply (fact assms)
done
The first Rewrite.Term and the fixing of a variable are a bit obscure to me.

Imperative OCaml data structure with pointers?

Is such a thing possible?
Hi all,
in my class we were told to implement Binary Search Trees in OCaml, using functional and imperative programming.
We are following an ADT and implementation in Pascal, a procedural language where pointers are used.
This is how the data structure looks like:
# Pascal
type
tKey = integer;
tPos = ^tNode;
tNode = record
key : tKey;
left, right : tPos;
end;
tBST = tPosT;
We were also given some basic BST operations. Here is an example of one, if that could help:
# Pascal
procedure add_key(VAR T : tBST; k:tKey);
var new, parent, child : tBST;
begin
createNode(new);
new^.key := k;
new^.left := nil;
new^.right := nil;
if T=nil then
T := new
else begin
parent := nil;
child := T;
while (child <> nil) and (child^.key <> k) do begin
parent := child;
if k < child^.key then
child := child^.left
else
child := child^.right;
end;
if (child = nil) then
if k < parent^.key then
parent^.left := new
else
parent^.right := new;
{ duplicates are ignored }
end;
end;
This is how my functional (if that makes any sense) data structure looks like:
type key =
Key of int;;
type bst =
Empty
| Node of (key * bst * bst);;
However, I am having big trouble using the imperative facet of OCaml. I have to make it look as similar as possible as the Pascal implementation and I don't know about the possibilities of data structures and pointers in OCaml since I've always programmed using recursive and so on. I was thinking in using multiple "let", if's and else's, but I have no idea how to define my data structure.
Would appreciate enormously input on this.
From what I understand you would have a type like this :
type key = int
type t = Empty | Node of t * key * t
But your add function shouldn't look like this :
let rec add x t =
match t with
| Empty ->
Node (Empty, x, Empty)
| Node (l, v, r) ->
let c = compare x v in
if c = 0 then t
else if c < 0 then Node (add x l, v, r)
else Node (l, v, add x r)
Because this is only functional.
Maybe you could change your type to :
type t = Empty | Node of t ref * key * t ref
And try to adapt the add function to this type.

No instance for (Monad m0) arising from a use of `return'

I try to create a program in haskell and Qt which displays in a graph some points got from an haskell function.
here is a working sample, but the point is in the return function and its parameters, not the rest of the code!
main :: IO ()
main = do
clazz <- newClass [
defMethod' "factorial" (\_ t𐌴xt𐌴 ->
let n = read $ T.unpack t𐌴xt𐌴 :: Integer
in return . T.pack . show $ product [1..n] :: IO Text)]
ctx <- newObject clazz ()
runEngineLoop defaultEngineConfig {
initialDocument = fileDocument "exemple4.qml",
contextObject = Just $ anyObjRef ctx}
here is my code:
main :: IO ()
main = do
clazz <- newClass [
defMethod' "init_tableau" (\_ ->
return $ map (^2) [0..20])]
ctx <- newObject clazz ()
runEngineLoop defaultEngineConfig {
initialDocument = fileDocument "exemple4.qml",
contextObject = Just $ anyObjRef ctx}
it should only return the 21 first occurences of i^2, beginning from 0.
and here are all the errors:
Build FAILED
/home/lowley/Documents/haskell/Qt/lancer-qml4.hs: line 10, column 9:
No instance for (MethodSuffix (m0 [b0]))
arising from a use of defMethod'
The type variables `m0', `b0' are ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance (Marshal a, CanGetFrom a ~ Yes, MethodSuffix b) =>
MethodSuffix (a -> b)
-- Defined in `Graphics.QML.Objects'
instance (Marshal a, CanReturnTo a ~ Yes) => MethodSuffix (IO a)
-- Defined in `Graphics.QML.Objects'
Possible fix:
add an instance declaration for (MethodSuffix (m0 [b0]))
In the expression:
defMethod' "init_tableau" (\ _ -> return $ map (^ 2) [0 .. 20])
In the first argument of `newClass', namely
`[defMethod' "init_tableau" (\ _ -> return $ map (^ 2) [0 .. 20])]'
In a stmt of a 'do' block:
clazz <- newClass
[defMethod' "init_tableau" (\ _ -> return $ map (^ 2) [0 .. 20])]
/home/lowley/Documents/haskell/Qt/lancer-qml4.hs: line 11, column 13:
No instance for (Monad m0) arising from a use of `return'
The type variable `m0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Monad ((->) r) -- Defined in `GHC.Base'
instance Monad IO -- Defined in `GHC.Base'
instance Monad [] -- Defined in `GHC.Base'
...plus two others
In the expression: return
In the expression: return $ map (^ 2) [0 .. 20]
In the second argument of defMethod', namely
`(\ _ -> return $ map (^ 2) [0 .. 20])'
/home/lowley/Documents/haskell/Qt/lancer-qml4.hs: line 11, column 27:
No instance for (Num b0) arising from a use of `^'
The type variable `b0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the first argument of `map', namely `(^ 2)'
In the second argument of `($)', namely `map (^ 2) [0 .. 20]'
In the expression: return $ map (^ 2) [0 .. 20]
/home/lowley/Documents/haskell/Qt/lancer-qml4.hs: line 11, column 31:
No instance for (Enum b0)
arising from the arithmetic sequence `0 .. 20'
The type variable `b0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Enum Double -- Defined in `GHC.Float'
instance Enum Float -- Defined in `GHC.Float'
instance Integral a => Enum (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 7 others
In the second argument of `map', namely `[0 .. 20]'
In the second argument of `($)', namely `map (^ 2) [0 .. 20]'
In the expression: return $ map (^ 2) [0 .. 20]
I think the error is tiny, it should be quickly corrected but all my attempts were failures.
thanks you
EDIT:
for informations:
Prelude> let liste=[0..20] in map (^2) liste
[0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400]
Prelude>
I tried :
defMethod' "init_tableau" (\_ ->
let a=map (^2) [0..20]
in return a)]
with roughly the same error
EDIT 2:
Prelude> :t map (^ 2) [0..20]
map (^ 2) [0..20] :: (Enum b, Num b) => [b]
EDIT 3:
with this code:
main :: IO ()
main = do
clazz <- newClass [
defMethod' "init_tableau" (\_ ->
return ( map (^2) [0..20] ) :: IO [Integer] )]
ctx <- newObject clazz ()
runEngineLoop defaultEngineConfig {
initialDocument = fileDocument "exemple4.qml",
contextObject = Just $ anyObjRef ctx}
I've got this error:
/home/lowley/Documents/haskell/hsqml-demo-samples-0.3.4.0/qml/tableau1.hs:11:9:
Couldn't match type `MarshalMode Integer ICanReturnTo ()'
with `Yes'
In the expression:
defMethod'
"init_tableau"
(\ _ -> return (map (^ 2) [0 .. 20]) :: IO [Integer])
In the first argument of `newClass', namely
`[defMethod'
"init_tableau"
(\ _ -> return (map (^ 2) [0 .. 20]) :: IO [Integer])]'
In a stmt of a 'do' block:
clazz <- newClass
[defMethod'
"init_tableau"
(\ _ -> return (map (^ 2) [0 .. 20]) :: IO [Integer])]
I still can't resolve it.
I have not tested this, but I suspect the problem here is that there are many appropriate monads that could be used. If you want to be completely parallel to the working example, you can explicitly choose to use IO as the monad by adding a type annotation to the return expression:
return $ map (^2) [0..20] :: IO [Integer]
Daniel Wagner's suggestion fixes the error you asked about.
You now have another, unrelated error:
Couldn't match type `MarshalMode Integer ICanReturnTo ()' with `Yes'
Now consider the type
defMethod' :: (Typeable obj, MethodSuffix ms) => String -> (ObjRef obj -> ms) -> Member obj
You are attempting to pass (\_ -> return ( map (^2) [0..20] ) :: IO [Integer] ) to that as the second argument.
So can we unify ObjRef obj -> ms with forall a. a -> IO [Integer]?
Well, the first part unifies because a is free. But is IO [Integer] an instance of MethodSuffix? Follow the typeclasses and you'll see this requires that [Integer] be an instance of Marshal and follow that and you'll see we can't do that. I didn't see a good listing of the basic instances of Marshal in the docs, but I did find them in the source.
So it seems if instead of [Integer] you try to return [Int] or Text, then this will likely typecheck.

Implementing Okasaki's bootstrapped heaps in OCaml, why doesn't it compile?

(A minimal non-compiling example can be found at https://gist.github.com/4044467, see more background below.)
I am trying to implement Bootstrapped Heaps introduced in Chapter 10 of Okasaki's Purely Functional Data Structure. The following is a simplified version of my non-compiling code.
We're to implement a heap with following signature:
module type ORDERED =
sig
type t
val compare : t -> t -> int
end
module type HEAP =
sig
module Elem : ORDERED
type heap
val empty : heap
val insert : Elem.t -> heap -> heap
val find_min : heap -> Elem.t
val delete_min : heap -> heap
end
We say a data structure is bootstrapped when its implementation depends on another implementation of the same kind of data structure. So we have a heap like this (the actual implementation is not important):
module SomeHeap (Element : ORDERED) : (HEAP with module Elem = Element) =
struct
module Elem = Element
type heap
let empty = failwith "skipped"
let insert = failwith "skipped"
let find_min = failwith "skipped"
let delete_min = failwith "skipped"
end
Then, the bootstrapped heap we're going to implement, which can depend on any heap implementation, is supposed to have the following signature:
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element)
So we can use it like this:
module StringHeap = BootstrappedHeap(SomeHeap)(String)
The implementation of BootstrappedHeap, according to Okasaki, is like this:
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element) =
struct
module Elem = Element
module rec BootstrappedElem :
sig
type t =
| E
| H of Elem.t * PrimH.heap
val compare : t -> t -> int
end =
struct
type t =
| E
| H of Elem.t * PrimH.heap
let compare t1 t2 = match t1, t2 with
| H (x, _), H (y, _) -> Elem.compare x y
| _ -> failwith "unreachable"
end
and PrimH : (HEAP with module Elem = BootstrappedElem) =
MakeH(BootstrappedElem)
type heap
let empty = failwith "not implemented"
let insert = failwith "not implemented"
let find_min = failwith "not implemented"
let delete_min = failwith "not implemented"
end
But this is not compiling! The error message is:
File "ordered.ml", line 52, characters 15-55:
Error: In this `with' constraint, the new definition of Elem
does not match its original definition in the constrained signature:
Modules do not match:
sig type t = BootstrappedElem.t end
is not included in
ORDERED
The field `compare' is required but not provided
The line 52 is the line
and PrimH : (HEAP with module Elem = BootstrappedElem) =
I think BootstrappedElem did implement ORDERED as it has both t and compare, but I failed to see why the compiler fails to find the compare function.
Change the signature of BootstrappedElem to
module rec BootstrappedElem : ORDERED
will make it compiling but this will hide the type constructor E and T in BootstrappedElem to make it impossible to implement the later parts.
The whole non-compiling code can be downloaded at https://raw.github.com/gist/4044281/0ce0336c40b277e59cece43dbadb9b94ce6efdaf/ordered.ml
I believe this might be a bug in the type-checker. I have reduced your code to the following example:
module type ORDERED =
sig
type t
val compare : t -> t -> int
end
module type CARRY = sig
module M : ORDERED
end
(* works *)
module HigherOrderFunctor
(Make : functor (X : ORDERED) -> (CARRY with module M = X))
= struct
module rec Base
: (ORDERED with type t = string)
= String
and Other
: (CARRY with module M = Base)
= Make(Base)
end
(* does not work *)
module HigherOrderFunctor
(Make : functor (X : ORDERED) -> (CARRY with module M = X))
= struct
module rec Base
: sig
(* 'compare' seems dropped from this signature *)
type t = string
val compare : t -> t -> int
end
= String
and Other
: (CARRY with module M = (Base : sig type t = string val compare : t -> t -> int end))
= Make(Base)
end
I don't understand why the first code works and the second (which seems equivalent) doesn't. I suggest you wait a bit to see if an expert comes with an explanation (Andreas?), then consider sending a bug report.
In this case, a solution is to first bind the signature that seems mishandled:
(* works again *)
module HigherOrderFunctor
(Make : functor (X : ORDERED) -> (CARRY with module M = X))
= struct
(* bind the problematic signature first *)
module type S = sig
type t = string
val compare : t -> t -> int
end
module rec Base : S = String
and Other : (CARRY with module M = Base) = Make(Base)
end
However, that is not possible in your setting, because the signature of BootstrappedElem is mutually recursive with BootstrappedHeap.
A workaround is to avoid the apparently-delicate with module ... construct and replace it with a simple type equality with type Elem.t = ...:
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element) =
struct
module Elem = Element
module rec BootstrappedElem :
sig
type t =
| E
| H of Elem.t * PrimH.heap
val compare : t -> t -> int
end =
struct
type t =
| E
| H of Elem.t * PrimH.heap
let compare t1 t2 = match t1, t2 with
| H (x, _), H (y, _) -> Elem.compare x y
| _ -> failwith "unreachable"
end
and PrimH : (HEAP with type Elem.t = BootstrappedElem.t) =
MakeH(BootstrappedElem)
type heap
let empty = failwith "not implemented"
let insert = failwith "not implemented"
let find_min = failwith "not implemented"
let delete_min = failwith "not implemented"
end
You could also avoid the mutual recursion and define both BootstrappedElem and BootstrappedHeap in one recursive knot, by defining BootstrappedElem inside the recursive BootstrappedHeap.
module BootstrappedHeap
(MakeH : functor (Element : ORDERED) -> HEAP with module Elem = Element)
(Element : ORDERED) : (HEAP with module Elem = Element) =
struct
module rec BootstrappedHeap : sig
module Elem : sig
type t = E | H of Element.t * BootstrappedHeap.heap
val compare : t -> t -> int
end
include (HEAP with module Elem := Elem)
end = struct
module Elem = struct
type t = E | H of Element.t * BootstrappedHeap.heap
let compare t1 t2 = match t1, t2 with
| H (x, _), H (y, _) -> Element.compare x y
| _ -> failwith "unreachable"
end
include (MakeH(Elem) : HEAP with module Elem := Elem)
end
module Elem = Element
type heap
let empty = failwith "not implemented"
let insert = failwith "not implemented"
let find_min = failwith "not implemented"
let delete_min = failwith "not implemented"
end
This style corresponds naturally to your decision of embedding Elem in the HEAP signature and using with module ... for refinement. Another solution would have been to define HEAP as a functor returning a signature, used as HEAP(Elem).S, and I suppose a different recursive style could have been chosed. Not to say that this would have been better: I think the "abstract module" style is more convenient.

Resources