Commit 3a7968f8 authored by erwan's avatar erwan
Browse files

Add a --replay mode to lutin that use the lastly generated seed

Print the seed when used from a RdbgPlugin
parent 7fc81ddc
OASISFormat: 0.4
Name: Lutin
Version: 2.22
Version: 2.23
Authors: Erwan Jahier
Maintainers: erwan.jahier@imag.fr
License: PROP
......
......@@ -69,12 +69,13 @@ $(MAIN)-html.org: html-preambule.org main.org
rm -f $(MAIN)-html.org
echo "# XXX Edite plutot le main.org patate ! " > $(MAIN)-html.org
cat html-preambule.org main.org | sed -e 's/\\pause//g' \
| grep -v "\[Answer\]" \
| sed -e 's/^html://g'\
| sed -e 's/^html\.//g'\
| sed -e 's/:B_note://g' >> $(MAIN)-html.org
chmod u-w $(MAIN)-html.org
# | grep -v "\[Answer\]" \
$(MAIN)-pdf.org: pdf-preambule.org main.org
rm -f $(MAIN)-pdf.org
echo "# XXX Edite plutot le main.org patate ! " > $(MAIN)-pdf.org
......
......@@ -7,7 +7,7 @@
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="title" content="A Lutin Tutorial"/>
<meta name="generator" content="Org-mode"/>
<meta name="generated" content="2017-03-22 14:17:49 CET"/>
<meta name="generated" content="2017-04-13 11:53:23 CEST"/>
<meta name="author" content="Erwan Jahier"/>
<meta name="description" content=""/>
<meta name="keywords" content=""/>
......@@ -251,12 +251,12 @@ org_html_manager.setup(); // activate after the parameters are set
</li>
<li><a href="#sec-3-16">3.16 Exceptions (cont)</a></li>
<li><a href="#sec-3-17">3.17 Exceptions (cont)</a></li>
<li><a href="#sec-3-18">3.18 About exceptions</a></li>
<li><a href="#sec-3-19">3.19 Parallelism: <code>&amp;&gt;</code></a></li>
<li><a href="#sec-3-20">3.20 Combinators (again)</a>
<li><a href="#sec-3-18">3.18 Combinators (again)</a>
<ul>
<li><a href="#sec-3-20-1">3.20.1 Trace Combinators</a></li>
</ul></li>
<li><a href="#sec-3-18-1">3.18.1 Trace Combinators</a></li>
</ul>
</li>
<li><a href="#sec-3-19">3.19 Parallelism: <code>&amp;&gt;</code></a></li>
</ul>
</li>
<li><a href="#sec-4">4 The <code>run</code> operator</a>
......@@ -649,6 +649,9 @@ obtain quieter sequence, one can use the <code>-quiet</code> option (<code>-q</c
<pre class="src src-sh">&lt;prompt&gt; luciole-rif lutin incr.lut
</pre>
......@@ -2031,24 +2034,64 @@ st2. If the "do" part is omitted, the statement terminates normally.
<p>
Note that the 43 value is generated iff i=43.
</p>
</div>
</div>
<div id="outline-container-3-18" class="outline-3">
<h3 id="sec-3-18"><span class="section-number-3">3.18</span> About exceptions</h3>
<h3 id="sec-3-18"><span class="section-number-3">3.18</span> Combinators (again)</h3>
<div class="outline-text-3" id="text-3-18">
<ul>
<li>Very powerful mechanism
</li>
<li>Can be used to build complex trace operators
</li>
<li>But should they used to program?
</li>
</ul>
</div>
<div id="outline-container-3-18-1" class="outline-4">
<h4 id="sec-3-18-1"><span class="section-number-4">3.18.1</span> Trace Combinators</h4>
<div class="outline-text-4" id="text-3-18-1">
<pre class="src src-lutin"><span style="color: #F0DFAF; font-weight: bold;">let</span> myloop(t:<span style="color: #7CB8BB;">trace</span>) : <span style="color: #7CB8BB;">trace</span> = <span style="color: #DCDCCC; font-weight: bold;">loop</span> <span style="color: #DCDCCC; font-weight: bold;">try</span> <span style="color: #DCDCCC; font-weight: bold;">loop</span> t
</pre>
<p>
Here we restart the loop from the beginning whenever we are
blocked somewhere inside <code>t</code>. (<a href="myloop.lut">myloop.lut</a>)
</p>
<pre class="src src-lutin"><span style="color: #F0DFAF; font-weight: bold;">let</span> myloop(t:<span style="color: #7CB8BB;">trace</span>) : <span style="color: #7CB8BB;">trace</span> = <span style="color: #DCDCCC; font-weight: bold;">loop</span> <span style="color: #DCDCCC; font-weight: bold;">try</span> <span style="color: #DCDCCC; font-weight: bold;">loop</span> t
<span style="color: #F0DFAF; font-weight: bold;">node</span> use_myloop(reset:<span style="color: #7CB8BB;">bool</span>) <span style="color: #F0DFAF; font-weight: bold;">returns</span>(x:<span style="color: #7CB8BB;">int</span>) =
myloop(
x = 0 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
<span style="color: #F0DFAF; font-weight: bold;">assert</span> <span style="color: #BFEBBF;">not</span> reset <span style="color: #F0DFAF; font-weight: bold;">in</span>
x = 1 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
x = 2 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
x = 3 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
x = 4
)
</pre>
<pre class="src src-sh">&lt;prompt&gt; luciole-rif lutin myloop.lut
</pre>
<p>
Each step you set reset to <code>true</code>, the output equals to <code>0</code>.
</p>
</div>
</div>
</div>
......@@ -2062,8 +2105,8 @@ Note that the 43 value is generated iff i=43.
<pre class="src src-lutin"><span style="color: #F0DFAF; font-weight: bold;">node</span> n() <span style="color: #F0DFAF; font-weight: bold;">returns</span>(x,y:<span style="color: #7CB8BB;">int</span>) = {
<span style="color: #DCDCCC; font-weight: bold;">loop</span> { -10 &lt; x <span style="color: #BFEBBF;">and</span> x &lt; 10 }
<pre class="src src-lutin"><span style="color: #F0DFAF; font-weight: bold;">node</span> n(i:<span style="color: #7CB8BB;">int</span>) <span style="color: #F0DFAF; font-weight: bold;">returns</span>(x,y:<span style="color: #7CB8BB;">int</span>) = {
<span style="color: #DCDCCC; font-weight: bold;">loop</span> { -i &lt; x <span style="color: #BFEBBF;">and</span> x &lt; i }
&amp;&gt; y = 0 <span style="color: #DCDCCC; font-weight: bold;">fby</span> <span style="color: #DCDCCC; font-weight: bold;">loop</span> { y = <span style="color: #BFEBBF;">pre</span> x } }
</pre>
......@@ -2107,65 +2150,10 @@ nota bene: this construct can be expensive because of:
<p>
Use the <code>run/in</code> construct instead if performance is a problem.
</p>
</div>
</div>
<div id="outline-container-3-20" class="outline-3">
<h3 id="sec-3-20"><span class="section-number-3">3.20</span> Combinators (again)</h3>
<div class="outline-text-3" id="text-3-20">
</div>
<div id="outline-container-3-20-1" class="outline-4">
<h4 id="sec-3-20-1"><span class="section-number-4">3.20.1</span> Trace Combinators</h4>
<div class="outline-text-4" id="text-3-20-1">
<pre class="src src-lutin"><span style="color: #F0DFAF; font-weight: bold;">let</span> myloop(t:<span style="color: #7CB8BB;">trace</span>) : <span style="color: #7CB8BB;">trace</span> = <span style="color: #DCDCCC; font-weight: bold;">loop</span> <span style="color: #DCDCCC; font-weight: bold;">try</span> <span style="color: #DCDCCC; font-weight: bold;">loop</span> t
</pre>
<p>
Here we restart the loop from the beginning whenever we are
blocked somewhere inside <code>t</code>. (<a href="myloop.lut">myloop.lut</a>)
</p>
<pre class="src src-lutin"><span style="color: #F0DFAF; font-weight: bold;">let</span> myloop(t:<span style="color: #7CB8BB;">trace</span>) : <span style="color: #7CB8BB;">trace</span> = <span style="color: #DCDCCC; font-weight: bold;">loop</span> <span style="color: #DCDCCC; font-weight: bold;">try</span> <span style="color: #DCDCCC; font-weight: bold;">loop</span> t
<span style="color: #F0DFAF; font-weight: bold;">node</span> use_myloop(reset:<span style="color: #7CB8BB;">bool</span>) <span style="color: #F0DFAF; font-weight: bold;">returns</span>(x:<span style="color: #7CB8BB;">int</span>) =
myloop(
x = 0 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
<span style="color: #F0DFAF; font-weight: bold;">assert</span> <span style="color: #BFEBBF;">not</span> reset <span style="color: #F0DFAF; font-weight: bold;">in</span>
x = 1 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
x = 2 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
x = 3 <span style="color: #DCDCCC; font-weight: bold;">fby</span>
x = 4
)
</pre>
<pre class="src src-sh">&lt;prompt&gt; luciole-rif lutin myloop.lut
</pre>
<p>
Each step you set reset to <code>true</code>, the output equals to <code>0</code>.
</p>
</div>
</div>
</div>
......
......@@ -263,6 +263,10 @@ obtain quieter sequence, one can use the ~-quiet~ option (~-q~ for short):
xterm -e "luciole-rif lutin -rif incr.lut"
#+end_src
# \href{run:./sh/incr-demo.sh}{\texttt{\color{DarkGreen}{ desktop XXX}}}
{{{run(./sh/incr-luciole-demo.sh, luciole-rif lutin incr.lut)}}}
......@@ -1048,10 +1052,29 @@ st2. If the "do" part is omitted, the statement terminates normally.
Note that the 43 value is generated iff i=43.
** About exceptions
- Very powerful mechanism
- Can be used to build complex trace operators
- But should they used to program?
** Combinators (again)
*** Trace Combinators
#+begin_src lutin
let myloop(t:trace) : trace = loop try loop t
#+end_src
Here we restart the loop from the beginning whenever we are
blocked somewhere inside =t=. ([[file:myloop.lut][myloop.lut]])
#+INCLUDE: "./myloop.lut" src lutin
#+begin_src sh :tangle sh/myloop-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "luciole-rif lutin myloop.lut"
#+end_src
{{{run(./sh/myloop-demo.sh, luciole-rif lutin myloop.lut)}}}
Each step you set reset to =true=, the output equals to =0=.
** Parallelism: =&>=
......@@ -1088,27 +1111,6 @@ nota bene: this construct can be expensive because of:
Use the =run/in= construct instead if performance is a problem.
** Combinators (again)
*** Trace Combinators
#+begin_src lutin
let myloop(t:trace) : trace = loop try loop t
#+end_src
Here we restart the loop from the beginning whenever we are
blocked somewhere inside =t=. ([[file:myloop.lut][myloop.lut]])
#+INCLUDE: "./myloop.lut" src lutin
#+begin_src sh :tangle sh/myloop-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "luciole-rif lutin myloop.lut"
#+end_src
{{{run(./sh/myloop-demo.sh, luciole-rif lutin myloop.lut)}}}
Each step you set reset to =true=, the output equals to =0=.
# ** Parallelism *)
......
......@@ -160,6 +160,10 @@ Let's consider the following Lutin program named [[./incr.lut][incr.lut]].
xterm -e "luciole-rif lutin -rif incr.lut"
#+end_src
# \href{run:./sh/incr-demo.sh}{\texttt{\color{DarkGreen}{ desktop XXX}}}
{{{run(./sh/incr-luciole-demo.sh, luciole-rif lutin incr.lut)}}}
......@@ -598,10 +602,26 @@ st2. If the "do" part is omitted, the statement terminates normally.
Note that the 43 value is generated iff i=43.
** About exceptions
- Very powerful mechanism
- Can be used to build complex trace operators
- But should they used to program?
** Combinators (again)
*** Trace Combinators
#+begin_src lutin
let myloop(t:trace) : trace = loop try loop t
#+end_src
Here we restart the loop from the beginning whenever we are
blocked somewhere inside =t=. ([[file:myloop.lut][myloop.lut]])
#+INCLUDE: "./myloop.lut" src lutin
#+begin_src sh :tangle sh/myloop-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "luciole-rif lutin myloop.lut"
#+end_src
{{{run(./sh/myloop-demo.sh, luciole-rif lutin myloop.lut)}}}
** Parallelism: =&>=
......@@ -624,24 +644,6 @@ nota bene: this construct can be expensive because of:
Use the =run/in= construct instead if performance is a problem.
** Combinators (again)
*** Trace Combinators
#+begin_src lutin
let myloop(t:trace) : trace = loop try loop t
#+end_src
Here we restart the loop from the beginning whenever we are
blocked somewhere inside =t=. ([[file:myloop.lut][myloop.lut]])
#+INCLUDE: "./myloop.lut" src lutin
#+begin_src sh :tangle sh/myloop-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "luciole-rif lutin myloop.lut"
#+end_src
{{{run(./sh/myloop-demo.sh, luciole-rif lutin myloop.lut)}}}
# ** Parallelism *)
......
......@@ -216,6 +216,10 @@ html.
xterm -e "luciole-rif lutin -rif incr.lut"
#+end_src
# \href{run:./sh/incr-demo.sh}{\texttt{\color{DarkGreen}{ desktop XXX}}}
{{{run(./sh/incr-luciole-demo.sh, luciole-rif lutin incr.lut)}}}
html:
......@@ -1005,10 +1009,29 @@ html.
Note that the 43 value is generated iff i=43.
** About exceptions
- Very powerful mechanism
- Can be used to build complex trace operators
- But should they used to program?
** Combinators (again)
*** Trace Combinators
#+begin_src lutin
let myloop(t:trace) : trace = loop try loop t
#+end_src
Here we restart the loop from the beginning whenever we are
blocked somewhere inside =t=. ([[file:myloop.lut][myloop.lut]])
#+INCLUDE: "./myloop.lut" src lutin
#+begin_src sh :tangle sh/myloop-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "luciole-rif lutin myloop.lut"
#+end_src
{{{run(./sh/myloop-demo.sh, luciole-rif lutin myloop.lut)}}}
html:
Each step you set reset to =true=, the output equals to =0=.
html.
** Parallelism: =&>=
......@@ -1045,27 +1068,6 @@ nota bene: this construct can be expensive because of:
Use the =run/in= construct instead if performance is a problem.
** Combinators (again)
*** Trace Combinators
#+begin_src lutin
let myloop(t:trace) : trace = loop try loop t
#+end_src
Here we restart the loop from the beginning whenever we are
blocked somewhere inside =t=. ([[file:myloop.lut][myloop.lut]])
#+INCLUDE: "./myloop.lut" src lutin
#+begin_src sh :tangle sh/myloop-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "luciole-rif lutin myloop.lut"
#+end_src
{{{run(./sh/myloop-demo.sh, luciole-rif lutin myloop.lut)}}}
html:
Each step you set reset to =true=, the output equals to =0=.
html.
# ** Parallelism *)
......
node n() returns(x,y:int) = {
loop { -10 < x and x < 10 }
node n(i:int) returns(x,y:int) = {
loop { -i < x and x < i }
&> y = 0 fby loop { y = pre x } }
\ No newline at end of file
......@@ -19,8 +19,6 @@ test:test.rif $(EXPDIR)
rm -f test.res && diff -B -u -i -w $(EXPDIR)/test.rif.exp test.rif > test.res
[ ! -s test.res ] && make clean
utest:test.rif
cp test.rif $(EXPDIR)/test.rif.exp ; true
......
......@@ -15,8 +15,7 @@ test.rif:
export GCC="/usr/bin/gcc -fPIC"
$(LURETTE) --test-length 2 --output test.rif0 && \
grep -v "lurette chronogram" test.rif0 | \
grep -v "Rdbg Version" | \
grep -v "This is lurette Version" | grep -v "#seed " | \
grep -v "Version" | grep -v "#seed " | \
grep -v "The execution lasted"| sed -e "s/^M//" > test.rif
test:test.rif $(EXPDIR)
......
(* Time-stamp: <modified the 10/02/2016 (at 14:45) by Erwan Jahier> *)
(* Time-stamp: <modified the 30/03/2017 (at 17:58) by Erwan Jahier> *)
(**********************************************************************************)
type vars = (string * Data.t) list
......@@ -28,6 +28,7 @@ let make argv =
let prog = MainArg.infile opt
and node = MainArg.main_node opt
in
let seed = MainArg.seed opt in
let lut_mach = LutExe.make opt prog node in
let lut_in = List.map var_to_var_pair (LutExe.in_var_list lut_mach) in
let lut_out = List.map var_to_var_pair (LutExe.out_var_list lut_mach) in
......@@ -98,8 +99,15 @@ let make argv =
[]
lut_out
in
let argv_list = Array.to_list argv in
let argv_str = String.concat " " argv_list in
let id =
if List.mem "-seed" argv_list then argv_str else
argv_str ^ " -seed " ^ (string_of_int seed)
in
let version = Printf.sprintf "with lutin Version %s (\"%s\")" Version.str Version.sha in
{
id = String.concat " " (Array.to_list argv);
id = Printf.sprintf "%s (%s)" id version;
inputs = lut_in;
outputs= lut_out;
kill=(fun _ -> ());
......
......@@ -29,6 +29,7 @@ type t = {
mutable _step_mode : Lucky.step_mode;
mutable _load_mem : bool;
mutable _seed : int option;
mutable _reset_seed : bool;
mutable _compute_volume : bool;
mutable _max_steps : int option;
mutable _show_locals :bool;
......@@ -64,6 +65,7 @@ let (make_opt : unit -> t) =
_step_mode = Lucky.StepInside;
_load_mem = false;
_seed = None;
_reset_seed = false;
_compute_volume = false;
_max_steps = None;
_show_locals = false;
......@@ -89,32 +91,61 @@ let set_libs opt libs =
let libs opt = match opt._libs with [] -> None | l -> Some l
let set_precision = Util.change_precision
let seed opt = match opt._seed with
| Some i -> i
| None -> ( Random.self_init (); Random.int 1073741823)
(*******************************************************************************)
(* seeds stuff *)
let set_seed opt s =
(match opt._seed with
(match s with
| Some i ->
Printf.fprintf stderr "The random engine seed is set to %i\n" i;
flush stderr;
| None -> ());
opt._seed <- s
let seed_file_name opt =
Printf.sprintf "%s-%s.seed" (String.concat "-" opt._infile) opt._main_node
(* for --replay *)
let reset_the_seed_to_last opt =
let f = seed_file_name opt in
try
let ic = open_in f in
let seed = int_of_string (input_line ic) in
set_seed opt (Some seed);
true
with _ ->
Printf.eprintf "W: cannot recover the seed in %s\n" f;
flush stderr;
false
let rec seed opt = match opt._seed with
| Some i -> i
| None ->
(* No seed is set:
- in -replay mode, we first try to read the seed in the seed file
- otherwise, we create a random seed and save if into opt, and
into a file for -replay *)
if opt._reset_seed && reset_the_seed_to_last opt then (seed opt) else
let seed = Random.self_init (); Random.int 1073741823 in
let seed_file = seed_file_name opt in
let oc = open_out seed_file in
Printf.fprintf oc "%d\n%s\n" seed (Util.entete "#" "");
flush oc;
close_out oc;
opt._seed <- Some seed;
seed
(* Emulate the event number when not run under rdbg so that we are able
to tell at which event we reached a deadlock
*)
(* let event_nb = ref 0 *)
let event_incr opt =
let seed = seed opt in
let r = Random.int 1073741823 in
opt._event_nb <- opt._event_nb + 1;
(* To make sure everything can be reproduced with and without rdbg *)
Random.full_init [|seed; opt._event_nb|];
(* Printf.fprintf *)
(* stderr "The random engine seed is set with (%i,%i) (%i,%i)\n" *)
(* opt._event_nb seed r (Random.int 1073741823); *)
(* flush stderr; *)
()
()
let (get_event_nb : t -> int) =
......@@ -289,7 +320,7 @@ let (mkoptab : t -> unit) =
))
["call gnuplot-rif to display data (type 'a' in the gnuplot window to refresh it)."]
;
mkopt opt
mkopt opt
["-rif";"-quiet";"-q";"-only-outputs"]
(Arg.Unit(function s -> opt._only_outputs <- true))
["display only outputs on stdout (i.e., behave as a rif input file)"]
......@@ -327,10 +358,15 @@ let (mkoptab : t -> unit) =
(* simu *)
mkopt opt
["--replay";"-r"]
(Arg.Unit(fun () -> opt._reset_seed <- true))
["Use the last generated seed to replay the last run"]
;
mkopt opt
["-seed"]
~arg:" <int>"
(Arg.Int(function i -> opt._seed <- Some i ; ()))
["Set a seed for the pseudo-random generator"]
["Set a seed for the pseudo-random generator (wins over --replay)"]
;
mkopt opt
["-boot"]
......
let str="2.22"
let sha="43f8d5b"
let str="2.23"
let sha="7fc81dd"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment