This feels like a silly question, but I'm stumped. I'm trying to use Frama-C Sodium and Why3 0.86.1 (both installed via OPAM) to prove some simple properties. Consider this program (toy.c):
int main(void) {
char *hello = "hello world!";
/*# assert \valid_read(hello+(0..11)); */
return 0;
}
I want to prove this assertion using the Frama-C GUI and Why3. So I run frama-c-gui toy.c, select "Why3 (ide)" as the prover and run "Prove function annotations by WP" on the main function. (Alternatively: I navigate to the "WP goals" tab and run the Why3 IDE from there.) Why3 appears, I call the prover of my choice to turn everything green, save the session and quit Why3, and then nothing happens in the Frama-C GUI: The property is still marked orange/"tried to verify but could not decide".
How do I tell Frama-C to actually use the proofs produced by Why3? The proofs themselves are definitely there: If I open Why3 again, everything is still green, so the session was saved properly. Also, Frama-C is aware that something has happened: While the Why3 IDE is open, a little cogwheel symbol is visible in the WP goals tab, and it disappears when I close Why3.
(I realize that this particular property can be proved by Alt-Ergo without involving Why3, but I do need Why3 for harder problems.)
Preliminary answer to myself: It looks like Frama-C's parser for the Why3 session XML file doesn't match the XML generated by Why3 0.86.1. This patch seems to fix this:
diff -ur frama-c-Sodium-20150201/src/wp/why3_session.ml frama-c-Sodium-20150201-hacked/src/wp/why3_session.ml
--- frama-c-Sodium-20150201/src/wp/why3_session.ml 2015-03-06 16:28:27.000000000 +0100
+++ frama-c-Sodium-20150201-hacked/src/wp/why3_session.ml 2015-09-17 21:35:30.717409735 +0200
## -160,6 +160,20 ##
let name = string_attribute "name" elt in
name
+let load_result parent_goal r =
+ match r.Xml.name with
+ | "result" ->
+ let status = string_attribute "status" r in
+ assert (parent_goal.goal_verified = false);
+ parent_goal.goal_verified <- (status = "valid")
+ | _ -> ()
+
+let load_proof parent p =
+ match p.Xml.name with
+ | "proof" ->
+ List.iter (load_result parent) p.Xml.elements
+ | _ -> ()
+
let rec load_goal parent g =
match g.Xml.name with
| "goal" ->
## -168,7 +182,9 ##
let mg =
raw_add_no_task parent gname
in
- mg.goal_verified <- verified
+ mg.goal_verified <- verified;
+ (* hack for different(?) session file format *)
+ List.iter (load_proof mg) g.Xml.elements
| "label" -> ()
| s ->
Wp_parameters.debug
No guarantees that this will work for anyone else (or even that it's correct for my own uses, although I do think so).
Any Frama-C developers here, by any chance, who could comment?
Thanks for reporting the bug. The proposed fix seems to work.
However, we would like to integrate more tightly with Why-3 sessions, and import back to Frama-C which prover(s) discharged each proof obligation. Indeed, we will fix the bug during this refactoring.
Related
Since I am an absolute Haskell beginner, but determined to conquer it, I am asking for help again.
using:
fetchData2 = do
conn <- connectSqlite3 "dBase.db"
statement <- prepare conn "SELECT * FROM test WHERE id > 0"
execute statement []
results <- fetchAllRows statement
print results
returns:
[[SqlInt64 3,SqlByteString "Newco"],[SqlInt64 4,SqlByteString "Oldco"],[SqlInt64 5,SqlByteString "Mycom"],[SqlInt64 4,SqlByteString "Oldco"],[SqlInt64 5,SqlByteString "Mycom"]]
Is there a clever way to clean this data into Int and [Char], in other words omitting types SqlInt64 and SqlByteString.
You could define a helper:
fetchRowFromSql :: Convertible SqlValue a => Statement -> IO (Maybe [a])
fetchRowFromSql = fmap (fmap (fmap fromSql)) . fetchRow
The implementation looks a bit daunting, but this is just because we need to drill down under the layered functors as you already noted (first IO, then Maybe and lastly []). This returns something that is convertible from a SqlValue. There are a bunch of these defined already. See e.g. the docs. An example (using -XTypeApplications):
fetchRowFromSql #String :: Statement -> IO (Maybe [String])
I should perhaps add that the documentation mentions that fromSql is unsafe. Meaning that if you try to convert a sql value to an incompatible Haskell value the program will halt.
I had been having issues with python 3.7 for quite some time about very pointless indentations, so I decided to get back to 3.6, specifically repl.it Python 3.6.1, and as I mentioned, the errors are for no good reason whatsoever as far as I can tell, the code is as written below:
from random import randint
import functools
printf = functools.partial(print, end=" ")
defNuc = ['C','A','T','G']
def opNuc():
def create():
nuc = [0]
nucop = [0]
length = randint(11,16)
print (length - 1)
for i in range(1,length):
part = randint(1,4)
for a in range(1,4)
if part == a:
nuc = defNuc[a]
nucOp = defNuc[-a]
if i != length - 1:
printf(nuc[i],i,"-")
else:
print(nuc[i],i)
for i in range (1,length):
if i != length - 1:
printf(nucOp[i],"-")
else:
print(nucop[i])
The error is at line 9, at
def create():
and as for the reason of error, it just says
expected an indented block
Edit:
This was completely my stupidity, don't take the post seriously, will be deleted in 10 minutes.
You never finished the definition of opNuc, so the parser is expecting an indented line to continue the body of that function. Either add a pass statement to provide a trivial body:
def opNuc():
pass
or indent the definition of create if that is supposed to be local to the body of opNuc (unlikely, but possible):
def opNuc():
def create():
...
The problem is that your first function, opNuc, was never finished. I have made this simple mistake many times myself and is very easy to miss. It's easy to fix though, just type pass inside of the opNuc function and it should be fine. Hope I helped!
I am currently learning sml but I have one question that I can not find an answer for. I have googled but still have not found anything.
This is my code:
fun diamond(n) =
if(n=1) then (
print("*")
) else (
print("*")
diamond(n-1)
)
diamond(5);
That does not work. I want the code to show as many * as number n is and I want to do that with recursion, but I don't understand how to do that.
I get an error when I try to run that code. This is the error:
Standard ML of New Jersey v110.78 [built: Thu Aug 20 19:23:18 2015]
[opening a4_p2.sml] a4_p2.sml:8.5-9.17 Error: operator is not a
function [tycon mismatch] operator: unit in expression:
(print "*") diamond /usr/local/bin/sml: Fatal error -- Uncaught exception Error with 0 raised at
../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
Thank you
You can do side effects in ML by using ';'
It will evaluate whatever is before the ';' and discard its result.
fun diamond(n) =
if(n=1)
then (print "*"; 1)
else (print "*"; diamond(n-1));
diamond(5);
The reason for the error is because ML is a strongly typed language that although you don't need to specify types explicitly, it will infer them based on environmental factors at compile time. For this reason, every evaluation of functions, statements like if else need to evaluate to an unambiguous singular type.
If you were allowed to do the following:
if(n=1)
then 1
else print "*";
then the compiler will get a different typing for the then and else branch respectively.
For the then branch the type would be int -> int whereas the type for the else branch would be int -> unit
Such a dichotomy is not allowed under a strongly typed language.
As you need to evaluate to a singular type, you will understand that ML does not support the execution of a block of instructions as we commonly see in other paradigms which transposed to ML naively would render something like this:
....
if(n=1)
then (print "1"
print "2"
)
else (print "3"
diamond(n-1)
)
...
because what type would the then branch evaluate to? int -> unit? Then what about the other print statement? A statement has to return a singular result(even it be a compound) so that would not make sense. What about int -> unit * unit? No problem with that except that syntactically speaking, you failed to communicate a tuple to the compiler.
For this reason, the following WOULD work:
fun diamond(n) =
if(n=1)
then (print "a", 1) /* A tuple of the type unit * int */
else diamond(n-1);
diamond(5);
As in this case you have a function of type int -> unit * int.
So in order to satisfy the requirement of the paradigm of strongly typed functional programming where we strive for building mechanisms that evaluate to one result-type, we thus need to communicate to the compiler that certain statements are to be executed as instructions and are not to be incorporated under the typing of the function under consideration.
For this reason, you use ';' to communicate to the compiler to simply evaluate that statement and discard its result from being incorporated under the type evaluation of the function.
As far as your actual objective is concerned, following is a better way of writing the function, diamond as type int -> string:
fun diamond(n) =
if(n=1)
then "*"
else "*" ^ diamond(n-1);
print( diamond(5) );
The above way is more for debugging purposes.
I've been looking around and can't find examples of this and all of my syntax wrestling skills are failing me. Can someone please tell me how to make this compile?? My ,s ;s or .s are just wrong I guess for defining a nested function...
I'm aware there is a function for doing string replaces already so I don't need to implement this, but I'm playing with Erlang trying to pick it up so I'm hand spinning some of the basics I need to use..
replace(Whole,Old,New) ->
OldLen = length(Old),
ReplaceInit = fun(Next, NewWhole) ->
if
lists:prefix(Old, [Next|NewWhole]) -> {_,Rest} = lists:split(OldLen-1, NewWhole), New ++ Rest;
true -> [Next|NewWhole]
end,
lists:foldr(ReplaceInit, [], Whole).
Basically I'm trying to write this haskell (also probably bad but beyond the point):
repl xs ys zs =
foldr replaceInit [] xs
where
ylen = length ys
replaceInit y newxs
| take ylen (y:newxs) == ys = zs ++ drop (ylen-1) newxs
| otherwise = y:newxs
The main problem is that in an if you are only allowed to use guards as tests. Guards are very restricted and, amongst other things, calls to general Erlang functions are not allowed. Irrespective of whether they are part of the OTP release or written by you. The best solution for your function is to use case instead of if. For example:
replace(Whole,Old,New) ->
OldLen = length(Old),
ReplaceInit = fun (Next, NewWhole) ->
case lists:prefix(Old, [Next|NewWhole]) of
true ->
{_,Rest} = lists:split(OldLen-1, NewWhole),
New ++ Rest;
false -> [Next|NewWhole]
end
end,
lists:foldr(ReplaceInit, [], Whole).
Because of this if is not used that often in Erlang. See about if and about guards in the Erlang documentation.
My code for display all days in this year.
I don't understand why if NewSec =< EndSec -> init:stop() end did not execute the first time in run_calendar?
I expect init:stop() could be executed first time but it is not.
What is wrong?
Code:
-module(cal).
-export([main/0]).
main() ->
StartSec = calendar:datetime_to_gregorian_seconds({{2009,1,1},{0,0,0}}),
EndSec = calendar:datetime_to_gregorian_seconds({{2009,12,31},{0,0,0}}),
run_calendar(StartSec,EndSec).
run_calendar(CurSec, EndSec) ->
{Date,_Time} = calendar:gregorian_seconds_to_datetime(CurSec),
io:format("~p~n", [Date]),
NewSec = CurSec + 60*60*24,
if NewSec =< EndSec -> init:stop() end,
run_calendar(NewSec, EndSec).
Result:
wk# erlc cal.erl
wk# erl -noshell -s cal main
{2009,1,1}
{2009,1,2}
{2009,1,3}
{2009,1,4}
{2009,1,5}
...
{2009,12,22}
{2009,12,23}
{2009,12,24}
{2009,12,25}
{2009,12,26}
{2009,12,27}
{2009,12,28}
{2009,12,29}
{2009,12,30}
{2009,12,31}
wk#
I believe that init:stop() is an asynchronous process that will attempt to shut down the runtime smoothly. According to the docs, "All applications are taken down smoothly, all code is unloaded, and all ports are closed before the system terminates."
It probably takes a while to actually stop, because you have an actively running process. If you change "init:stop()" to "exit(stop)", it will terminate immediately:
3> cal:main().
{2009,1,1}
** exception exit: stop
in function cal:run_calendar/2
Init:stop is asynchronous and it will take time to quit. An alternate way would be to wrap up the test in the call itself and use pattern matching to terminate the loop:
-module(cal).
-export([main/0]).
main() ->
StartSec = calendar:datetime_to_gregorian_seconds({{2009,1,1},{0,0,0}}),
EndSec = calendar:datetime_to_gregorian_seconds({{2009,12,31},{0,0,0}}),
run_calendar(false, StartSec, EndSec).
run_calendar(true, _StartSec, _EndSec) ->
finished;
run_calendar(false, CurSec, EndSec) ->
{Date,_Time} = calendar:gregorian_seconds_to_datetime(CurSec),
io:format("~p~n", [Date]),
NewSec = CurSec + 60*60*24,
run_calendar(NewSec =< EndSec, NewSec, EndSec).
(or something similar, hopefully you get the idea)
You have a mistake in your if statement
You said
if NewSec =< EndSec -> init:stop() end,
This is incorrect. You have to write something like:
if
A =< B -> do something ...;
true -> do something else
end
The if syntax is
if
Condition1 -> Actions1;
Condition2 -> Actions2;
...
end
One of these conditions must always be true.
Why is this?
Erlang is a functional language, not a statement language. In an functional
language every expression must have a value. if is an expression, so it must have a value.
The value of (if 2 > 1 -> 3 end) is 3 but what is the value of
(if 1 > 2 -> 3 end) - answer it has no value - but it must have a value
everything must have a value.
In a statement language everything is evaluated for its side effect -so this would
be a valid construction.
In Erlang you will generate an exception.
So your code generates an exception - which you don't trap so you don't see it and
init:stop() never gets called ...