]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.tutorial/scl/Tutorial/X Old tutorial.md
Import org.simantics.scl.tutorial from incubator SVN repo
[simantics/platform.git] / bundles / org.simantics.scl.tutorial / scl / Tutorial / X Old tutorial.md
diff --git a/bundles/org.simantics.scl.tutorial/scl/Tutorial/X Old tutorial.md b/bundles/org.simantics.scl.tutorial/scl/Tutorial/X Old tutorial.md
new file mode 100644 (file)
index 0000000..68baf45
--- /dev/null
@@ -0,0 +1,1698 @@
+<script type="text/javascript"\r
+  src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">\r
+</script>\r
+\r
+# Getting started\r
+\r
+SCL Console is the easiest way to access SCL in Simantics. Therefore we will\r
+be using it all the time in this tutorial.  \r
+\r
+----\r
+\r
+SCL Console is opened from the menu *Show View/Other/SCL Console*.\r
+\r
+\includegraphics[scale=0.4]{figures/ShowView.png}\r
+\hspace{1cm}\r
+\includegraphics[scale=0.4]{figures/ShowView2.png}\r
+\r
+The view that is opened looks like this:\r
+\r
+\includegraphics[scale=0.5]{figures/SCLConsole.png}\r
+\r
+SCL commands are written to the box at the bottom of the view and the command responses\r
+are shown in the upper part of the view. Try writing\r
+~~~\r
+> 1 + 1\r
+~~~\r
+and press enter.\r
+\r
+\r
+----\r
+If the current command in the SCL Console input box contains an error, it is shown with a red underline.\r
+Moving the mouse pointer to that position shows an error description:\r
+\r
+\includegraphics[scale=0.5]{figures/ConsoleError.png}\r
+\r
+When the command contains an errors, the console is not willing to execute it. Pressing *enter*\r
+adds a new line to the command.\r
+\r
+While editing the command, arrow keys can be used to move the cursor around. \r
+Pressing *ctrl-enter* adds a new line even if the command is currently valid.\r
+Pressing *ctrl* and arrow keys up or down, you can browse the previously entered commands. \r
+\r
+Also copy *ctrl-C*, paste and cut work in the editing area.\r
+\r
+\r
+----\r
+### Exercise\r
+\r
+Run a multiline command:\r
+~~~\r
+> for [1..10] (\x -> \r
+      for [1..x] (\y ->\r
+          print (show x + " + " + show y + " = " + show (x+y))\r
+      )\r
+  )   \r
+~~~\r
+Then find it from the history and modify it to show multiplications instead of additions.\r
+\r
+\r
+----\r
+### Remark\r
+We will show lots of examples of SCL code in this tutorial. If some explanation leaves\r
+you in uncertain state, copy some of the examples to the console and \r
+play with them.\r
+\r
+\r
+## Basic expressions\r
+\r
+We start from the basic mathematical expressions you can write in SCL.\r
+This should cover the most needs you have if you want to use SCL expressions\r
+in component types.\r
+\r
+----\r
+Writing mathematical formulas in SCL is mostly unsurprising.\r
+~~~\r
+> 3*7+1\r
+22\r
+> 2 - sqrt 2\r
+0.5857864376269049\r
+> cos pi\r
+-1.0\r
+~~~\r
+\r
+One difference from many programming languages is that parentheses are not required around the \r
+parameters and multiple parameters are separated by whitespace:\r
+~~~\r
+> atan2 1 1\r
+0.7853981633974483\r
+~~~\r
+\r
+Parentheses are needed for each parameter separately, if the parameter is\r
+more complicated expression than  constant or variable:\r
+~~~\r
+> atan2 (sin 0.4) (cos 0.4)\r
+0.4\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+What is wrong with the following code. How to fix it?\r
+~~~\r
+> sin -1\r
+~~~\r
+\r
+----\r
+The results of the computations can be bound to variables and used in subsequent expressions:\r
+~~~\r
+> m = 4.0\r
+> c = 2.998e8\r
+> energy = m * c^2\r
+> energy\r
+3.5952016E17\r
+~~~\r
+\r
+If the variable is bound multiple times, the latest definition is used:\r
+~~~\r
+> a = 4\r
+> a = 8\r
+> a\r
+8\r
+~~~\r
+\r
+\r
+----\r
+### Remark\r
+Replacing a variable binding with a new binding is a feature of SCL Console.\r
+In SCL modules, variables can be bound only once.\r
+\r
+----\r
+A variable name must begin with a *lower-case* letter or an underscore.\r
+Following that can be any number of letters (lower-case and upper-case), numbers and underscores.\r
+The following names are reserved and cannot be used as identifiers:\r
+`_`, `forall`, `if`, `then`, `else`,\r
+`where`, `by`, `do`, `mdo`, `class`, `effect`,\r
+`match`, `with`, `instance`, `deriving`,\r
+`data`, `type`, `infix`, `infixl`, `infixr`.\r
+`import`, `include`, `importJava`, `as`.\r
+\r
+\r
+----\r
+\r
+This is the list of arithmetical functions available in SCL. The middle column\r
+contains the types of the functions. You can ignore them now.\r
+\r
+<table><tr><td>\r
+zero </td><td> Additive a => a </td><td> additive neutral element </td></tr><tr><td> \r
+(+) </td><td> Additive a => a -> a -> a </td><td> addition </td></tr><tr><td>\r
+sum </td><td> Additive a => [a] -> a </td><td> sum of list elements </td></tr><tr><td>\r
+neg </td><td> Ring a => a -> a </td><td> negation </td></tr><tr><td>\r
+(-) </td><td> Ring a => a -> a -> a </td><td> difference </td></tr><tr><td>\r
+one </td><td> Ring a => a </td><td> multiplicative neutral element </td></tr><tr><td>\r
+(*) </td><td> Ring a => a -> a -> a </td><td> multiplication </td></tr><tr><td>\r
+fromInteger </td><td> Ring a => Integer -> a </td><td> converts an integer to another number format </td></tr><tr><td>\r
+abs </td><td> OrderedRing a => a -> a </td><td> absolute value </td></tr><tr><td>\r
+(/) </td><td> Real a => a -> a -> a </td><td> division </td></tr><tr><td>\r
+(`^`) </td><td> Real a => a -> a -> a </td><td> exponentiation </td></tr><tr><td>\r
+pi </td><td> Real a => a </td><td> $\pi$ </td></tr><tr><td>\r
+sqrt </td><td> Real a => a -> a </td><td> square root </td></tr><tr><td>\r
+exp </td><td> Real a => a -> a </td><td> exponent function </td></tr><tr><td>\r
+log </td><td> Real a => a -> a </td><td> natural logarithm </td></tr><tr><td>\r
+sin,cos,tan </td><td> Real a => a -> a </td><td> trigonometric functions </td></tr><tr><td>\r
+asin,acos,atan </td><td> Real a => a -> a </td><td> inverse trigonometric functions </td></tr><tr><td>\r
+atan2 </td><td> Real a => a -> a -> a </td><td> arctangent with two parameters </td></tr><tr><td>\r
+sinh,cosh,tanh </td><td> Real a => a -> a </td><td> hyperbolic functions </td></tr><tr><td>\r
+asinh,acosh,atanh </td><td> Real a => a -> a </td><td> inverse hyperbolic functions </td></tr><tr><td>\r
+fromDouble </td><td> Real a => Double -> a </td><td> converts a double to another number format </td></tr><tr><td>\r
+floor </td><td> Real a => a -> a </td><td> the largest previous integer </td></tr><tr><td>\r
+ceil </td><td> Real a => a -> a </td><td> the smallest following integer </td></tr><tr><td>  \r
+div </td><td> Integer a => a -> a -> a </td><td> integer division </td></tr><tr><td>\r
+mod </td><td> Integer a => a -> a -> a </td><td> integer remainer\r
+</td></tr></table>\r
+\r
+Their meaning is mostly self-explanatory. \r
+Real and integer divisions are two different functions:\r
+~~~\r
+> 5 / 2\r
+2.5\r
+> 5 `div` 2\r
+2\r
+~~~\r
+The hat `^` is exponentiation:\r
+~~~\r
+> 3^4\r
+81.0\r
+~~~ \r
+Negation function `neg` can be used with the unary minus syntax. So the following are equivalent:\r
+~~~\r
+> neg 3\r
+-3\r
+> -3\r
+-3\r
+~~~\r
+\r
+\r
+----\r
+### Remark\r
+At this point you may encounter the following problem:\r
+~~~\r
+> a = 2\r
+> b = 3.4\r
+> a + b\r
+~~~\r
+The console does not execute the last expression because it contains an error \r
+``Expected $\langle$Integer$\rangle$ got $\langle$Double$\rangle$''.\r
+This is because the variable `a` is bound to an integer value and `b` is bound to a double value\r
+and SCL does automatic number conversion only for numerical literals (2, 3.4 etc.). There are several ways to fix\r
+the problem. First is to define `a` as a double:\r
+~~~\r
+> a = 2.0\r
+~~~\r
+or\r
+~~~\r
+> a = 2 :: Double\r
+~~~\r
+Another way is to convert the integer value to double in the final expression:\r
+~~~\r
+> fromInteger a + b\r
+5.4\r
+~~~\r
+\r
+\r
+----\r
+\r
+Numbers and many other objects can be compared with the following functions:\r
+<table><tr><td>\r
+(==) </td><td> Eq a => a -> a -> Boolean </td><td> equality </td></tr><tr><td> \r
+(!=) </td><td> Eq a => a -> a -> Boolean </td><td> inequality </td></tr><tr><td>\r
+(<),(>) </td><td> Ord a => a -> a -> Boolean </td><td> strict comparison </td></tr><tr><td>\r
+(<=),(>=) </td><td> Ord a => a -> a -> Boolean </td><td> non-strict comparison </td></tr><tr><td>\r
+min </td><td> Ord a => a -> a -> a </td><td> returns the the smaller of two parameters </td></tr><tr><td>\r
+max </td><td> Ord a => a -> a -> a </td><td> returns the larger of two parameters </td></tr><tr><td>\r
+compare </td><td> Ord a => a -> a -> Integer </td><td> returns -1 (0, 1), if the first parameter is smaller (equal, bigger) than the second one\r
+</td></tr></table>\r
+For example:\r
+\r
+~~~\r
+> 1 < 2\r
+True\r
+> 6 < 4\r
+False\r
+> max 1.5 3.8\r
+3.8\r
+~~~\r
+\r
+\r
+----\r
+Boolean expressions can be used to write conditional expressions:\r
+~~~\r
+> a = 3\r
+> b = 4\r
+> if a < b then a else b\r
+3\r
+> a = 5\r
+> if a < b then a else b\r
+4\r
+~~~\r
+In order to test multiple conditions, if-expressions can be combined:\r
+~~~\r
+> if a < b \r
+  then -1\r
+  else if a > b\r
+  then 1\r
+  else 0\r
+1\r
+~~~\r
+\r
+\r
+----\r
+Boolean values can be combined with conjunction `&&`, disjunction `||` and negation `not`.\r
+~~~\r
+> True && False\r
+False\r
+> True || False\r
+True\r
+> not True\r
+False\r
+~~~\r
+\r
+\r
+----\r
+\r
+Strings are written by enclosing them into double quotes:\r
+~~~\r
+> "Hello world!"\r
+"Hello world!"\r
+~~~\r
+\r
+Some of the operators seen so far can also be applied to strings:\r
+~~~\r
+> "Hello" + " world!"\r
+"Hello world!"\r
+> "Foo" < "Bar"\r
+False\r
+~~~\r
+\r
+There are also many functions specific to strings. We will however \r
+describe just some of them:\r
+<table><tr><td>\r
+length </td><td> String -> Integer </td><td> the length of a string </td></tr><tr><td>\r
+substring </td><td> String -> Integer -> Integer -> String </td><td> returns a substring of the string\r
+                                                     when the begin and the end positions of the\r
+                                                     string are given </td></tr><tr><td>\r
+show </td><td> Show a => a -> String </td><td> converts a value to a string </td></tr><tr><td> \r
+read </td><td> Read a => String -> a </td><td> converts a string to a value </td></tr><tr><td>\r
+indexOf </td><td> String -> String -> Integer </td><td> the index of the first position in the string that matches the given string </td></tr><tr><td>\r
+lastIndexOf </td><td> String -> String -> Integer </td><td> the index of the last position in the string that matches the given string </td></tr><tr><td>\r
+startsWith </td><td> String -> String -> Boolean </td><td> checks if the string starts with the given prefix </td></tr><tr><td>\r
+trim </td><td> String -> String </td><td> removes the white space from the beginning and end of the string\r
+</td></tr></table>\r
+From these functions, we need only `show` in this tutorial. \r
+\r
+~~~\r
+> x = 5.7\r
+> "x = " + show x\r
+x = 5.7\r
+~~~\r
+\r
+\r
+## Functions\r
+\r
+In SCL, functions are first-class values that can be manipulated with the\r
+same ease as numbers and other values. Almost all control structures also\r
+require that you define your own functions. Therefore we describe them\r
+before going to other data structures.\r
+\r
+----\r
+The syntax of the function definitions in SCL resemble function definitions in mathematics:\r
+~~~\r
+> dist x y = abs (x - y)\r
+> dist 2 5\r
+3\r
+> dist 6 4\r
+2\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Define a generalized average function:\r
+$${\rm avgG}\ p\ x\ y = \left({x^p + y^p \over 2}\right)^{1 \over p}$$\r
+Check that it works correctly:\r
+~~~\r
+> avgG 1 3 5\r
+4.0\r
+> avgG 2 2 14\r
+10.0\r
+> avgG (-1) 3 6\r
+4.0\r
+~~~\r
+\r
+\r
+----\r
+\r
+Functions can be recursive. For example Euclid's algorithm for\r
+computing greatest common divisor for two integers can be implemented\r
+as:\r
+~~~\r
+> gcd a b = if a > b\r
+            then gcd b a\r
+            else if a == 0\r
+            then b\r
+            else gcd (b `mod` a) a\r
+> gcd 12 9\r
+3           \r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Implement a function `fib` for computing Fibonacci numbers. First two Fibonacci numbers\r
+are one and after that every Fibonacci number is the sum of two previous Fibonacci numbers:\r
+1, 1, 2, 3, 5, 8, 13, \ldots.  \r
+\r
+\r
+----\r
+Many functions are implemented by cases. In these situations function definition can be\r
+written as multiple separate equations:\r
+~~~\r
+> gcd a b | a > b = gcd b a\r
+  gcd 0 b         = b\r
+  gcd a b         = gcd (b `mod` a) a\r
+~~~\r
+In this way it is easier to verify that every individual equation is corrent.\r
+\r
+There are two ways to restrict the applicability of an equation.\r
+The first way is to use patterns as parameters instead of just variables.\r
+In the example above, the second equation has a constant pattern 0 as a first parameter.\r
+We see later more complicated patterns.\r
+The second way to restrict the applicability is to add guards to the equation. \r
+A guard is the part in the first equation above after the vertical bar and before the equality.\r
+It is a boolean condition that must be true for equation to be applicable.\r
+\r
+The actual function value is computed by the first equation that can be applied with the given parameters. \r
+\r
+\r
+----\r
+### Exercise\r
+Rewrite the Fibonacci's function using either constant patterns or guards.\r
+\r
+\r
+----\r
+One of the cornerstones of all functional programming languages, including SCL, is the ability\r
+to give functions as parameters to other functions:\r
+~~~\r
+> epsilon = 1e-9\r
+> der f x = (f (x + epsilon) - f (x - epsilon)) / (2*epsilon)\r
+> der sin 0\r
+1.0\r
+> der log 5\r
+0.2000000165480742\r
+~~~\r
+This kind of functions are called *higher order functions*.\r
+\r
+Here is another example:\r
+~~~\r
+> iterate f n x | n > 0     = iterate f (n-1) (f x)\r
+                | otherwise = x\r
+> collatz n | n `mod` 2 == 0 = n `div` 2\r
+            | otherwise      = 3*n + 1\r
+> iterate collatz 0 13\r
+13\r
+> iterate collatz 1 13\r
+40\r
+> iterate collatz 2 13\r
+20\r
+> iterate collatz 5 13\r
+16\r
+> iterate collatz 8 13\r
+2\r
+> iterate collatz 9 13\r
+1\r
+~~~\r
+\r
+\r
+----\r
+Often the function we want to define can be get by filling some parameters of an already existing function.\r
+For example a function `limitZero`, that returns zero if its parameter is negative and otherwise\r
+returns the parameter unmodified, can be defined as:\r
+~~~\r
+> limitZero = max 0.0\r
+> limitZero 2.1\r
+2.1\r
+> limitZero (-5.4)\r
+0.0\r
+~~~\r
+This is called *partial application*.\r
+\r
+\r
+----\r
+Binary operators can be referred and partially applied by enclosing them\r
+in parenthesis:\r
+~~~\r
+> f = (+)\r
+> f 1 2\r
+3\r
+> incByOne = (+) 1\r
+> incByOne 5\r
+6\r
+~~~\r
+\r
+Inversely, an ordinary function can be used as a binary operator by enclosing it\r
+to backquotes (in fact, we have seen it already in the definiton of `gcd`):\r
+~~~\r
+> 1 `f` 2\r
+3\r
+> 14 `div` 3\r
+4\r
+~~~\r
+\r
+\r
+----\r
+Functions can be also defined without giving them a name:\r
+~~~\r
+> \x -> x * 2\r
+<function>\r
+> (\x -> x * 2) 3\r
+6\r
+~~~\r
+\r
+This is useful when using higher order functions:\r
+~~~\r
+> der (\x -> x^2 - 5*x) 2\r
+-1.000000082740371\r
+~~~\r
+\r
+\r
+----\r
+For writing complex functions, it is necessary to define auxiliary\r
+variables. There are two ways of doing this in SCL. The first way is\r
+`where` syntax:\r
+~~~\r
+> dist x1 y1 x2 y2 = sqrt (dx*dx + dy*dy)\r
+    where\r
+      dx = x1-x2\r
+      dy = y1-y2      \r
+~~~\r
+The second way is `do` syntax\r
+~~~\r
+> dist x1 y1 x2 y2 = do\r
+      dx = x1-x2\r
+      dy = y1-y2\r
+      sqrt (dx*dx + dy*dy)      \r
+~~~\r
+The difference between these constructs is often only aesthetic.\r
+\r
+One feature of SCL that is imporant here is that SCL uses\r
+the layout (indentation) of the code for parsing. The statements\r
+in the same `where` or `do` block must be consistently\r
+indented and indentation must be larger than the enclosing context.\r
+\r
+\r
+----\r
+\r
+SCL standard library defines the following functions for\r
+manipulating functions:\r
+<table><tr><td>\r
+id </td><td> a -> a </td><td> identity function </td></tr><tr><td>\r
+(\$) </td><td> (a -> <e> b) -> a -> <e> b </td><td> application operator </td></tr><tr><td>\r
+(.) </td><td> (b -> <e> c) -> (a -> <e> b) -> (a -> <e> c) </td><td> function composition </td></tr><tr><td>\r
+const </td><td> a -> b -> a </td><td> constant function </td></tr><tr><td>\r
+curry </td><td> ((a, b) -> <e> c) -> a -> b -> <e> c </td><td> give function parameters separately instead of a pair </td></tr><tr><td>\r
+uncurry </td><td> (a -> b -> <e> c) -> ((a, b) -> <e> c)  </td><td> inverse of curry </td></tr><tr><td>\r
+curry3 </td><td> ((a, b, c) -> <e> d) -> a -> b -> c -> <e> d  </td><td> give function parameters separately instead of a tripl </td></tr><tr><td>\r
+uncurry3 </td><td> (a -> b -> c -> <e> d) -> ((a, b, c) -> <e> d) </td><td> inverse of curry3  </td></tr><tr><td>\r
+flip </td><td> (a -> b -> <e> c) -> b -> a -> <e> c </td><td> flips the order of the function parameters\r
+</td></tr></table>\r
+Function `$` just applies given function and a parameter:\r
+\r
+~~~\r
+f $ x = f x\r
+~~~\r
+\r
+The precedence of the operator is very weak and it associates\r
+to right. It can be used\r
+to remove some parentheses in deeply nested expression. So\r
+we can write\r
+\r
+~~~\r
+> text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."\r
+> length \r
+    $ filter (\s -> length s > 4) \r
+    $ splitString text "[ ,.]"\r
+5\r
+~~~\r
+\r
+instead of\r
+\r
+~~~\r
+> length (filter (\s -> length s > 4) (splitString text "[ ,.]"))\r
+5\r
+~~~\r
+\r
+\r
+## Data structures\r
+\r
+----\r
+One of the simplest data structure is a pair:\r
+~~~\r
+> ("Citizen Kane", 1941)\r
+("Citizen Kane", 1941)\r
+~~~\r
+As seen above, the different elements of the pair can have different types. \r
+\r
+The components of the pair can be accessed with the functions `fst` and `snd`:\r
+~~~\r
+> fst ("Citizen Kane", 1941)\r
+"Citizen Kane"\r
+> snd ("Citizen Kane", 1941)\r
+1941\r
+~~~\r
+\r
+Other tuple lenghts are also supported:\r
+~~~\r
+> ()\r
+()\r
+> ("1", 1, 1.0)\r
+("1", 1, 1.0)\r
+~~~\r
+\r
+\r
+----\r
+Pairs and other tuples are useful, when we want to return more than one value from a function:\r
+~~~\r
+> toPolarCoordinates (x,y) = (sqrt (x*x + y*y), atan2 y x)\r
+> toRectangularCoordinates (r,angle) = (r*cos angle, r*sin angle)\r
+> polar = toPolarCoordinates (3,-6)\r
+> polar\r
+(6.708203932499369, -1.1071487177940904)\r
+> toRectangularCoordinates polar\r
+(3.000000000000001, -6.0)\r
+~~~\r
+\r
+As seen in the above example, when tuples are given as parameters to the functions, they can\r
+be pattern matched. In `toPolarCoordinates (x,y)` the components of the pair given\r
+as a parameter to the function are bound to `x` and `y`. \r
+A much less readable version of the above function would be:\r
+~~~\r
+> toPolarCoordinates p = (sqrt (fst p*fst p + snd p*snd p), \r
+                          atan2 (snd p) (fst p))\r
+~~~\r
+\r
+Patterns can be nested. A nonsensical example: \r
+~~~\r
+> shuffle ((a,b), (c,d)) = ((c,b), (a,d))\r
+> shuffle ((1,2), (3,4))\r
+((3, 2), (1, 4))\r
+~~~\r
+\r
+\r
+----\r
+### Remark\r
+The following command produces an error ``Expected $\langle$Integer$\rangle$ got $\langle$String$\rangle$\r
+~~~\r
+> shuffle (("1","2"), ("3","4"))\r
+~~~\r
+althought the function definition doesn't seem to care about the contents of the values (even if they are all of different types).\r
+This is a restriction of the current version of SCL Console: all functions you define are *monomorphic* meaning\r
+that all types involved must be fully known. When this is not a case, the compiler chooses the types somewhat arbitrarily.\r
+In SCL modules, there is no such restrictions and the compiler chooses the most generic type as possible for a function.\r
+Therefore, if the `shuffle` were defined in a SCL module, the above command would work.\r
+\r
+----\r
+Maybe the most important datatype is a list that may \r
+hold any number of values of the same type. Lists\r
+are constructed by enclosing the values in brackets:  \r
+~~~\r
+> [1, 2, 3, 4]\r
+[1, 2, 3, 4]\r
+~~~\r
+\r
+Elements of the lists are accessed with `!` operator:\r
+~~~\r
+> l = [1, 2, 3]\r
+> l!0\r
+1\r
+> l!2\r
+3\r
+~~~\r
+The length of the list can be found out with `length`:\r
+~~~\r
+> length l\r
+3\r
+~~~\r
+\r
+Two lists are joined together with `+` operator:\r
+~~~\r
+> [1, 2] + [3, 4]\r
+[1, 2, 3, 4]\r
+~~~\r
+\r
+Finally, a list containing some range of integers can be constructed as\r
+~~~\r
+> [4..9]\r
+[4, 5, 6, 7, 8, 9]\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+A quadratic equation $a x^2 + b x + c = 0$ has real solutions only if the discriminant\r
+$\Delta = b^2 - 4ac$ is non-negative. If it is zero, the equation has one solution and\r
+if it is positive, the equation has two solutions:\r
+$${-b \pm \sqrt{\Delta} \over 2a}.$$\r
+Write a function $`solveQuadratic`$ that solves a quadratic function whose\r
+coefficients are given as parameters and returns a list containing all solutions\r
+of the equation:\r
+~~~\r
+> solveQuadratic 1 1 (-2)\r
+[1.0, -2.0]\r
+> solveQuadratic 1 1 1\r
+[]\r
+~~~\r
+\r
+\r
+----\r
+Many useful tools for manipulating lists are higher order functions.\r
+The function `map` applies a given function to all elements of a list\r
+and produces a new list of the same length from the results:\r
+$$`map`\ f\ [x_1,x_2,\ldots,x_n] = [f\ x_1,f\ x_2,\ldots,f\ x_n]$$\r
+Here is couple of examples:\r
+~~~\r
+> map (\s -> "_" + s + "_") ["a", "b", "c"]\r
+["_a_", "_b_", "_c_"]\r
+> map ((*) 3) [1..4]\r
+[3, 6, 9, 12]\r
+~~~\r
+\r
+Unwanted elements can be removed from a list by `filter` function:\r
+~~~\r
+> filter (\s -> length s > 4) ["small", "big", "large", "tiny"]\r
+["small", "large"]\r
+> isPrime p = filter (\d -> p `mod` d == 0) [2..p-1] == []\r
+> filter isPrime [2..20]\r
+[2, 3, 5, 7, 11, 13, 17, 19]\r
+~~~\r
+\r
+The function `foldl` computes an aggergate value over a list of values\r
+by applying a binary function to the elements starting from the given initial element:\r
+$${\tt foldl}\ (\oplus)\ x_0\ [x_1,x_2,\ldots,x_n] = (\cdots((x_0 \oplus x_1) \oplus x_2) \oplus \cdots \oplus x_n)$$\r
+In practice:\r
+~~~\r
+> foldl (+) 0 [2,3,4]\r
+9\r
+> foldl (*) 1 [2,3,4]\r
+24\r
+> foldl max 0 [2,3,4]\r
+4\r
+~~~\r
+The function `sum` is equivalent to `foldl (+) zero`, but is in \r
+some cases implemented much more effeciently (for example for strings).\r
+\r
+The function `concatMap` is similar to `map`, but it assumes\r
+that the given function produces lists and concatenates the lists together:\r
+~~~\r
+> concatMap \r
+      (\(n,v) -> map (const v) [1..n]) \r
+      [(3,"a"), (2,"l"), (1,"i")]\r
+["a", "a", "a", "l", "l", "i"]\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Define a generalized average function for lists:\r
+$${\rm avgG}\ p\ [x_1,\ldots,x_{n}] = \left({x_1^p + \cdots + x_n^p \over n}\right)^{1 \over p}$$\r
+\r
+\r
+----\r
+### Exercise\r
+One useful way for producing lists is to map a range expression. For example\r
+~~~\r
+> diffs (l :: [Integer]) = map (\i -> l!(i+1) - l!i) [0..length l-2]\r
+> diffs [1,2,4,8,3]\r
+[1, 2, 4, -5]\r
+~~~\r
+Use the pattern to reimplement the function `reverse` from the standard library\r
+that reverses the order of elements in a list.\r
+\r
+\r
+----\r
+SCL supports *list comprehension* which allows to write\r
+many list producing expressions with a syntax that closely\r
+resembles the set comprehension from mathematics:\r
+~~~\r
+> l = [1..3]\r
+> [2*x | x <- l]\r
+[2, 4, 6]\r
+> [(x,y) | x <- l, y <- l]\r
+[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]\r
+> [(x,y) | x <- l, y <- l, x < y]\r
+[(1, 2), (1, 3), (2, 3)]\r
+> [(x,y) | x <- l, y=4-x]\r
+[(1, 3), (2, 2), (3, 1)]\r
+~~~\r
+As seen in the above examples, the left side of the vertical bar \r
+can be any expression producing the elements of the list. The\r
+right side of the bar is a list of producing statements:\r
+`x <- l` considers all `x` in the list `l`,\r
+`x = e` sets the value of `x` by the expression `e`\r
+and any boolean expression like `x < y` filters the produced elements.\r
+\r
+\r
+----\r
+### Remark\r
+SCL does not support yet pattern matching of lists althought it is supported in Haskell. \r
+\r
+\r
+----\r
+This is a list of some list functions provided by SCL standard library:\r
+\r
+\r
+<table><tr><td>\r
+map </td><td> Functor a => (a -> b) -> f a -> f b </td><td> </td></tr><tr><td>\r
+concatMap </td><td> (a -> <e> [b]) -> [a] -> <e> [b] </td><td> </td></tr><tr><td>\r
+filter </td><td> (a -> <e> Boolean) -> [a] -> <e> [a] </td><td> </td></tr><tr><td>\r
+filterJust </td><td> [Maybe a] -> [a] </td><td> </td></tr><tr><td>\r
+foldl </td><td> (a -> b -> <e> a) -> a -> [b] -> <e> a </td><td> apply the given binary operation from left to right </td></tr><tr><td>\r
+foldl1 </td><td> (a -> a -> <e> a) -> [a] -> <e> a </td><td> </td></tr><tr><td>\r
+unfoldl </td><td> (b -> <e> Maybe (a, b)) -> b -> <e> [a] </td><td> </td></tr><tr><td>\r
+unfoldr </td><td> (b -> <e> Maybe (a, b)) -> b -> <e> [a] </td><td> </td></tr><tr><td>\r
+zip </td><td> [a] -> [b] -> [(a,b)] </td><td> combine elements in the two lists </td></tr><tr><td>\r
+zipWith </td><td> (a -> b -> <e> c) -> [a] -> [b] -> <e> [c] </td><td> </td></tr><tr><td>\r
+unzip </td><td> [(a,b)] -> ([a],[b]) </td><td> </td></tr><tr><td>\r
+sort </td><td> Ord a => [a] -> [a] </td><td> sorts the elements in the list </td></tr><tr><td>\r
+sortBy </td><td> Ord b => (a -> <e> b) -> [a] -> <e> [a] </td><td> sorts the elements by a given criteria </td></tr><tr><td>\r
+sortWith </td><td> (a -> a -> <e> Integer) -> [a] -> <e> [a] </td><td> sorts the elements by a given comparison function </td></tr><tr><td>\r
+(\\) </td><td> Eq a => [a] -> [a] -> [a] </td><td> removes from the first list the elements that occur in the second list </td></tr><tr><td>\r
+range </td><td> Integer -> Integer -> [Integer] </td><td> </td></tr><tr><td>\r
+reverse </td><td> [a] -> [a] </td><td> reverses the order of the elements in the list </td></tr><tr><td>\r
+take </td><td> Integer -> [a] -> [a] </td><td> returns $n$ first elements of the list </td></tr><tr><td>\r
+drop </td><td> Integer -> [a] -> [a] </td><td> removes $n$ first elements from the list and returns the tail </td></tr><tr><td>\r
+lookup </td><td>  Eq a => a -> [(a, b)] -> Maybe b </td><td> finds a pair from the list such that the first component\r
+                                             matches the given value and returns the second component </td></tr><tr><td>\r
+and </td><td> [Boolean] -> Boolean </td><td> </td></tr><tr><td>\r
+or </td><td> [Boolean] -> Boolean </td><td> </td></tr><tr><td>\r
+any </td><td> (a -> <e> Boolean) -> [a] -> <e> Boolean </td><td> </td></tr><tr><td>\r
+all </td><td> (a -> <e> Boolean) -> [a] -> <e> Boolean \r
+</td></tr></table>\r
+\r
+\r
+----\r
+One data structure used quite often is an optional value.\r
+It is useful, if the function produces the result only for\r
+some parameter values. Optional value is either \r
+`Just value` or `Nothing`. Here is an example:\r
+~~~\r
+> safeSqrt x | x >= 0    = Just (sqrt x)\r
+             | otherwise = Nothing\r
+> safeSqrt 2\r
+Just 1.4142135623730951\r
+> safeSqrt (-2)\r
+Nothing   \r
+~~~\r
+The type of the expressions  `Just value` and `Nothing` is `Maybe t`,\r
+where $`t`$ is the type of `value`.\r
+\r
+Optional values can be handled with pattern matching\r
+(the example is from the standard library):\r
+~~~\r
+> fromMaybe _ (Just value)  = value\r
+  fromMaybe default Nothing = default\r
+~~~\r
+\r
+\r
+----\r
+Sometimes it is useful to use pattern matching without\r
+defining a new function for it. Therefore there is\r
+`match` construct:\r
+~~~\r
+> match (1,2,3) with\r
+     (x,y,z) -> x+y+z\r
+6\r
+~~~\r
+As with functions, there can be multiple cases and the\r
+first matching case is chosen:\r
+~~~\r
+> match safeSqrt 3 with\r
+      Just v  -> v\r
+      Nothing -> fail "Something bad happened." \r
+~~~\r
+\r
+## Types\r
+\r
+----\r
+\r
+Every expression in SCL has a type. Type determines the set of possible values\r
+of the expression. They are used for detecting errors in SCL code, for choosing the\r
+right implementation of a method (for example addition `(+)`) and for generating\r
+efficient byte code.\r
+\r
+When the type is monomorphic (does not contain type variables), it can be printed as\r
+~~~\r
+> typeOf "foo"\r
+String\r
+> typeOf [1,2,3]\r
+[Integer]\r
+~~~\r
\r
+\r
+----\r
+Normally SCL compiler will infer the types of the expressions automatically and\r
+you don't have to specify them manually. There are however situations where\r
+explicit control of types is useful:\r
+* You want to document the interface of your functions. It is good practice\r
+  to write a type annotation for all top-level functions declared in a SCL module.\r
+  Such declarations are not available in SCL Console: \r
+  ~~~\r
+  fst :: (a,b) -> a\r
+  fst (x,y) = x\r
+  ~~~\r
+* SCL compiler cannot infer a type that satisfies all the required constraints:\r
+  ~~~\r
+  > strId x = show (read x)\r
+  There is no instance for <Show ?a>.\r
+  There is no instance for <Read ?a>.\r
+  > strId x = show (read x :: Integer)\r
+  > strId "1"\r
+  "1"\r
+  > strId "1.0"\r
+  java.lang.NumberFormatException: For input string: "1.0"\r
+  ...\r
+  > strId x = show (read x :: Double)\r
+  > strId "1"\r
+  "1.0"\r
+  > strId "1.0"\r
+  "1.0"\r
+  ~~~\r
+  The type annotation is needed here, because `read` parses a string\r
+  to a certain type of values, `show` converts it back to string,\r
+  and the behavior of the composition depends on what the intermediate type is.\r
+  There is however not enough information for the compiler to infer the type\r
+  (it is shown as `?a` in the error message). \r
+* Code specialized to a certain type may be more efficient than a generic code\r
+  that applies to all data types.\r
+A type of an expression or identifier is annotated by adding `::` and a type\r
+expression after it. Type annotations may also be used in patterns:\r
+~~~\r
+sign (x :: Double) = compare x 0 \r
+~~~\r
+\r
+\r
+----\r
+The following types (or more exactly, type constructors) are built in the SCL compiler:\r
+* `Boolean`\r
+* `Byte`, `Short`, `Integer`, `Long`\r
+* `Float`, `Double`\r
+* `String`\r
+* `[]`\r
+* `()`, `(,)`, `(,,)`, ...\r
+* `(->)`\r
+* `Maybe`\r
+* `Array`\r
+* `BooleanArray`, `ByteArray`, `ShortArray`, \r
+  `IntegerArray`, `LongArray`, `FloatArray`, `DoubleArray`\r
+\r
+Other type constructors are defined in SCL modules, either importing them from Java\r
+or using `data` declaration.\r
+Except for the couple of special cases in the previous list, the names of \r
+all type constructors are capitalized.\r
+\r
+Some type constructors are parametric (compare to generics in Java or templates in C++).\r
+For example, the list type constructor `[]` has one parameter: the type of the list\r
+elements. Thus `[Integer]` is the type of the integer lists and `[String]` \r
+is the type of string lists. \r
+`[[Integer]]` is the type of the lists of integer\r
+lists. Parameters are usually written after the parametric type constructor: \r
+for example `Maybe Integer` or `Array String`, but some of the builtin type \r
+constructors can be written in a special way in order to make the type \r
+expressions more readable:\r
+~~~\r
+[a] = [] a\r
+(a,b) = (,) a b\r
+(a,b,c) = (,,) a b c\r
+...\r
+a -> b = (->) a b\r
+~~~\r
+\r
+Particularly important type constructor is `(->)` for building function types.\r
+For example, the type of the function computing the length of a string is `String -> Integer`: \r
+the function takes a string as a parameter and returns an integer.\r
+\r
+Types of the functions taking multiple parameters are written by composing function types. \r
+For example, the type of a function taking nth element of a string list is \r
+`[String] -> Integer -> String`. The function takes a string list and an integer as\r
+a parameter and returns a string. Function type operator `->` is right associative\r
+thus the previous type is equivalent to `[String] -> (Integer -> String)`. \r
+Thus the type expression can be read as well as a type of functions taking a string\r
+list and returning another function from integers and strings.\r
+\r
+`(a,b)` is the type of pairs where the first component of the pair has type `a`\r
+and the second component has type `b`. Tuple types `(a,b,c)`, `(a,b,c,d)` etc. \r
+are defined similarly. `Maybe a` is the type of optional values.\r
+\r
+\r
+----\r
+Many functions can be defined so that they do not need to know the exact types they are operating with.\r
+Such unknown types can be filled in type expressions by type variables: for example the function\r
+we discussed earlier that took nth element of a string list does not need the information that\r
+list elements are strings in its implementation and so it can be given a more generic type\r
+`[a] -> Integer -> a`, i.e a function taking a list of `a`:s and an integer as a parameter\r
+and returning a single `a`.\r
+\r
+Type variables may also refer to parametric types, but all useful examples involve type constraints we describe below.\r
+\r
+\r
+----\r
+### Exercise*\r
+\r
+Function types with type variables tell quite much about the function assuming it is total,\r
+i.e does not hang or throw a runtime exception with any parameters. Write the *unique*\r
+functions with the following type signatures:\r
+~~~\r
+a -> a\r
+(a,b) -> (b,a)\r
+~~~\r
+Write all possible functions with the following type signatures:\r
+~~~\r
+a -> a -> a\r
+~~~\r
+\r
+Because SCL Console does not support definition of functions with generic types,\r
+this exercise can be done only by writing your own SCL module.\r
+\r
+----\r
+SCL does not support function overloading at least in the way Java and C++ support it.\r
+This means that every function has a unique type signature. Now consider the addition function\r
+`(+)`. We could defined its signature for example as `Integer -> Integer -> Integer`,\r
+but then we would need some other name for the sum of doubles `Double -> Double -> Double` or\r
+strings `String -> String -> String`. It would seem like the right signature would be\r
+`a -> a -> a`, but that is not satisfactory either, because then the function had to\r
+somehow support all possible types. \r
+\r
+The solution to the problem is to constraint the set of allowed types for the type variable.\r
+Such a constrained type is written in the case of addition function as\r
+`Additive a => a -> a -> a`. The constraint `Additive a` is composed of a type class\r
+`Additive` followed by parameters of the constraint. \r
+The type can be understood in two different ways. A logical reading is\r
+> For any additive type `a`, the function takes two `a`:s as parameters and returns `a`.\r
+and an operational reading that gives a good intuition what is happening in runtime\r
+>  The function takes a parameter `Additive a` that describes a set of methods that can be used to operate the values of `a` and two `a`:s and returns `a`.\r
+\r
+Constrained type variable can also be parametric. For example, let's say we want to define a function getNth that takes nth element of a list but also works with arrays. The signature would then be\r
+~~~\r
+getNth :: Sequence s => s a -> Integer -> a\r
+~~~\r
+\r
+Type classes form a hierarchy: each class may have any number of superclasses. Only the most specific type class is needed in the constraints. For example, addition and multiplication have the following signatures:\r
+~~~\r
+(+) :: Additive a => a -> a -> a\r
+(*) :: Ring a => a -> a -> a\r
+~~~\r
+and Additive is a superclass of Ring a. A function using both operators need to specify only Ring as a constraint:\r
+~~~\r
+doubleAndAddOne :: Ring a => a -> a\r
+doubleAndAddOne x = 2*x + 1\r
+~~~\r
+\r
+This is a hierarchy of ``numerical'' type classes defined in the standard library of SCL:\r
+\r
+\includegraphics[scale=0.6]{figures/TypeClasses.png}\r
+\r
+The white boxes are type classes. An open arrow between type classes is the inheritance between type classes.\r
+The yellow boxes are types defined in the standard library. They are connected to the type classes\r
+they belong to.\r
+\r
+There are also type classes for converting values to strings `Show` and vice versa `Read`.\r
+Types in the type class `Hashable` provide a method to compute a hash code.\r
+Types in the type class `Serializable` can be serialized to a byte array and deserialized back to a value.\r
+There are also some type classes that make programming with different containers more generic:\r
+`Functor`, `Monad`, etc. \r
+\r
+\r
+----\r
+SCL functions are referentially transparent which means that they are like\r
+mathematical functions always returning the same value for the same parameters\r
+and not causing any observable side-effects. This seems extremely restrictive\r
+because most of the programs are written in order to generate some kind of\r
+side-effects and even completely mathematical algorithms involve functions\r
+that are not referentially transparent such as generation of random numbers.\r
+\r
+This policy does not however restrict expressive power of the language because\r
+functions can return and manipulate *descriptions of computations*.\r
+These computations are then executed by some external means.\r
+Two different ways of handling computations in SCL are monads and effect types.\r
+Effect types are not applicable to as large range of different\r
+computation concepts as monads are but they are easier to work with.\r
+\r
+An effectful computation has type `<effects> t`.\r
+The type after angle brackets is the type of the value obtained by the computation.\r
+Side-effects that might happen during the computation are listed inside of angle brackets.\r
+Effect types must always occur as a return type of a function. Here are some examples (some fictional) \r
+of functions with side-effects:\r
+~~~\r
+randomBetween :: Double -> Double -> <Nondet> Double\r
+resource :: String -> <ReadGraph> Resource\r
+claim :: Resource -> Resource -> Resource -> <WriteGraph> ()\r
+randomLiteral :: Double -> Double -> <Nondet,WriteGraph> Resource\r
+~~~\r
+\r
+Effect types are much like type constraints: you can mostly ignore them when using functions.\r
+All effects you use are automatically collected and added to the type signature of the defined\r
+function (or checked against type annotation if provided).\r
+\r
+Like type classes, effects form a hierarchy. For example WriteGraph inherits ReadGraph\r
+and a function both reading and writing to graph is annotated only with `<WriteGraph>` effect.\r
+\r
+Like types, effects can also be abstracted with effect variables. This is important when defining generic\r
+functions that manipulate possibly effectful functions:\r
+~~~\r
+executeTwice :: (() -> <e> ()) -> <e> ()\r
+executeTwice f = do f () ; f ()\r
+\r
+(.) :: (b -> <e2> c) -> (a -> <e1> b) -> (a -> <e1,e2> c)\r
+(f . g) x = f (g x)\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Revisit the earlier lessons listing library functions and their types. \r
+Can you now understand all the type signatures?\r
+\r
+\r
+## Side-effects\r
+\r
+----\r
+So far our examples have used pure functions without side effects.\r
+There are indeed quite few functions in the standard library producing\r
+side effects. One of them is the printing function: \r
+~~~\r
+> print "Hello world!"\r
+Hello world!\r
+~~~\r
+\r
+Side-effectful function applications can be sequenced \r
+in a `do` block:\r
+~~~\r
+> do print "Hello,"\r
+     print "    World!"\r
+Hello,\r
+    World!     \r
+~~~\r
+\r
+----\r
+It is very typical that we want to cause some effect for\r
+every element of some list. For that purpose there is a function `for`:\r
+~~~\r
+> for [1..3] print\r
+1\r
+2\r
+3\r
+~~~\r
+\r
+Here is a little more complicated example:\r
+~~~\r
+> items = ["patridge in a pear tree", "turtle doves",\r
+           "french hens", "colly birds", "gold rings",\r
+           "geese-a-laying", "swans-a-swimming", "maids-a-milking",\r
+           "ladies dancing", "lords-a-leaping", "pipers piping",\r
+           "drummers drumming"]\r
+> numbers = ["and a", "two", "three", "four", "five", "six",\r
+             "seven", "eight", "nine", "ten", "eleven", "twelve"]\r
+> printVerse n = do\r
+      print "On the twelfth day of Christmas, my true love gave to me"\r
+      for [1..n] (\i -> do\r
+          c = n-i\r
+          print $ (if n==1 then "a" else numbers!c) + " " + items!c\r
+      )\r
+      print ""\r
+> for [1..12] printVerse\r
+...\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Procude the lyrics of the song ``99 Bottles of Beer''\r
+<http://www.99-bottles-of-beer.net/lyrics.html>.\r
+\r
+\r
+----\r
+Sometimes it is useful to introduce a state that can be modified\r
+during an algorithm. Such a state is created with function `ref`,\r
+it is accessed with `getReg` and modified with `(:=)` operator:\r
+~~~\r
+> nRef = ref 1\r
+> for [1..8] (\_ -> do \r
+      n = getRef nRef\r
+      print n\r
+      nRef := 2*n\r
+  )\r
+1\r
+2\r
+4\r
+8\r
+16\r
+32\r
+64\r
+128\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Reproduce the `gcd` function by using modifible state.\r
+\r
+\r
+----\r
+This is a partial list of functions in the standard library producing side-effects:\r
+\setlength\LTleft{-2cm}\r
+<table><tr><td>\r
+for </td><td> FunctorE f => f a -> (a -> <e> ()) -> <e> () </td><td> executes the given function with every element in the structure </td></tr><tr><td>\r
+print </td><td> Show a => a -> <Proc> () </td><td> prints the given value </td></tr><tr><td>\r
+ref </td><td> a -> <Proc> (Ref a) </td><td> creates a state </td></tr><tr><td>\r
+getRef </td><td> Ref a -> <Proc> a </td><td> accesses a state </td></tr><tr><td>\r
+(:=) </td><td> Ref a -> a -> <Proc> () </td><td> modifies the state </td></tr><tr><td>\r
+newArrayList </td><td> () -> <Proc> ArrayList a </td><td> creates an array list </td></tr><tr><td>\r
+addArrayList </td><td> ArrayList a -> a -> <Proc> () </td><td> add an element at the end of the list </td></tr><tr><td>\r
+getArrayList </td><td> ArrayList a -> Integer -> <Proc> a </td><td> gets an element from the list </td></tr><tr><td>\r
+lengthArrayList </td><td> ArrayList a -> <Proc> Integer </td><td> returns the current lenght of the list </td></tr><tr><td>\r
+freezeArrayList </td><td> ArrayList a -> <Proc> [a] </td><td> freezes the list and returns the corresponding immutable list\r
+</td></tr></table>\r
+\r
+\r
+## Browsing Simantics database\r
+\r
+----\r
+The functionality we have used so far has been readily available in the console.\r
+There is also functionality that must be imported before using:\r
+~~~\r
+> import "Simantics/Ontologies"\r
+~~~\r
+The string `Simantics/Ontologies` is the name of the *SCL module* that is imported.\r
+We assume that the import command is excuted in the rest of this section. \r
+\r
+\r
+----\r
+In order to browse the database more conveniently, let's define some helper functions.\r
+~~~\r
+> nameOfResource r = match possibleRelatedValue r L0.HasName with\r
+    Just name -> name\r
+    Nothing -> "no name"\r
+> printNames (rs :: [Resource]) = \r
+      for rs (\r -> print $ nameOfResource r)    \r
+> findEntities (p :: Resource -> <ReadGraph> Boolean) = findRecursively\r
+    where\r
+      findRecursively r = do \r
+          children = concatMap findRecursively $ immediateChildren r\r
+          if p r\r
+          then [r] + children\r
+          else children\r
+      immediateChildren s = s # L0.ConsistsOf     \r
+> findByType t = findEntities (flip isInstanceOf t)\r
+> aprosOntologies = resource "http://www.apros.fi"\r
+> project = currentProject ()\r
+~~~\r
+\r
+Now we can find all connection types defined in the Apros ontologies:\r
+~~~\r
+> printNames $ findByType STR.ConnectionType aprosOntologies\r
+PipelineStructureConnectionType\r
+...\r
+ElectricalNameReferenceConnectionType\r
+~~~\r
+Find all module types:\r
+~~~\r
+> import "http://www.apros.fi/Apros-6.1" as APROS\r
+> printNames $ findByType APROS.AprosModuleType aprosOntologies\r
+~~~\r
+Show all pipes in the workspace with their lengths:\r
+~~~\r
+> import "http://www.apros.fi/Combustion/Configuration-6.0/ModuleTypes" \r
+         as MT\r
+> import "http://www.apros.fi/Combustion/Configuration-6.0/Relations" \r
+         as REL\r
+> for (findByType MT.PIPE project) (\pipe ->\r
+      print $ nameOfResource pipe + " " + \r
+              show (relatedValue pipe REL.PI12_LENGTH :: Float)      \r
+  )\r
+~~~\r
+Find all modules that are not connected anywhere:\r
+~~~\r
+> isUnconnected r = not (existsStatement r STR.IsConnectedTo \r
+                      || existsStatement r APROS.AttachedModule)\r
+> printNames $ filter isUnconnected \r
+             $ findByType APROS.AprosModule project\r
+~~~\r
+\r
+\r
+----\r
+This is a list of most important database accessing functions (the\r
+type `Resource` is abbreviated as `Res` in the type signatures):\r
+\setlength\LTleft{-4cm}\r
+<table><tr><td>\r
+resource </td><td> String -> <ReadGraph> Res </td><td> the resource with the given URI </td></tr><tr><td>\r
+uriOf </td><td> Res -> <ReadGraph> String </td><td> the URI of the given resource </td></tr><tr><td>\r
+(\#) </td><td> Res -> Res -> <ReadGraph> [Res] </td><td> returns all objects for given subject and predicate </td></tr><tr><td>\r
+existsStatement </td><td> Res -> Res -> <ReadGraph> Boolean </td><td> returns true, if there is a statement with the given subject and predicate  </td></tr><tr><td>\r
+singleObject </td><td> Res -> Res -> <ReadGraph> Res </td><td> returns the unique object with the given subject and predicate </td></tr><tr><td>\r
+possibleObject </td><td> Res -> Res -> <ReadGraph> Maybe Res </td><td> returns a possible object with the given subject and predicate </td></tr><tr><td>\r
+valueOf </td><td> Serializable a => Res -> <ReadGraph> a </td><td> reads a value associated with a resource </td></tr><tr><td>\r
+relatedValue </td><td> Serializable a => Res -> Res -> <ReadGraph> a </td><td> reads a property </td></tr><tr><td>\r
+possibleRelatedValue </td><td> Serializable a => Res -> Res -> <ReadGraph> Maybe a </td><td> reads a possibly existing property </td></tr><tr><td>\r
+inverseOf </td><td> Res -> <ReadGraph> Res </td><td> inverse of a relation </td></tr><tr><td>\r
+singleTypeOf </td><td> Res -> Res -> <ReadGraph> Res </td><td> the unique type of the resource inheriting the given type </td></tr><tr><td>\r
+possibleTypeOf </td><td> Res -> Res -> <ReadGraph> Maybe Res </td><td> a possible type of the resource inheriting the given type </td></tr><tr><td> \r
+isInstanceOf </td><td> Res -> Res -> <ReadGraph> Boolean </td><td> tests if a resource is an instance of the given type </td></tr><tr><td>\r
+isSubrelationOf </td><td> Res -> Res -> <ReadGraph> Boolean </td><td> tests if a resource is a subrelation of a given relation </td></tr><tr><td>\r
+isInheritedFrom </td><td> Res -> Res -> <ReadGraph> Boolean </td><td> tests if a resource is a subtype of a given type </td></tr><tr><td>\r
+claim </td><td> Res -> Res -> Res -> <WriteGraph> () </td><td> adds a statement </td></tr><tr><td>\r
+deny </td><td> Res -> Res -> Res -> <WriteGraph> () </td><td> removes a statement </td></tr><tr><td>\r
+claimRelatedValue </td><td> Serializable a => Res -> Res -> a -> <WriteGraph> () </td><td> sets the value of a property </td></tr><tr><td>\r
+syncRead </td><td> (() -> <Proc,ReadGraph> a) -> <Proc> a </td><td> makes a read request </td></tr><tr><td>\r
+syncWrite </td><td> (() -> <Proc,ReadGraph,WriteGraph> a) -> <Proc> a </td><td> makes a write request\r
+</td></tr></table>\r
+\r
+\r
+## Manipulating diagrams\r
+\r
+----\r
+Diagrams could be in principle manipulated with the set of primitive\r
+graph functions introduced in the previous section. There is however\r
+some tools available to work with diagrams at a higher level. \r
+Therefore we need for this section the following imports:\r
+~~~\r
+> import "Simantics/Diagram"\r
+> import "http://www.apros.fi/Apros-6.1" as APROS\r
+> import "http://www.apros.fi/Combustion/Configuration-6.0/Relations" \r
+         as REL\r
+> import "http://www.apros.fi/Combustion/Diagram-6.0/Symbols" \r
+         as SYMBOLS          \r
+> import "http://www.apros.fi/Combustion/Diagram-6.0/Relations" \r
+         as CPS\r
+~~~\r
+\r
+For this section you should also create a model with (default) name Model\r
+and a new diagram to that model with (default) name NewGenericDiagram. If\r
+you want to change these names, you should also change the code\r
+examples accordingly. Populate the diagram with couple of elements and\r
+connect them together.\r
+\r
+\r
+----\r
+We show first how to read the diagram contents:\r
+~~~\r
+> dia = diagram (model "Model") ["NewGenericDiagram"]\r
+> for (elementsOfR dia) print\r
+(Connection [Terminal "SP_01" #221240, Terminal "MU_01" #218187] [Edge 0 1] (Just "XA_02"), #450761)\r
+(Component #217233 "SP_01" (Position ...) [Property #137577, ...], #450756)\r
+(Component #217663 "MU_01" (Position ...) [Property #144599, ...], #450751)\r
+~~~\r
+The actual result depends on how you have populated your diagram.\r
+\r
+The result is not very readable because of all the resource identifiers. \r
+Let's write a pretty-printing function:\r
+~~~\r
+> printElement ((Component t n pos props),_) = do\r
+    print $ n + " :: " + nameOfResource t\r
+    print $ "    " + show pos\r
+    for props (\(Property relation value) ->\r
+        print $ "    " + nameOfResource relation + " " + show value\r
+    )\r
+ printElement ((Connection nodes _ name),_) = do\r
+    print $ "Connection " + \r
+            (match name with Just n -> n ; Nothing -> "")\r
+    printNode (Terminal element connectionPoint) = \r
+        print $ "    " + element + " " + nameOfResource connectionPoint\r
+    printNode otherwise = ()\r
+    for nodes printNode\r
+ printElement ((Flag t name _ _ _ _ _ pos _),_) = do\r
+    print $ "Flag " + name + " :: " + nameOfResource t\r
+    print $ "    " + show pos\r
+ printElement (el,_) = print el // Use the default printing as a fallback \r
+~~~\r
+Now we get:\r
+~~~>  \r
+> for (elementsOfR dia) printElement\r
+Connection XA_02\r
+    SP_01 SP_OUTPUT_SIGN_1_1\r
+    MU_01 MULTIPLYER_INPUT_SIGN_1_1\r
+SP_01 :: SetpointS\r
+    Position 1.0 0.0 0.0 1.0 94.0 115.0\r
+    SP_VALUE 0.0\r
+    SP_MINMAX_ON false\r
+    SP_GRADIENT_UP 60.0\r
+    SP_TRACKING_ON false\r
+    SP_MIN 0.0\r
+    SP_GRADIENT_DOWN -60.0\r
+    SP_FAST_MODE_ON true\r
+    SP_MAX 100.0\r
+MU_01 :: Gain\r
+    Position 1.0 0.0 0.0 1.0 104.0 115.0\r
+    MULTIPLYER_BIAS 0.0\r
+    MULTIPLYER_GAIN 1.0\r
+    MULTIPLYER_OUTPUT 0.0\r
+~~~\r
+\r
+\r
+----\r
+Next, let's create some new diagrams. We need two helper functions:\r
+~~~\r
+> aprosDiagram modelName diagramName = NewDiagram \r
+      (model modelName) \r
+      [diagramName]\r
+      APROS.Folder\r
+      APROS.GenericAprosComposite\r
+> joinMap = createJoinMap ()\r
+~~~\r
+The first function creates a specification for a new diagram:\r
+it describes the model where the diagram is created, the path\r
+to the diagram, the type of folders in the path and finally\r
+the type of the diagram itself. The second definition defines\r
+a `joinMap` that is used for connecting diagrams together (by flags).\r
+\r
+Now we can write:\r
+~~~\r
+> newDia = fst $ createDiagramR (aprosDiagram "Model" "TestDiagram1") joinMap []\r
+~~~\r
+This should create a new diagram with name TestDiagram1. The\r
+last parameter is the list of diagram elements. Because the list\r
+is empty, our diagram is also empty.\r
+\r
+Easiest way to create some content is to copy it from another diagram:\r
+~~~\r
+> sortEls l = filter (not . isReferring) l + filter isReferring l\r
+    where\r
+      isReferring (Connection _ _ _) = True\r
+      isReferring (SimpleConnection _ _ _ _ _) = True\r
+      isReferring (Monitor _ _ _ _) = True\r
+      isReferring otherwise = False\r
+> els = sortEls $ map fst $ elementsOfR dia\r
+> createDiagramR (ExistingDiagram newDia) joinMap els \r
+~~~\r
+This replaces the contents of TestDiagram1 by the contents of NewGenericDiagram.\r
+The function `sortEls` is needed to work around a bug in `createDiagramR`\r
+occurring if some element is created after another element that refers to it.\r
+\r
+\r
+----\r
+Usually we want to modify the contents of the diagram somehow before copying it.\r
+Here are couple of example functions for transforming the elements:\r
+~~~\r
+> mapElementName f (Component t name pos props) =\r
+      Component t (f name) pos props\r
+  mapElementName f (Connection nodes edges possibleName) =\r
+      Connection (map prefixNode nodes) edges (map f possibleName)\r
+    where\r
+      prefixNode (Terminal name cp) = Terminal (f name) cp\r
+      prefixNode n = n\r
+  mapElementName f (Flag t name label output external \r
+                         ioBinding ioTableRowIndex pos refs) = \r
+      Flag t (f name) label output external \r
+           ioBinding ioTableRowIndex pos refs\r
+  mapElementName f el = el // This is not yet a complete definition!\r
+> moveElement delta (Component t name pos props) =\r
+      Component t name (move delta pos) props\r
+  moveElement delta (Connection nodes edges name) =\r
+      Connection (map moveNode nodes) edges name\r
+    where\r
+      moveNode (RouteLine False pos) = RouteLine False (pos + fst delta)\r
+      moveNode (RouteLine True pos) = RouteLine True (pos + snd delta)\r
+      moveNode n = n\r
+  moveElement delta (Flag t name label output external\r
+                          ioBinding ioTableRowIndex pos refs) = \r
+      Flag t name label output external \r
+           ioBinding ioTableRowIndex (move delta pos) refs\r
+  moveElement delta el = el // This is not yet a complete definition!\r
+~~~\r
+Now we can move the elements and add a prefix to them:  \r
+~~~  \r
+> modifiedEls = map (moveElement (20,20)) \r
+              $ map (mapElementName ((+) "PREFIX_")) els\r
+> createDiagramR (ExistingDiagram newDia) joinMap modifiedEls\r
+~~~\r
+\r
+Finally, let's try making some clones of the elements:\r
+~~~  \r
+> modifiedEls = [ moveElement (dx,dy) $ mapElementName ((+) prefix) el\r
+                | i <- [0..3]\r
+                , j <- [0..3]\r
+                , dx = 30 * fromInteger i\r
+                , dy = 30 * fromInteger j\r
+                , prefix = "P_" + show i + "_" + show j + "_"\r
+                , el <- els] \r
+> createDiagramR (ExistingDiagram newDia) joinMap modifiedEls\r
+~~~\r
+\r
+\r
+----\r
+### Exercise\r
+Write a function `createPipeline` that takes as a parameter\r
+a diagram specification and a list of two-dimensional points\r
+and creates a pipeline such that elevations of the points are\r
+the second components of the points in the list, the lengths \r
+of the points are the distances between successive points and\r
+the diagram positions are based on the physical positions.\r
+The following command should work: \r
+~~~\r
+> dia = ExistingDiagram (diagram (model "Model") ["TestDiagram1"])\r
+> createPipeline dia [(1,1), (6,1), (10,5)]\r
+~~~\r
+\r
+Hint: The following commands create a pipe and a point that are connected\r
+together with point elevation and pipe lenght specified:   \r
+~~~\r
+> els = [\r
+      Component SYMBOLS.Point "PO_01" (location 30 30) \r
+                [Property REL.PO11_ELEV (toDynamic 10.0)],\r
+      Component SYMBOLS.Pipe "PI_01" (location 40 30) \r
+                [Property REL.PI12_LENGTH (toDynamic 5.0)],\r
+      Connection [Terminal "PO_01" CPS.PointSelf,\r
+                  Terminal "PI_01" CPS.PI12_CONNECT_POINT_1_1_1]\r
+                  [Edge 0 1] Nothing\r
+  ]\r
+> createDiagramR dia joinMap els\r
+~~~\r
+\r
+\r
+----\r
+### Remark\r
+This is the data type definition of the diagram elements:\r
+~~~\r
+data DiagramElement res = \r
+    Component\r
+        res            // component type\r
+        String         // name\r
+        Position       // position\r
+        [Property res] // properties\r
+  | SimpleConnection String res String res (Maybe String)\r
+  | Connection [ConnectionNode res] [Edge] (Maybe String)\r
+  | Flag \r
+        res \r
+        String         // name \r
+        String         // label\r
+        Boolean        // output\r
+        Boolean        // external\r
+        (Maybe String)  // IOTableBinding\r
+        (Maybe Integer) // IOTableRowIndex\r
+        Position       // position  \r
+        [Dynamic]      // references to the joins\r
+  | SVG String Position\r
+  | Monitor String (Maybe MonitorReference) MonitorVisuals Position\r
+data Position = Position Double Double Double Double Double Double\r
+data Property res = Property res Dynamic\r
+data Edge = Edge Integer Integer\r
+data ConnectionNode res = Terminal String res\r
+                        | RouteLine\r
+                              Boolean   // is horizontal\r
+                              Double    // position\r
+data Font = Font String Integer Integer\r
+data Alignment = Baseline | Center\r
+               | Leading | Trailing\r
+data MonitorReference = MonitorReference String String\r
+data MonitorVisuals = MonitorVisuals (Maybe Font) Double Alignment Alignment                              \r
+~~~\r
+\r
+## Model queries\r
+\r
+----\r
+In this section, we make queries and mass modifications to the components\r
+of a model. For preliminaries, you need to run the import command:\r
+~~~\r
+import "Apros/ModelQueries"\r
+~~~\r
+\r
+It defines the following functions:\r
+~~~\r
+forAllComponentsIn :: (Resource -> <e> a) -> Resource -> <ReadGraph,e> ()\r
+forAllComponents ::  (Resource -> <e> a) -> <Proc,ReadGraph,e> ()\r
+forComponentsIn :: (Resource -> <e> Boolean) -> Resource \r
+                -> (Resource -> <e> a) -> <ReadGraph,e> ()\r
+forComponents :: (Resource -> <e> Boolean) -> (Resource -> <e> a) -> <Proc,ReadGraph,e> ()\r
+searchComponents :: (Resource -> <e> Boolean) -> <Proc,ReadGraph,e> [Resource]\r
+searchComponentsIn :: (Resource -> <e> Boolean) -> Resource -> <ReadGraph,e> [Resource]\r
+\r
+nameSatisfies :: (String -> <e> Boolean) -> Resource -> <e,ReadGraph> Boolean\r
+nameIs name = nameSatisfies (== name)\r
+getName :: Resource -> <ReadGraph> String\r
+\r
+typeIs :: Resource -> Resource -> <ReadGraph> Boolean\r
+\r
+configurationValueSatisfies :: Serializable a => Resource -> (a -> <e> Boolean) \r
+                            -> Resource -> <e,ReadGraph> Boolean\r
+configurationValueIs :: Serializable a => Resource -> a \r
+                     -> Resource -> <e,ReadGraph> Boolean\r
+setConfigurationValue :: Serializable a => Resource -> a -> Resource -> <WriteGraph> ()\r
+getConfigurationValue :: Serializable a => Resource -> Resource -> <ReadGraph> a\r
+\r
+stateValueSatisfies :: Serializable a => Resource -> (a -> <e> Boolean) \r
+                    -> <ReadGraph> (Resource -> <e,ReadGraph> Boolean)\r
+stateValueIs :: Serializable a => Resource -> a \r
+             -> <ReadGraph> (Resource -> <e,ReadGraph> Boolean)\r
+setStateValue :: Serializable a => Resource -> a\r
+              -> <ReadGraph> (Resource -> <WriteGraph> ())\r
+getStateValue :: Serializable a => Resource -> <ReadGraph> (Resource -> <ReadGraph> a)\r
+\r
+(&&&) :: Combinable a => a -> a -> a\r
+instance Combinable (Resource -> <e> Boolean)\r
+instance Combinable (Resource -> <e> ())\r
+\r
+printName :: Resource -> <ReadGraph,Proc> ()\r
+row :: [Resource -> <e> String] -> (Resource -> <e> String)\r
+~~~\r
+\r
+\r
+----\r
+The functions make it possible to define queries to the active\r
+model of the form:\r
+``for all components satisfying a condition execute an action.''\r
+For example:\r
+\r
+1) Print the names of all points in the model:\r
+    ~~~\r
+   forComponents\r
+       (typeIs MODULETYPES.POINT)\r
+       printName\r
+   ~~~ \r
+2) Set area of pipe PIP01 to 0.0033\r
+   ~~~\r
+   forComponents\r
+       (nameIs "PIP01")\r
+       (setConfigurationValue ATTRIBUTES.PI12_AREA 0.2)\r
+   ~~~\r
+3) Find all pipes in the active model and set their area to 0.001 m2:\r
+   ~~~\r
+   forComponents\r
+       (typeIs MODULETYPES.PIPE)\r
+       (setConfigurationValue ATTRIBUTES.PI12_AREA (0.001 :: Float))\r
+   ~~~\r
+4) Find all pipes with area < 0.0001 m2 in the active model and set their area to 0.001 m2:\r
+   ~~~\r
+   forComponents\r
+       (configurationValueSatisfies ATTRIBUTES.PI12_AREA (\(x :: Float) -> x < 0.0001))\r
+       (setConfigurationValue ATTRIBUTES.PI12_AREA (0.001 :: Float))\r
+   ~~~\r
+5) Find all pipes with fluid section WSB and list their boron concentrations:\r
+   ~~~\r
+   forComponents\r
+       (configurationValueIs ATTRIBUTES.PO11_SECTION_NAME "WSB")\r
+       (print . row [getName, showFloat . getStateValue ATTRIBUTES.PO11_BOR_CONC])\r
+   ~~~\r
+6) Find all pipes with fluid section WS and set their fluid section to WSB:\r
+   ~~~\r
+   forComponents\r
+       (configurationValueIs ATTRIBUTES.PO11_SECTION_NAME "WS")\r
+       (setConfigurationValue ATTRIBUTES.PO11_SECTION_NAME "WSB")\r
+   ~~~\r
+7) Find all pipes in diagram Diagram2 and set their length to 123.45 m:\r
+   ~~~\r
+   forComponentsIn\r
+         (typeIs MODULETYPES.PIPE)\r
+         (resource "http://Projects/Development%20Project/Model/Configuration/Diagram2")\r
+         (setConfigurationValue ATTRIBUTES.PI12_LENGTH (123.45 :: Float))\r
+   ~~~  \r
+\r
+----\r
+It is also possible to write the results of a query to a file.\r
+~~~\r
+printingToFile "c:/temp/componentListing.txt" (\r
+    forComponents\r
+        (configurationValueIs ATTRIBUTES.PO11_SECTION_NAME "WSB")\r
+        (print . row [getName, showFloat . getStateValue ATTRIBUTES.PO11_BOR_CONC])\r
+    )\r
+~~~\r
+\r
+\r
+# Further topics\r
+\r
+----\r
+\r
+If you start to use SCL more frequently and write your own helper functions,\r
+it becomes quickly cumbersome to paste them every time into the console.\r
+You can write a list of commands into a separate file and run it with the command\r
+~~~\r
+> runFromFile "c:/file/path"\r
+~~~\r
+Commands are separated from each other by indentation.\r
+\r
+Another way to store function definitions is to write your own modules.\r
+It also frees you from some restrinctions of SCL Console.\r
+You can write the module into a file, say `c:/scl/MyModule.scl`\r
+and import it as:\r
+~~~\r
+> import "file:c:/scl/MyModule"\r
+~~~\r
+What makes working with modules harder than console commands is that\r
+it is not so easy to update a module that you have already imported.\r
+It is however possible by running:\r
+~~~\r
+> reset ""\r
+~~~\r
+that clears the whole SCL environment. After clearing the environment, you \r
+have to reimport all the modules you want to use.\r
+We will improve the situation in next versions of \r
+the SCL environment.\r
+\r
+\r
+----\r
+There are many language features we have not touched in this tutorial.\r
+Many of them are also in Haskell, so you can familize yourself with them\r
+by reading Haskell tutorials:\r
+* defining new data types,\r
+* defining new type classes and their instances,\r
+* defining binary operators, their associativity and precedence.\r
+SCL supports also monads like Haskell. Only difference is that monadic\r
+syntax uses keyword `mdo` instead of `do`. Althought\r
+the importance of monads is lessen in SCL because of effect types,\r
+they are still a useful concept to know. Monads are particularly\r
+useful for building domain specific languages in SCL.\r
+\r
+\r
+----\r
+There are also couple of features that we have not described that\r
+are specific to SCL:\r
+* definition of new effect types\r
+* syntax for importing Java code to SCL, for example:\r
+  ~~~\r
+  importJava "java.util.List" where\r
+      @JavaName get\r
+      (!) :: [a] -> Integer -> a\r
+  \r
+      @JavaName size\r
+      length :: [a] -> Integer\r
+  \r
+      subList :: [a] -> Integer -> Integer -> [a]\r
+  ~~~\r
+* value annotations\r
+  ~~~\r
+  @inline\r
+  curry :: ((a, b) -> <e> c) -> a -> b -> <e> c\r
+  curry f x y =  f (x, y)\r
+  \r
+  @macro\r
+  a && b = if a then b else False\r
+  ~~~\r
+\r
+\r