I am trying to implement a parser and semantic for a 'CSP' in Scala . I have already implemented the parser , and now I am busy working on a Semantic part of the language. I am completely new to the world of concurrent systems and non-deterministic choices. so here is my question:
I want to implement the "Non-deterministic Choice" and "Interface Parallel" as explained
here.
I now can understand understand the procedure but I can't get my head straight when it comes to non-determinism. I am in need of a good data type to implement this in Scala, I am thinking to put all the processes in a list and then randomize the list and then choose a element from modified list. but that doesn't sound so non-deterministic for me.
Has anyone experienced on this issue before and knows a good algorithm?
My very limited understanding of CSP is that the CSP operators correspond to the following Haskell types:
-- Prefixing corresponds to functions
x :: A
P :: B
x -> P :: A -> C
-- Choice corresponds to product
P :: A
Q :: B
P □ Q :: (A, B)
-- Non-determinism corresponds to sum
-- I don't know how to make the non-determinism symbol, so I use (△)
P :: A
Q :: B
(P △ B) :: Either A B
Then you can use the algebraic isomorphisms to reduce CSP expressions. Using the Wikipedia example:
(coin -> STOP) □ (card -> STOP)
-- translates to the following Haskell type:
(coin -> Stop, card Stop)
-- which is algebraically isomorphic to:
(Either coin card -> Stop)
-- translates in reverse back to CSP:
coin □ card -> STOP
Also, I think one of the Wikipedia examples is wrong (or I'm wrong). I believe this expression should reduce to:
(a -> a -> STOP) □ (a -> b -> STOP)
-- translates to the following Haskell type:
(a -> a -> STOP, a -> b -> STOP)
-- which is algebraically isomorphic to:
a -> Either a b -> STOP
-- translates in reverse back to CSP:
a -> (a △ b) -> STOP
I still haven't figured out the equivalent of interface parallel, though. It doesn't seem to correspond to an elegant concept.
This is an advanced topic. The parsing side is the easy bit. Writing correct concurrent primitives is very hard and will almost certainly require formal verification using a tool such as FDR.
If you're only interested in writing the expression parser part, not the concurrency primitives, you might prefer to build upon JCSP, which already provides these primitives in a Java API. The authors of this (UKC) used formal verification to validate its components, notably the channel and alternative (choice) parts.
Related
Is there a good way to use type information to choose to do different things?
For example, this isn't valid Haskell, but I don't see why it couldn't be:
tostring :: (Show b) => b -> String
tostring x = f x where f = if b == String then tail . init . show else show
The important part is not getting the correct string out, but using the type of b as a way to switch between functionality/functions.
#chi's answer already demonstrates how to use Typeable to do run-time type checking, but I'd like to point out that to me, this looks like exactly the thing typeclasses are meant for. For your example, the only problem is that you don't like the Show implementation for String: In that case, just create your own typeclass!
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
-- The class
class MyShow a where
myShow :: a -> String
-- The instance for String
-- (The `OVERLAPPING` pragma is required, because
-- otherwise GHC won't know which instance to choose for String)
instance {-# OVERLAPPING #-} MyShow [Char] where
myShow = tail . init . show
-- For everything that is not a String, just copy the Show instance
instance Show a => MyShow a where
myShow = show
EDIT: As pointed out by leftaroundabout, overlapping instances are complicated and can lead to some unexpected behavior. Look at the example at the bottom of the documentation.
I will answer the question as it is. Haskell erases all type information during compile time, mostly for efficiency reasons. By default, when a polymorphic function is called, e.g. f :: a->a, no type information is available, and f has no way to know what a actually is -- in this case, f can only be the identity function, fail to terminate, or raise an error.
For the rare cases where type information is needed, there is Typeable. A polymorphic function having type f :: Typeable a => ... is passed a run-time description of the type a, allowing it to test it. Essentially, the Typeable a constraint forces Haskell to keep the runtime information until run time. Note that such type information must be known at the call site -- either because f is called with a completely known type, or because f is called with a partially known type (say f x with x :: Maybe b) but there are suitable Typeable constraints in scope (Typeable b, in the previous example).
Anyway, here's an example:
{-# LANGUAGE TypeApplications, ScopedTypeVariables, GADTs #-}
import Data.Typeable
tostring :: forall b. (Show b, Typeable b) => b -> String
tostring x = case eqT #b #String of -- if b==String
Just Refl -> x -- then
Nothing -> show x -- else
Note how we were able to return x in the "then" branch, since there it is known to be a String.
The name like "A_of_B" is a unique naming convention in OCaml, but I want to know why. Is it a result of the different language usage between French and English? Or Xavier Leroy's personal preference?
Background: I found that OCaml's type conversion functions have the name like A_of_B, for example, int_of_string : string -> int or float_of_int : int -> float in Stdlib module. Other popular languages use the name like AtoB, for example, itoa function in C.
First of all, let's start with a short excursus to the history of OCaml. Xavier Leroy didn't invent the language and neither the language was born in France. OCaml was born from the Meta Language (ML) of the LCF (Logic for Computable Functions) theorem prover, developed in Stanford and University of Edinburgh by Robin Milner. Below is a snippet of code, obtained from the original LCF 1977,
let gensrinfo th =
let srthm = disjsrvars th in
let hypfrees = formlfrees(hyp srthm)
and hyptyvars = formltyvars(hyp srthm)
and (),p,() = destimpequiv(concl srthm) in
srthm , termmatch(hypfrees,hyptyvars) p;;
Does it resemble something? ;) It was a little bit later when the French Formel team developed a new implementation of ML, based on the Categorical Abstract Machine, that later turned into SML, and Caml itself was born 10 years later than the code snippet above in 1987. And three years later, in 1990, Xavier Leroy designed a completely new implementation of Caml based on a bytecode interpreter called ZINC. Five years later, they developed an optimizing compiler, and five more years later, in 2000, Objective Caml was born, aka O'Caml and, now, OCaml.
This is all to say that, originally, ML was designed and developed by the English-speaking community and there is no justification to search for the convention etymology in the French language or Xavier's preferences. We, indeed, can find this convention already in LCF (e.g., intoftok, tokofint operators) and in other derivatives of LCF, such as HOL, e.g., the HOL 1988 standard library already had the function int_of_string, at that time Xavier didn't even graduate yet.
So, why this convention? It comes from the way of reasoning about programs, which is logical rather than imperative (remember, ML was born as a meta-language (the logic language) in a theorem prover). Instead of thinking about how a function is implemented, we are thinking about what the term represents, so what is int_of_string "42"? It is an integer, that has textual representation "42". We do not convert "42" into an integer and think about it as a transformation box, instead, we employ declarative thinking as in mathematics, e.g., cos 0.0 doesn't convert 0.0 into 1.0, cos 0.0 is 1.0. This style of thinking facilitates equational reasoning -- a powerful way of thinking about programs and understanding their semantics.
My guess is that it is intended to be more readable when working with functions as values, e.g. with higher-order functions like function composition:
# let compose f g = fun x -> f (g x);;
val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
Here, composition is reflected directly in names:
# let string_of_float = compose string_of_int int_of_float;;
val string_of_float : float -> string = <fun>
Whereas it could be a bit hard to read the equivalent with functions names with the reverse order:
compose int_to_string float_to_int
I am using Haskell and QuickCheck to write a test for the following function:
{-| Given a list of points and a direction, find the point furthest
along in that direction. -}
fn :: (Eq a, Ord a, DotProd a) => [a] -> a -> a
fn pnts dir = pnts !! index
where index = fromJust $ elemIndex (maximum dotproducts) dotproducts
dotproducts = map (dot dir) pnts
I believe this implementation to be correct, since it's not too complex of a function. But, I want to use QuickCheck to test it for some edge cases.
However, I run into the problem that, when I define my QuickCheck tests, they are identical to the function I am testing.
How do I write a test in QuickCheck that tests the purpose of a function without repeating its implementation?
How do I write a test in QuickCheck that tests the purpose of a function without repeating its implementation?
First, note that sometimes, a quickcheck property that states that a function behaves according to its current implementation is not completely worthless. You can use it for regression tests if you ever change the implementation. For example, if you optimize the definition of your fn to use clever data structures, the Quickcheck property based on the old, more straight-forward implementation might prove helpful.
Second, you often want your Quickcheck properties to check high-level and declarative properties of your functions, while the implementation is usually lower-level and more directly executable. In this case, you could specify such properties as:
forall lists of points ps and directions d, the point fn ps d is in the list ps.
forall lists of points ps, directions d, and forall points p in ps, the point p is not further along in the direction d than the point fn ps d.
forall points p and forall directions d, fn [p, origin] d is p.
I'm not totally sure about the underlying geometry, so my examples might be stupid. But I hope the examples convey the general idea: The quickcheck properties could check for properties of the specification "being further along in a direction" without mentioning the particular algorithm.
I'm writing some code (a Metropolis-Hastings MCMC sampler) that will use a random number generator, and modify an array and potentially other structures based on this.
My initial idea was to use the ST monad, so that I could use ST arrays and the mersenne-random-pure64 package, keeping the PureMT generator as part of the state.
However I want to be able to split off some of the work into separate helper functions (e.g to sample a random integer in a given range, to update the array structure, and potentially more complicated things). To do this, I think I would need to pass the references to the PureMT gen and the array to all the functions, which could quickly become very ugly if I need to store more state.
My instinct is to group all of the state into a single data type that I can access anywhere, as I would using the State monad by defining a new datatype, but I don't know if that is possible with the ST monad, or the right way to go about it.
Are there any nice patterns for doing this sort of thing? I want to keep things as general as possible because I will probably need to add extra state and build more monadic code around the existing parts.
I have tried looking for examples of ST monad code but it does not seem to be covered in Real World Haskell, and the haskell wiki examples are very short and simple.
thanks!
My instinct is to group all of the state into a single data type that I can access anywhere, as I would using the State monad by defining a new datatype, but I don't know if that is possible with the ST monad, or the right way to go about it.
Are there any nice patterns for doing this sort of thing? I want to keep things as general as possible because I will probably need to add extra state and build more monadic code around the existing parts.
The key point to realize here is that it's completely irrelevant that you're using ST. The ST references themselves are just regular values, which you need access to in a variety of places, but you don't actually want to change them! The mutability occurs in ST, but the STRef values and whatnot are basically read-only. They're names pointing to the mutable data.
Of course, read-only access to an ambient environment is what the Reader monad is for. The ugly passing of references to all the functions is exactly what it's doing for you, but because you're already in ST, you can just bolt it on as a monad transformer. As a simple example, you can do something like this:
newtype STEnv s e a = STEnv (ReaderT e (ST s) a)
deriving (Functor, Applicative, Monad)
runEnv :: STEnv s e a -> ST s e -> ST s a
runEnv (STEnv r) e = runReaderT r =<< e
readSTEnv :: (e -> STRef s a) -> STEnv s e a
readSTEnv f = STEnv $ lift . readSTRef . f =<< ask
writeSTEnv :: (e -> STRef s a) -> a -> STEnv s e ()
writeSTEnv f x = STEnv $ lift . flip writeSTRef x . f =<< ask
For more generality, you could abstract over the details of the reference types, and make it into a general "environment with mutable references" monad.
You can use the ST monad just like the IO monad, bearing in mind that you only get arrays and refs and no other IO goodies. Just like IO, you can layer a StateT over it if you want to thread some state transparently through your computation.
What I'm doing: I'm writing a small interpreter system that can parse a file, turn it into a sequence of operations, and then feed thousands of data sets into that sequence to extract some final value from each. A compiled interpreter consists of a list of pure functions that take two arguments: a data set, and an execution context. Each function returns the modified execution context:
type ('data, 'context) interpreter = ('data -> 'context -> 'context) list
The compiler is essentially a tokenizer with a final token-to-instruction mapping step that uses a map description defined as follows:
type ('data, 'context) map = (string * ('data -> 'context -> 'context)) list
Typical interpreter usage looks like this:
let pocket_calc =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
Interpreter.parse map "path/to/file.txt"
let new_context = Interpreter.run pocket_calc data old_context
The problem: I'd like my pocket_calc interpreter to work with any class that supports add, sub and mul methods, and the corresponding data type (could be integers for one context class and floating-point numbers for another).
However, pocket_calc is defined as a value and not a function, so the type system does not make its type generic: the first time it's used, the 'data and 'context types are bound to the types of whatever data and context I first provide, and the interpreter becomes forever incompatible with any other data and context types.
A viable solution is to eta-expand the definition of the interpreter to allow its type parameters to be generic:
let pocket_calc data context =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
let interpreter = Interpreter.parse map "path/to/file.txt" in
Interpreter.run interpreter data context
However, this solution is unacceptable for several reasons:
It re-compiles the interpreter every time it's called, which significantly degrades performance. Even the mapping step (turning a token list into a interpreter using the map list) causes a noticeable slowdown.
My design relies on all interpreters being loaded at initialization time, because the compiler issues warnings whenever a token in the loaded file does not match a line in the map list, and I want to see all those warnings when the software launches (not when individual interpreters are eventually run).
I sometimes want to reuse a given map list in several interpreters, whether on its own or by prepending additional instructions (for instance, "div").
The questions: is there any way to make the type parametric other than eta-expansion? Maybe some clever trick involving module signatures or inheritance? If that's impossible, is there any way to alleviate the three issues I have mentioned above in order to make eta-expansion an acceptable solution? Thank you!
A viable solution is to eta-expand the
definition of the interpreter to allow
its type parameters to be generic:
let pocket_calc data context =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
let interpreter = Interpreter.parse map "path/to/file.txt" in
Interpreter.run interpreter data context
However, this solution is unacceptable
for several reasons:
It re-compiles the interpreter every time it's called, which
significantly degrades performance.
Even the mapping step (turning a token
list into a interpreter using the map
list) causes a noticeable slowdown.
It recompiles the interpreter every time because you are doing it wrong. The proper form is more something like this (and technically, if the partial interpretation of Interpreter.run to interpreter can do some computations, you should move it out of the fun too).
let pocket_calc =
let map = [ "add", (fun d c -> c # add d) ;
"sub", (fun d c -> c # sub d) ;
"mul", (fun d c -> c # mul d) ]
in
let interpreter = Interpreter.parse map "path/to/file.txt" in
fun data context -> Interpreter.run interpreter data context
I think your problem lies in a lack of polymorphism in your operations, which you would like to have a closed parametric type (works for all data supporting the following arithmetic primitives) instead of having a type parameter representing a fixed data type.
However, it's a bit difficult to ensure it's exactly this, because your code is not self-contained enough to test it.
Assuming the given type for primitives :
type 'a primitives = <
add : 'a -> 'a;
mul : 'a -> 'a;
sub : 'a -> 'a;
>
You can use the first-order polymorphism provided by structures and objects :
type op = { op : 'a . 'a -> 'a primitives -> 'a }
let map = [ "add", { op = fun d c -> c # add d } ;
"sub", { op = fun d c -> c # sub d } ;
"mul", { op = fun d c -> c # mul d } ];;
You get back the following data-agnostic type :
val map : (string * op) list
Edit: regarding your comment about different operation types, I'm not sure which level of flexibility you want. I don't think you could mix operations over different primitives in the same list, and still benefit from the specifities of each : at best, you could only transform an "operation over add/sub/mul" into an "operation over add/sub/mul/div" (as we're contravariant in the primitives type), but certainly not much.
On a more pragmatic level, it's true that, with that design, you need a different "operation" type for each primitives type. You could easily, however, build a functor parametrized by the primitives type and returning the operation type.
I don't know how one would expose a direct subtyping relation between different primitive types. The problem is that this would need a subtyping relation at the functor level, which I don't think we have in Caml. You could, however, using a simpler form of explicit subtyping (instead of casting a :> b, use a function a -> b), build second functor, contravariant, that, given a map from a primitive type to the other, would build a map from one operation type to the other.
It's entirely possible that, with a different and clever representation of the type evolved, a much simpler solution is possible. First-class modules of 3.12 might also come in play, but they tend to be helpful for first-class existential types, whereas here we rhater use universal types.
Interpretive overhead and operation reifications
Besides your local typing problem, I'm not sure you're heading the right way. You're trying to eliminate interpretive overhead by building, "ahead of time" (before using the operations), a closure corresponding to a in-language representation of your operation.
In my experience, this approach doesn't generally get rid of interpretive overhead, it rather moves it to another layer. If you create your closures naïvely, you will have the parsing flow of control reproduced at the closure layer : the closure will call other closures, etc., as your parsing code "interpreted" the input when creating the closure. You eliminated the cost of parsing, but the possibly suboptimal flow of control is still the same. Additionnaly, closures tend to be a pain to manipulate directly : you have to be very careful about comparison operations for example, serialization, etc.
I think you may be interested in the long term in an intermediate "reified" language representing your operations : a simple algebraic data type for arithmetic operations, that you would build from your textual representation. You can still try to build closures "ahead of time" from it, though I'm not sure the performances are much better than directly interpreting it, if the in-memory representation is decent. Moreover, it will be much easier to plug in intermediary analyzers/transformers to optimize your operations, for example going from an "associative binary operations" model to a "n-ary operations" model, which could be more efficiently evaluated.