Commit 43f8d5bc authored by erwan's avatar erwan
Browse files

Rework the lutin tutorial.

parent c7a6f554
OASISFormat: 0.4
Name: Lutin
Version: 2.20
Version: 2.21
Authors: Erwan Jahier
Maintainers: erwan.jahier@imag.fr
License: PROP
......
......@@ -50,6 +50,9 @@ handout: grille.pdf
re :
make handout
x:
xpdf -fullscreen $(MAIN)-pdf.pdf
fig:$(OBJDIR)
make $(FIGPDF)
......@@ -59,10 +62,14 @@ png:$(OBJDIR)
%.pdf: $(OBJDIR)/%.pdf
cp $< $@
$(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
......@@ -204,6 +211,8 @@ $(OBJDIR)/%.noweb: %.org
$(OBJDIR)/%.html: $(OBJDIR)/%.org demarche-it-en.png
cd $(OBJDIR); \
$(EMACS) --visit=$*.org --eval "(load-theme 'zenburn)" --funcall org-export-as-html --eval "(kill-emacs)" -Q
cp $@ /tmp/xxx
cat /tmp/xxx | sed -e 's/<div id=\"postamble\">/<HR><div id=\"postamble\">/g'> $@
# --eval "(setq org-export-headline-levels 2)" \
......
......@@ -54,7 +54,7 @@
(setq auto-mode-alist (cons '("\\.ml\\w?" . tuareg-mode) auto-mode-alist))
(autoload 'tuareg-mode "tuareg" "Major mode for editing Caml code" t)
(setq org-export-html-postamble-format "Last Updated %d. Created by %c")
(autoload 'lustre-mode "lustre" "Edition de code lustre" t)
......@@ -108,3 +108,20 @@
; ("\\section\{%s\}" . "\\section*\{%s\}")
; ("\\subsection\{%s\}" . "\\subsection*\{%s\}")
; ("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}")))
(defvar my-website-html-postamble
"<div class='footer'>
Last updated %C. <br>
Built with %c.
</div>")
(setq org-publish-project-alist
`(("org"
:html-postamble ,my-website-html-postamble)))
(setq org-export-html-auto-postamble 'nil)
(setq org-export-html-postamble "Your postamble here")
(setq org-export-allow-bind-keywords t)
(setq org-export-allow-BIND 1)
extern sin(x: real) : real
let abs(x:real) : real = if x < 0.0 then -x else x
node bizzare() returns (res: real) =
exist x,eps: real in
res = 0.0 and eps = 0.0 fby
loop abs(eps - pre eps) < .02
and x = pre x + 0.5 + pre eps
let between(x, min, max : real) : bool = ((min < x) and (x < max))
node bizzare() returns (x,res: real) =
exist noise: real in
assert between(noise,-0.1, 0.1) in
res = 0.0 and x = 0.0 fby
loop x = pre x + 0.1 + noise
and res = sin(pre x)
#+OPTIONS:toc:2
#+TODO: todo cont | done
#+OPTIONS: \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
......@@ -13,11 +14,17 @@
#+INFOJS_OPT: buttons:t view:info toc: path:http://orgmode.org/org-info.js
#+style: <style type="text/css">pre{background-color: #232323; color: #E6E1DC;}</style>
#+STYLE: <link rel="stylesheet" type="text/css" href="slides.css" />
#+style: <style type="text/css">blockquote{border: 1px solid #CCC; background-color: #E6E1DC; color: #232323;}</style>
#+STYLE: <link rel="stylesheet" type="text/css" href="worg-zenburn.css" />
#+OPTIONS: html-postamble:nil
#+MACRO: runpdf
#+MACRO: run #+begin_src sh \\n<prompt> $2 \n#+end_src
#+MACRO: nprun $2
......@@ -26,13 +33,13 @@
#+MACRO: begin_html
#+MACRO: end_html
#+MACRO: onlyhtml $1
#+MACRO: htmlonly $1
#+MACRO: onlypdf
#+MACRO: pdfonly
#+MACRO: pdfhtml $2
#+BIND: org-export-html-postamble "<div class='footer'> Built with %c. </div>"
#+AUTHOR: Erwan Jahier
#+TITLE: A Lutin Tutorial
......
This diff is collapsed.
# XXX Edite plutot le main.org patate !
#+OPTIONS:toc:2
#+TODO: todo cont | done
#+OPTIONS: \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
......@@ -14,11 +15,17 @@
#+INFOJS_OPT: buttons:t view:info toc: path:http://orgmode.org/org-info.js
#+style: <style type="text/css">pre{background-color: #232323; color: #E6E1DC;}</style>
#+STYLE: <link rel="stylesheet" type="text/css" href="slides.css" />
#+style: <style type="text/css">blockquote{border: 1px solid #CCC; background-color: #E6E1DC; color: #232323;}</style>
#+STYLE: <link rel="stylesheet" type="text/css" href="worg-zenburn.css" />
#+OPTIONS: html-postamble:nil
#+MACRO: runpdf
#+MACRO: run #+begin_src sh \\n<prompt> $2 \n#+end_src
#+MACRO: nprun $2
......@@ -27,13 +34,13 @@
#+MACRO: begin_html
#+MACRO: end_html
#+MACRO: onlyhtml $1
#+MACRO: htmlonly $1
#+MACRO: onlypdf
#+MACRO: pdfonly
#+MACRO: pdfhtml $2
#+BIND: org-export-html-postamble "<div class='footer'> Built with %c. </div>"
#+AUTHOR: Erwan Jahier
#+TITLE: A Lutin Tutorial
......@@ -66,9 +73,18 @@ non-deterministic reactive machines.
- No topological sort of equations
** In order to run this tutorial
You first need to install opam. For instance, on debian-like boxes do
#+BEGIN_SRC sh
sudo apt-get install opam
opam init ; opam switch 4.04.0 ; eval `opam config env`
#+END_SRC
and then do:
#+BEGIN_SRC sh
sudo apt-get install opam gnuplot tcl
sudo apt-get install gnuplot tcl
opam repo add verimag-sync-repo "http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/opam-repository"
opam update
opam install lutin
......@@ -79,8 +95,18 @@ http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lustre-v4/distrib/index.html
{{{pdfhtml(
- [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/lutin-tuto-html.html][Link to an htlm version of those slides with exercises]]
Basically, to get all the tools necessary to run this tutorial accessible
from ypour path, you should have something like that in your =.bashrc= :
#+BEGIN_SRC sh
# for lutin, gnuplot-rif, luciole-rif
. ~/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true
# for simec (luciole), sim2chrogtk
export LUSTRE_INSTALL=~/lustre-v4-xxx
source $LUSTRE_INSTALL/setenv.sh
#+END_SRC
** In order to run the demo from the pdf slides
......@@ -94,27 +120,29 @@ urlCommand "browserhook.sh '%s'"
- Download the bash script [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/sh/browserhook.sh][browserhook.sh (link to the script)]]
- Make it executable and available from your path
- Then the green link should launch the corresponding shell command,
- A [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/lutin-tuto-handout.pdf][pdf version of this tutorial]]
)}}}
- A [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/doc/lutin-tuto/lutin-tuto-handout.pdf][pdf version of this tutorial]]
{{{runpdf(./sh/echo-go.sh, echo "go!")}}}
* Execute Lutin programs
# \includegraphics[width=10cm]{file:lutin-luciole.png}
** Stimulate Lutin programs
{{{onlyhtml(Before learning the [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/doc/lutin-man.pdf][language]], let's have a look at a
couple of tools that will allow us to play with our Lutin programs.
)}}}
Before learning the [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/doc/lutin-man.pdf][language]], let's have a look at a
couple of tools that will allow us to play with our Lutin programs.
The Lutin program command-line interpreter is a stand-alone
executable named ~lutin~. You should be able to find it [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/download.html][There]].
From now on, we suppose that ~lutin~ is accessible from your path.
The Lutin program command-line interpreter is a stand-alone
executable named ~lutin~. This program ougth to be
accessible from your path if you have followed the instr
......@@ -164,7 +192,8 @@ q# bye!
*** A program with no input
Consider the [[./one.lut][one.lut]] program:
# Consider the [[./one.lut][one.lut]] program:
#+INCLUDE: "./one.lut" src lutin
#+begin_src sh :tangle sh/one-demo.sh :exports none :noweb yes
......@@ -192,10 +221,15 @@ Consider the [[./one.lut][one.lut]] program:
#+END_SRC
A Lutin program might have no input at all. In such a case, it might
be to helpful to know that the ~--max-steps~ (~-l~ for short) allows
one to set a maximum number of simulation steps to perform. Try
launch ~lutin one.lut -l 5~ on [[./one.lut][one.lut]]:
one to set a maximum number of simulation steps to perform.
#+ATTR_HTML: :border 2 :rules all :frame border :class striped table-striped
#+BEGIN_QUOTE
*Question* :
Try to launch ~lutin one.lut -l 5~ on one.lut
#+END_QUOTE
......@@ -223,7 +257,7 @@ obtain quieter sequence, one can use the ~-quiet~ option (~-q~ for short):
** Stimulate Lutin programs graphically with ~luciole~
#+INCLUDE: "./N.lut" src lutin
#+INCLUDE: "./incr.lut" src lutin
#+begin_src sh :tangle sh/incr-luciole-demo.sh :exports none :noweb yes
xterm -e "luciole-rif lutin -rif incr.lut"
......@@ -320,7 +354,7 @@ cat rdbg.rif | sim2chrogtk -ecran > /dev/null
)}}}
{{{htmlonly([[./png/chronogrammes.png]])}}}
{{{htmlonly([[./png/lurette-sim2chro.png]])}}}
......@@ -335,14 +369,13 @@ file:jpg/geluck-echec.jpg)}}}
- And now I'm at peace
* The Language
* The Lutin Language
{{{htmlonly(
The aim of this tutorial is to be complementary to the [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/doc/lutin-man.pdf][Reference
Manual]]. The idea here is to present the language via examples. If
you want precise definitions of the various language statements
syntax and semantics, please refer to the [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/doc/lutin-man.pdf][Reference Manual]].)}}}
syntax and semantics, please refer to the [[http://www-verimag.imag.fr/DIST-TOOLS/SYNCHRONE/lurette/doc/lutin-man.pdf][Reference Manual]].
** Back to programs of Section 1
......@@ -350,17 +383,18 @@ syntax and semantics, please refer to the [[http://www-verimag.imag.fr/DIST-TOOL
- Let's come back to the Lutin programs mentioned so far.
#+INCLUDE: "./incr.lut" src lutin
*** We said said That the first one, [[file:incr.lut][incr.lut]] increments its input by one. Let's explain why.
*** We said said that the first one, [[file:incr.lut][incr.lut]] increments its input by one. Let's explain why.
- Those programs illustrate the 2 kinds of expressions we have in Lutin.
- *constraint expressions* (~y = x+1~) that asserts facts outputs
variables.
- *trace expression* (~loop~ <te>) that allows one to combine
constraint expressions.
- *constraint expressions* (~y = x+1~) that asserts facts outputs
variables.
- *trace expression* (~loop~ <te>) that allows one to combine
constraint expressions.
{{{onlyhtml(
The behavior of a /satisfiable/ constraint expression is to produce
as outputs one of its possible solutions during one logical instant
(i.e., during one /step/). The behavior of the trace expression
......@@ -404,9 +438,18 @@ from the others. However, it is possible to set variables previous
values at declarations time. The program [[file:N2.lut][N2.lut]] below behaves
exactly as [[file:N.lut][N.lut]]:
#+INCLUDE: "./N2.lut" src lutin
)}}}
#+INCLUDE: "./N2.lut" src lutin
#+BEGIN_QUOTE
*Question*:
Write a Lutin program with no input that generates one output =y=
with the following sequence of values : 1 3 5 7 9 ...
#+END_QUOTE
#+BEGIN_QUOTE
*Question*:
Write a Lutin program with no input that generates one output =y=
with the following sequence of values : 1 2 4 8 16 32 ...
#+END_QUOTE
......@@ -444,7 +487,7 @@ input and an output variables). As a matter of fact, writing
non-deterministic is even simpler: you just need to write no
constraint at all! Indeed, observe how this [[file:trivial.lut][trivial.lut]] program
behaves:
......@@ -475,7 +518,6 @@ as done in [[file:trivial2.lut][trivial2.lut]]:
#+end_example
** Non deterministic programs (cont)
As you've just seen, a Lutin program is by default chaotic. To
make it less chaotic, one has to add constraints which narrow the set
......@@ -551,17 +593,18 @@ Lutin constraints can only be linear, which means that the set of
#+end_example
- [[file:range2.lut][Question]]: write a simpler program than [[file:range.lut][range.lut]] that behaves
#+BEGIN_QUOTE
*Question*: write a simpler program than [[file:range.lut][range.lut]] that behaves
the same.
#+END_QUOTE
{{{onlyhtml([[file:range2.lut][Answer]])}}}
** Non deterministic programs (cont)
- A 3D non-deterministic example
{{{onlyhtml(Of course constraints can be more complex, as in [[file:polyhedron.lut][polyhedron.lut]]:)}}}
{{{onlyhtml(Of course constraints can be more complex as in [[file:polyhedron.lut][polyhedron.lut]]:)}}}
#+INCLUDE: "./polyhedron.lut" src lutin
......@@ -619,8 +662,10 @@ file:./png/Screenshot-Gnuplot-se.png
** Non deterministic programs (cont)
Constraint may also depend on inputs. Try to play the
[[file:range-bis.lut][range-bis.lut]] program:
Constraint may also depend on inputs.
Try to play the [[file:range-bis.lut][range-bis.lut]] program:
#+INCLUDE: "./range-bis.lut" src lutin
#+begin_src sh :tangle sh/range-bis-demo.sh :exports none :noweb yes
......@@ -631,18 +676,18 @@ Constraint may also depend on inputs. Try to play the
The major difference with [[file:range.lut][range.lut]] is that the constraint
expression ~0 <= y and y <= i~ is not always satisfiable. If one
enters a negative value, that program will stop.
Question: modify the [[file:range-bis.lut][range-bis.lut]] program (with the concept
#+BEGIN_QUOTE
*Question:* modify the [[file:range-bis.lut][range-bis.lut]] program (with the concept
introduced so far) so that when a negative input is provided, it
returns -1.
[[file:answer1.lut][Answer]]
#+END_QUOTE
** Controlled non-determinism: the choice operator
......@@ -687,7 +732,7 @@ weight directives (=:3=):
In [[file:choice2.lut][choice2.lut]], ~x=42~ is chosen with a probability of 3/4.
#+begin_src sh :tangle sh/choice2-demo.sh :exports none :noweb yes
xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "lutin -l 1000 -q choice2.lut | grep 42 | wc -l";
#+end_src
......@@ -736,7 +781,6 @@ xterm -hold -fa "Liberation Mono:size=15:antialias=false" -e "lutin -quiet letd
{{{run(./sh/letdef-demo.sh, lutin -quiet letdef.lut)}}}
** A parametric combinator
The [[file:combinator.lut][combinator.lut]] program illustrates the use of parametric combinators:
......@@ -744,9 +788,8 @@ The [[file:combinator.lut][combinator.lut]] program illustrates the use of param
#+INCLUDE: "./combinator.lut" src lutin
#+begin_src sh :tangle sh/combinator-demo.sh :exports none :noweb yes
lutin -l 100 combinator.lut -o walk.rif ;
gnuplot-rif walk.rif
rm walk.rif
rm -f walk.rif ; lutin -l 100 combinator.lut -o walk.rif && \
gnuplot-rif walk.rif
#+end_src
{{{run(./sh/combinator-demo.sh, lutin -l 100 combinator.lut -o walk.rif ; gnuplot-rif walk.rif)}}}
......@@ -754,6 +797,10 @@ rm walk.rif
file:png/Screenshot-walk.png
#+BEGIN_QUOTE
*Question:* Write such a randow walk for a real variable
#+END_QUOTE
** Combinators (cont)
......@@ -786,24 +833,24 @@ the [[file:up-and-down.lut][up-and-down.lut]] program:
Question: what happens if you guard the =up= combinator by =x<max=
#+BEGIN_QUOTE
*Question:* what happens if you guard the =up= combinator by =x<max=
instead of =pre x < max=?
#+END_QUOTE
** Local variables
Sometimes, it is useful to use auxiliary variables that are not
output variables. Such variables can be declared using the
~exist/in~ construct. Its use is illustrated in the
[[file:true_since_n_instants.lut][true_since_n_instants.lut]] program:
[[file:true-since-n-instants.lut][true-since-n-instants.lut]] program:
#+INCLUDE: "./true_since_n_instants.lut" src lutin
#+INCLUDE: "./true-since-n-instants.lut" src lutin
#+begin_src sh :tangle sh/true-since-demo.sh :exports none :noweb yes
xterm -e "luciole-rif lutin true_since_n_instants.lut";
xterm -e "luciole-rif lutin true-since-n-instants.lut";
#+end_src
{{{run(./sh/true-since-demo.sh, luciole-rif lutin true\_since\_n\_instants.lut)}}}
{{{run(./sh/true-since-demo.sh, luciole-rif lutin true-since-n-instants.lut)}}}
It is possible to set its previous value at declaration time as for
......@@ -838,7 +885,7 @@ illustrated the [[file:local.lut][local.lut]] program:
#+begin_src sh :tangle sh/local-demo.sh :exports none :noweb yes
lutin local.lut -l 100 -o local.rif ; gnuplot-rif local.rif ; rm local.rif
rm -f local.rif; lutin local.lut -l 100 -o local.rif && gnuplot-rif local.rif
#+end_src
{{{run(./sh/local-demo.sh,lutin local.lut -l 100 -o local.rif ; gnuplot-rif local.rif)}}}
......@@ -847,15 +894,18 @@ illustrated the [[file:local.lut][local.lut]] program:
file:png/Screenshot-Gnuplot-local.png
- Question: modify the previous program so that x reaches the target
#+BEGIN_QUOTE
*Question:* modify the previous program so that x reaches the target
after a [[file:png/Screenshot-Gnuplot-localbis.png][damped oscillation]]
like in the following screen-shot:
file:png/Screenshot-Gnuplot-localbis.png
[[file:local-bis.lut][Answer]]
#+END_QUOTE
** Distribute a constraint into a scope: =assert=
......@@ -869,9 +919,9 @@ file:png/Screenshot-Gnuplot-localbis.png
constraint that does not involve ~pre cpt~.
Consider for instance the [[file:true_since_n_instants2.lut][true_since_n_instants2.lut]] program:
Consider for instance the [[file:true-since-n-instants2.lut][true-since-n-instants2.lut]] program:
#+INCLUDE: "./true_since_n_instants2.lut" src lutin
#+INCLUDE: "./true-since-n-instants2.lut" src lutin
- One flaw is that ~res = (b and (cpt<=0))~ is duplicated.
......@@ -897,10 +947,11 @@ expression ~<te>~ by substituting all the constraint expressions
- Question : Rewrite the [[file:true_since_n_instants2.lut][true_since_n_instants2.lut]] using the
#+BEGIN_QUOTE
*Question:* Rewrite the [[file:true-since-n-instants2.lut][true-since-n-instants2.lut]] using the
~assert/in~ construct and avoid code duplication.
[[file:true_since_n_instants3.lut][Answer]]
#+END_QUOTE
** External code
......@@ -908,12 +959,12 @@ Lutin program can call any function defined in a shared library (=.so=)
#+begin_src lutin :tangle ext-call.lut :exports none :noweb yes
extern sin(x: real) : real
let abs(x:real) : real = if x < 0.0 then -x else x
node bizzare() returns (res: real) =
exist x,eps: real in
res = 0.0 and eps = 0.0 fby
loop abs(eps - pre eps) < .02
and x = pre x + 0.5 + pre eps
let between(x, min, max : real) : bool = ((min < x) and (x < max))
node bizzare() returns (x,res: real) =
exist noise: real in
assert between(noise,-0.1, 0.1) in
res = 0.0 and x = 0.0 fby
loop x = pre x + 0.1 + noise
and res = sin(pre x)
#+end_src
......@@ -921,11 +972,15 @@ node bizzare() returns (res: real) =
#+begin_src sh :tangle sh/ext-call-demo.sh :exports none :noweb yes
rm -f ext-call.rif
lutin -L libm.so -l 200 -o ext-call.rif ext-call.lut
lutin -L libm.so -l 200 -o ext-call.rif ext-call.lut && \
gnuplot-rif ext-call.rif
#+end_src
{{{run(./sh/ext-call-demo.sh, lutin -L libm.so -l 200 ext-call.lut -o f.rif;gnuplot-rif f.rif)}}}
{{{run(./sh/ext-call-demo.sh, lutin -L libm.so -l 200 ext-call.lut -o ext-call.rif;gnuplot-rif ext-call.rif)}}}
file:png/Screenshot-Gnuplot-ext.png
** Exceptions
......@@ -991,15 +1046,14 @@ st2. If the "do" part is omitted, the statement terminates normally.
[[file:except.lut][except.lut]]
Note that the 43 value is never generated (if i<>43 of course).
Note that the 43 value is generated iff i=43.
** About exceptions
- Very (too?) powerful mechanism
- Very powerful mechanism
- Can be used to build complex trace operators
- But should they used to program?
** Parallelism: =&>=
** Parallelism: =&>=
# file:paralel.lut
......@@ -1062,7 +1116,7 @@ Each step you set reset to =true=, the output equals to =0=.
# In Lutin, there are two operators for computing things in parallel: *)
# =&>= and =run=. *)
* The =run= operator
* The =run= operator
** Cheap parallelism: Calling Lutin nodes =run/in=
The idea is the following: when one writes:
......@@ -1085,7 +1139,6 @@ In Lustre, one would simply write
Moreover in Lutin, the order of equations matters.
** Cheap parallelism: Calling Lutin nodes =run/in=
- The =run/in= construct is another (cheaper) way of executing code in parallel
......@@ -1125,8 +1178,7 @@ sensors]] exemple.
#** Nodes versus combinators
** Why does the =run/in= statement makes Lutin usable?
** Why does the =run/in= statement is important?
Using combinators and =&>=, it was already possible to reuse code, but
=run/in= is
......@@ -1248,7 +1300,7 @@ and a few macros:
{{{run(./sh/is_stable-demo.sh,luciole-rif lutin is\_stable.lut -m is\_stable)}}}
*** The Lustre version
*** The Lustre version :noexport:
Now, let's write the same thing in Lustre, just for the fun of it
(and also because the notion of stability can be useful when writing
......
# XXX Edite plutot le main.org patate !
# Time-stamp: <modified the 16/03/2017 (at 11:11) by Erwan Jahier>
# Time-stamp: <modified the 20/03/2017 (at 22:16) by jahier>
#+OPTIONS: LaTeX:t
#+OPTIONS:toc:2
#+TODO: todo cont | done
......@@ -82,9 +82,18 @@ file:./demarche-it-en.png
- No topological sort of equations
** In order to run this tutorial