Verified software toolchain: if-then-else proof - coq

I'm learning using the Verified Software Toolchain (VST). I get stuck at proving a simple "if-then-else" block.
Here is the .c file:
int iftest(int a){
int r=0;
if(a==2){
r=0;
else{
r=0;
}
return r;
}
I write a specification about the iftest() as follow:
Definition if_spec :=`
DECLARE _iftest`
WITH a0:int
PRE [_a OF tint]
PROP ()
LOCAL (`(eq (Vint a0)) (eval_id _a))
SEP ()
POST [tint]
PROP ()
LOCAL ((`(eq (Vint (Int.repr 0))) retval))
SEP ().`
the proof steps are:
Lemma body_iftest : semax_body Vprog Gtot f_iftest if_spec.Proof.
start_function.
name a _a.
name r _r.
forward. (*r=0*)
simplify_typed_comparison.
forward. (*if(E)*). go_lower. subst. normalize.
it generates a hypothesis:Post := EX x : ?214, ?215 x : environ -> mpred and the "then" clause can't go on by "go_lower" and "normalize".

In the current version of VST there is a forward_if PRED tactic. Here is how you can use it to solve your goal:
Require Import floyd.proofauto.
Require Import iftest.
Local Open Scope logic.
Local Open Scope Z.
Definition if_spec :=
DECLARE _iftest
WITH a0:int
PRE [_a OF tint]
PROP ()
LOCAL (`(eq (Vint a0)) (eval_id _a))
SEP ()
POST [tint]
PROP ()
LOCAL ((`(eq (Vint (Int.repr 0))) retval))
SEP ().
Definition Vprog : varspecs := nil.
Definition Gtot : funspecs := if_spec :: nil.
Lemma body_iftest : semax_body Vprog Gtot f_iftest if_spec.
Proof.
start_function.
name a _a.
name r _r.
forward.
forward_if (PROP ()
LOCAL (`(eq (Vint (Int.repr 0))) (eval_id _r)) SEP()).
+ forward.
entailer.
+ forward.
entailer.
+ forward.
Qed.
P.S. #bazza is right about a missing } before else. I assume it is fixed.

Potentially a non-helpful answer, but I can't help noticing that your .c code has 3 {'s and only 2 }'s, suggesting that it doesn't compile. Could the error message you're receiving have something to do with that?

Related

Getting access to Coq's rich XML-like AST output

In older versions of Coq (< 8.5), the main coqtop process would interchange data with IDEs using strings.
This was supposedly recently changed - how does one query the richer XML-like structure representing ASTs?
Use case: I would like to interpret whatever Coq computes in a different way - that is, I need its results after performing operations (such as invoking tactics) in a form that's not string that I need to parse.
Note: this answer has been edited to make it up to date
The only reasonable option as of end of 2018 is SerAPI, a Coq language server that supports full serialization of Coq documents. Using SerAPI you can get a full representation of any Coq document or internal structure:
$ rlwrap sertop --printer=human
(Add () "Lemma u n : n + 0 = n.")
> (Answer 0 (StmAdded 2 (...) NewTip))
(Query ((sid 2)) Ast)
> (Answer 1(ObjList
> ((CoqAst
> (VernacStartTheoremProof Lemma
> ((((((Id u)) ()))
> (((LocalRawAssum
> (((Name (Id n))))
> (Default Explicit)
> (CHole () IntroAnonymous ())))
> (CNotation
> "_ = _"
> (((CNotation
> "_ + _"
> (((CRef
> (Ident
> (Id n)))
> ())
> (CPrim
> (Numeral (Ser_Bigint 0))))
> () ()))
> (CRef
> (Ident
> (Id n)))
> ()))
> () ()))
> ())))
> false)))))
Note that SerAPI is experimental software and I am the main author.

LWT simple interaction with a subprocess

Here is a simple program that uses the Unix module to interact with a subprocess. I just launch a cat shell command, send it a string and read it back:
#load "unix.cma";; (* Needed if you are in the toplevel *)
let () =
let sin, sout, serr = Unix.open_process_full "cat" [||] in
output_string sout "test\n";
flush sout;
input_line sin |> print_string;
flush stdout;
Unix.close_process_full (sin, sout, serr) |> ignore;;
Recently I started studying the Lwt library, and I wanted to reproduce the same functionality with it. I though that the following should have exactly the same result:
#use "topfind";; (* *)
#thread;; (* Also only for the toplevel *)
#require "lwt.simple-top";; (* *)
let () =
let open Lwt in
let process = Lwt_process.open_process_full ( "cat" , [||] ) in
Lwt_io.write_line process#stdin "test\n"
>>= ( fun () -> Lwt_io.flush process#stdin )
>>= ( fun () -> Lwt_io.read process#stdout )
>>= ( fun str -> Lwt_io.print str )
>>= ( fun () -> Lwt_io.flush Lwt_io.stdout )
|> Lwt_main.run
But it doesn't work as I expect it to -- apparently it reads and then prints an empty string.
I guess I have some fundamental confusion on how Lwt should work, but I cannot figure it out. Can someone show me how one can communicate with a subprocess using Lwt?
Use Lwt_process.shell to make a proper command, in your case, the proper command is the following:
Lwt_process.shell "cat";;
- : Lwt_process.command = ("", [|"/bin/sh"; "-c"; "cat"|])
Also, I suspect, that after you will run your program in a proper way, you will be wondering, why is your program blocking. This reason is because cat process will not finish until you write an EOF to it's input channel. That's why the Lwt_io.read call will not ever finish. A solution would be to close the stdin channel.

Ocamlbuild plugin: build dynamic dependencies only if the target has changed

I'm trying to write an ocamlbuild plugin. The goal is to build Qt apps (without OCaml code for the time being). To handle the final linking phase, I have written the list of objs, mocs, uis and rcs in a .qtobjs file (like a .itarget), and the list of Qt libs in a .qtpackages file. The rule that applies to these files parses these lists and dynamically builds the objects, mocs and so on before linking everything.
The problem is that I would like not to dynamically build the targets that have not changed. See the rule below:
rule "Link a c++ executable that uses Qt."
~deps:["%.qtobjs"; "%.qtpackages"]
~prod:"%.cxxnative"
(fun env build ->
let dir = Pathname.dirname (env "%.qtobjs") in
let output = env "%.cxxnative" in
let objlist = pwd / (env "%.qtobjs") in
let liblist = pwd / (env "%.qtpackages") in
let packages = read_lines liblist in
let lflags = List.map (fun p -> "-l"^p) packages
# find_all "lflags" in
let objs = List.map (fun o -> dir / o) (read_lines objlist) in
(* Here, I would like to forget the targets that have not changed *)
let objs_to_build = List.filter
(fun target ->
(* something to tell if "target" has to be rebuilt *))
objs in
(* This is where I build the dependencies : *)
let success_builds = build
(List.map (fun o -> [o])
objs_to_build) in
let objects = filter_map
(function
| Outcome.Good x when get_extension x = "opp" ->
Some (pwd / "_build" / (update_extension "o" x))
| Outcome.Good _ -> None
(* Because I don't want to link the ui.h file generated by uic *)
| Outcome.Bad exn -> raise exn)
success_builds in
let tags_objs = tags_of_pathname (env "%.qtobjs") ++ "link" in
let tags_packs = tags_of_pathname (env "%.qtpackages") in
Cmd (S [A (find_one "cxx"); T tags_objs; T tags_packs; Command.atomize lflags;
A "-o"; P output; Command.atomize objects]));
I would like not to call "build" when it's not necessary.
NB: a function
newer_than: Pathname.t -> Pathname.t -> bool
could solve my problem.
Problem solved.
For those who are interested, the problem was in the COMPILING rule : because the ".o" rule was already used by ocamlbuild, I registered it to officially produce ".opp" files but the command actually wrote .o files. So when recompiling, ocamlbuild had no clue that the object file was already present.
Three options:
replace the default ".o" rule (I don't even know if it is possible ?),
produce ".opp" files (but it's less standard),
or alter the compiling rule to do Nop if the .o file exists:
if Pathname.exists (env "%.o") then Nop
else Cmd (S [A ("c++");
A "-c";
A "-o"; P (env "%.o"); P (env "%.cpp")]));

Prolog - Summing numbers

I am new in prolog. I have found breadth first search program in the internet which is search for routes between cities. I want to extend the program to store and calculate distances. But I can't figure out how to do it.
The original code:
move(loc(omaha), loc(chicago)).
move(loc(omaha), loc(denver)).
move(loc(chicago), loc(denver)).
move(loc(chicago), loc(los_angeles)).
move(loc(chicago), loc(omaha)).
move(loc(denver), loc(los_angeles)).
move(loc(denver), loc(omaha)).
move(loc(los_angeles), loc(chicago)).
move(loc(los_angeles), loc(denver)).
bfs(State, Goal, Path) :-
bfs_help([[State]], Goal, RevPath), reverse(RevPath, Path).
bfs_help([[Goal|Path]|_], Goal, [Goal|Path]).
bfs_help([Path|RestPaths], Goal, SolnPath) :-
extend(Path, NewPaths),
append(RestPaths, NewPaths, TotalPaths),
bfs_help(TotalPaths, Goal, SolnPath).
extend([State|Path], NewPaths) :-
bagof([NextState,State|Path],
(move(State, NextState), not(member(NextState, [State|Path]))),
NewPaths), !.
extend(_, []).
Output:
1 ?- bfs(loc(omaha), loc(chicago), X).
X = [loc(omaha), loc(chicago)] ;
X = [loc(omaha), loc(denver), loc(los_angeles), loc(chicago)] ;
false.
I have tried this:
bfs(A,B,Path,D) :-
bfs(A,B,Path),
path_distance(Path,D).
path_distance([_], 0).
path_distance([A,B|Cs], S1) :-
move(A,B,D),
path_distance(Cs,S2),
S1 is S2+D.
bfs(A,B, Path) :-
bfs_help([[A]], B, RevPath), reverse(RevPath, Path).
bfs_help([[Goal|Path]|_], Goal, [Goal|Path]).
bfs_help([Path|RestPaths], Goal, SolnPath) :-
extend(Path, NewPaths),
append(RestPaths, NewPaths, TotalPaths),
bfs_help(TotalPaths, Goal, SolnPath).
extend([State|Path], NewPaths) :-
bagof([NextState,State|Path],
(move(State, NextState,_), not(member(NextState, [State|Path]))),
NewPaths), !.
extend(_, []).
Output:
5 ?- bfs(loc(omaha), loc(chicago), X,D).
false.
What i want:
1 ?- bfs(loc(omaha), loc(chicago), X, D).
X = [loc(omaha), loc(chicago)] ;
D = 1
X = [loc(omaha), loc(denver), loc(los_angeles), loc(chicago)] ;
D = 6
false.
Please anyone help me to solve this problem!
Sorry for my english.
It seems cheapest to define a relation path_distance/2. That is not the most elegant way,
but it should serve your purpose:
bfs(A,B,Path,D) :-
bfs(A,B,Path),
path_distance(Path,D).
path_distance([_], 0).
path_distance([A,B|Cs], S1) :-
move(A,B,D),
path_distance([B|Cs],S2),
S1 is S2+D.
You might also reconsider bfs/3 a bit. The query
?- bfs(A,B, Path).
Gives rather odd results.
Both move/2 and move/3 are now used. Thus:
move(A,B) :-
move(A,B,_).
move(loc(omaha), loc(chicago),1).
move(loc(omaha), loc(denver),2).
move(loc(chicago), loc(denver),1).
move(loc(chicago), loc(los_angeles),2).
move(loc(chicago), loc(omaha),1).
move(loc(denver), loc(los_angeles),2).
move(loc(denver), loc(omaha),1).
move(loc(los_angeles), loc(chicago),2).
move(loc(los_angeles), loc(denver),3).

How can you add (say a vectors name) to an object of type 'formula' within a function?

This is a very trimmed down version of what I want to do, I can't paste my exact problem cause the code is too long and complex but I think this gets at the root of issue. Thanks to Josh's answer to this question How do you code an R function so that it 'knows' to look in 'data' for the variables in other arguments? I'm part way there.
example <- function(model, xvar3=NULL, xvar4=NULL, data){
print(class(model))
#xvar3 <- eval(substitute(xvar3), envir=data, enclos=parent.frame())
#xvar4 <- eval(substitute(xvar4), envir=data, enclos=parent.frame())
print(class(xvar3))
xvar5 <- xvar4^2
mod <- glm( model + xvar3 + xvar5, data=data)
return(mod)
}
example(mpg ~ cyl, hp, wt, data=mtcars)
This fails. If you remove the comments (based on help from previous question) it solves the problem of 'finding' hp and wt. 'model' is of class formula and I would like that to become 'mpg ~ cyl + xvar3 + xvar5' so that the glm will run. But I can't seem to be able to add them to the formula.
I've been toying around with 'call' classes and further with 'eval', and 'as.formula' with variations of 'paste' and 'noquote' etc but can't see to get it to stick.
Here's one way. The trick I used is to create a new formula based on the given one + the two extra variables. I then did a trick with the environment of the formula so that both xvar3/xvar5 AND any variables local to the caller can be used.
glm will always look in the formula's environment AND in the data for variables (and nowhere else!). That's why the formula environment must the manipulated a bit in this case: it contains xvar3 and xvar5, and the parent environment is set to the original formula's environment so that it is also searched for variables (foo in the last example)...
example <- function(model, xvar3=NULL, xvar4=NULL, data){
e <- new.env(parent=environment(model))
e$xvar3 <- eval(substitute(xvar3), envir=data, enclos=parent.frame())
e$xvar4 <- eval(substitute(xvar4), envir=data, enclos=parent.frame())
e$xvar5 <- e$xvar4^2
model <- update(model, . ~ . + xvar3 + xvar5)
environment(model) <- e
mod <- glm(model, data=data)
return(mod)
}
example(mpg ~ cyl, hp, wt, data=mtcars)
# Using a local variable should work too:
doit <- function(d) {
foo <- d$cyl+1
example(mpg ~ foo, hp, wt, data=d)
}
doit(mtcars)
Here's how I'd do it:
add_vars <- function(model, xvar3=NULL, xvar4=NULL, data){
# Capture the unevalated calls to xvar3 and xvar4
xvar3 <- substitute(xvar3)
xvar4 <- substitute(xvar4)
# Use substitute to create the correct formula to supply to update
update_f <- eval(substitute(. ~ . + xvar3 + I(xvar4 ^ 2),
list(xvar3 = xvar3, xvar4 = xvar4)))
# Modify the original formula string
update(model, update_f)
}
add_vars(mpg ~ cyl, hp, wt)
# mpg ~ cyl + hp + I(wt^2)
Another option for this (from a colleague):
example <- function(model, xvar3=NULL, xvar4=NULL, data){
data$xvar3 <- eval(substitute(xvar3), envir=data, enclos=parent.frame())
data$xvar4 <- eval(substitute(xvar4), envir=data, enclos=parent.frame())
data$xvar5 <- data$xvar4^2
model <- as.formula(paste(model[2], paste(model[3], "xvar4","xvar5", sep="+"), sep="~"))
mod <- glm(model, data=data)
return(mod)
}
example(mpg ~ cyl, hp, wt, data=mtcars)
I like this it's quite clean.