I have programmed a langton's ant and it work nice.
Now I want to run 2 ant simultaneously.I have a run function how make the computation and ant's movement and it's a infinite run loop.
How can I run 2 of this loop at once ?
I have try to look on Thread but i'm not sure that it's the best for my case.
This is some example of my code :
Run function :
let run(f,tab2 : t_fourmi*int array array) =
f.xx := !(f.x);
f.yy := !(f.y);
let d = ref 0
and z = ref 0
and o = ref 0
(* 1 = de bas, 2 = de droite, 3 = de haut, 4 = de gauche *)
in
if tab2.(!(f.x)/5).(!(f.y)/5) = 0
then move_right(f,1,tab2);
if !(f.xx) + 5 = !(f.x)
then d := 4
else if !(f.xx) - 5 = !(f.x)
then d := 2
else if !(f.yy) + 5 = !(f.y)
then d := 1
else if !(f.yy) - 5 = !(f.y)
then d := 3;
while true
do
(*
print_string "step : ";
print_int !o;
print_newline(); *)
o := !o + 1;
f.xx := !(f.x);
f.yy := !(f.y);
z := tab2.(!(f.x)/5).(!(f.y)/5);
if !z = 0
then move_right(f,!d,tab2)
else if !z = 1
then move_left(f,!d,tab2)
else if !z = 2
then move_right(f,!d,tab2)
else if !z = 3
then move_right(f,!d,tab2);
if !(f.xx) + 5 = !(f.x)
then d := 4
else if !(f.xx) - 5 = !(f.x)
then d := 2
else if !(f.yy) + 5 = !(f.y)
then d := 1
else if !(f.yy) - 5 = !(f.y)
then d := 3;
done;
;;
Example of move function :
let move_left(f,d,tab2 : t_fourmi*int*int array array) = (* d = direction d'ou la fourmi viens *)
(* 1 = de bas, 2 = de droite, 3 = de haut, 4 = de gauche *)
f.xx := !(f.x);
f.yy := !(f.y);
if d = 1
then f.x := !(f.x) - 5
else if d = 2
then f.y := !(f.y) - 5
else if d = 3
then f.x := !(f.x) + 5
else if d = 4
then f.y := !(f.y) + 5;
if !(f.x) >= 995
then f.x := 5
else if !(f.x) <= 5
then f.x := 995;
if !(f.y) >= 995
then f.y := 5
else if !(f.y) <= 5
then f.y := 995;
create_fourmi(f);
let n = tab2.(!(f.xx)/5).(!(f.yy)/5) in
drawinv(!(f.xx),!(f.yy),n,tab2);
;;
If you need more function, ask me.
Thanks
If I understand your code correctly (it's unfortunately not very readable), it could be outlined as essentially:
let init params =
...
let step state =
...
let move thing state =
...
let run params thing =
let state = ref (init params) in
while true do
let state := step state in
move thing state
done
where I've factored init, step and move out into separate function, which should be pretty straight-forward to do. And by doing so we can replace the run function with a run_two function that can run two instances virtually at the same time, though not entirely in parallel. They won't run independently, but in synchrony, iteration by iteration:
let run_two params1 thing1 params2 thing2 =
let state1 = ref (init params1) in
let state2 = ref (init params2) in
while true do
state1 := step !state1;
state2 := step !state2;
move !state1;
move !state2;
done
This doesn't use any threads or other complicated concurrency primitives. It's just ordinary code organized in a way that allows composition. It also allows the init and step function to be completely pure, which makes them easy to test and reason about. You could even make the move functions pure, if you factor out the drawing.
You can use threads, though it will open a pandora box for you. You have to synchronize your ants, since probably you want them to move in the same world.
Running two ants in different threads
First of all, you have to represent each ant process as an ever-looping function of type ant -> unit, where ant is the type that describes ant's initial position, moving parameters, and so on (if you don't need this, then just use unit instead. So suppose we have a function val run : ant -> unit. Next, we need to make sure, that we do not write to the same board at the same time from different threads, so we need to create a mutex, using Mutex.create, we then need to update our run function and do Mutex.lock before updating our board, and Mutex.unlock after. Finally, we should ensure that no ants will starve for the board, and that once an ant finishes it moves it yields the control to another ant, we could do this using Thread.delay if we want our simulation to be smooth (i.e., if we want to artificially slow it down to human-observable speed). Otherwise, we can just use Thread.yield. (Note, normally threads are preempted (forced to yield) by the system, but this is done in special yield points. When we do system programming there are usually lots of yield points, but this is not our case, so we have to implement this cooperation explicitly). Finally, our updated run function is ready to be run in a thread, with Thread.createrun ant. This function will return to our main thread of execution, so we can run a second ant and so on. Once all ants start running we have to call Thread.join to wait for all of them. Ideally, this function should never return.
I hope, that the above outline provided enough information for you, and you can enjoy the coding yourself. Feel free to ask questions int the comment section if anything is unclear. Probably, the first question would be how to compile it. It is (there are simpler ways, of course, but the most basic is, assuming that your program is in the ant.ml):
ocamlopt -thread unix.cmxa threads.cmxa ant.ml -o ant
Running two ants in co-routines
While the above will work, it seems too complicated and too system-dependent for such a simple simulation task. Why do we need to use system threads for that? We actually don't, we can be clever and implement co-routines using plain OCaml and continuation-passing style. Don't worry, a continuation is just a function. And a continuation-passing style is when we are calling another function at the end of the other function. In this approach, we will not have the run function that runs infinitely, instead, we will have a step function that advances an ant one step forward at each invocation. For the demonstration purposes, let's simplify our step function so that each ant just greets another, e.g.,
let step other yield =
print_endline ("Hello, " ^ other);
yield ()
That simple. We do our step, and then call the yield function (that is that fancy continuation) to yield the control to the next ant. Now let's tie it together in a simple infinite loop, e.g.,
let rec loop () =
step "Joe" ## fun () ->
step "Doe" ## fun () ->
loop ()
let () = loop ()
Let's make it clear. step "Joe" ## fun () -> <continue> is the same as step "Joe" (fun () -> <continue>), and this (fun () -> <continue>) is the yield function that is passed to the step function that greets Joe. Once Joe is greeted the step function calls us again and we evaluate the <continue>, which is, in our case step "Doe" ## fun () -> loop (), i.e., we pass the fun () -> loop () function as the yield argument to the step function that greets Doe, so once Doe is greeted, we call loop () ... and now we're at the begining of the loop.
In our case, we were passing a value of type unit in our continuations, but we can also pass an arbitrary value, e.g., a value that will represent the state of our simulation (the board with ant positions). This will enable a functional implementation of your simulation if you want to try it.
Related
I'm quite new to Maple and I would like to create the following list:
U__N := u__1[0], u__2[0], u__1[1], u__2[1], u__1[2], u__2[2], u__1[3], u__2[3], u__1[4], u__2[4], u__1[5], u__2[5]
I came up with the following two options. For both I lack the knowledge for the last step
Option 1
U__N := seq([u__1[k], u__2[k]], k = 0 .. 5)
which gives me a nested list: U__N := [u__1[0], u__2[0]], [u__1[1], u__2[1]], [u__1[2], u__2[2]], [u__1[3], u__2[3]], [u__1[4], u__2[4]], [u__1[5], u__2[5]]. However, now I do not know how to "un-nest" the nested list.
Option 2:
Create two separate lists
U__N2 := seq(u__2[k], k = 0 .. 5 - 1)
which returns U__N1 := u__1[0], u__1[1], u__1[2], u__1[3], u__1[4]
U__N2 := seq(u__2[k], k = 0 .. 5 - 1)
which returns U__N2 := u__2[0], u__2[1], u__2[2], u__2[3], u__2[4].
Now I would like to concatenate/combine these two lists alternatively.
Do you have any suggestions for one of these two options or an alternative solution?
I would prefer to create the pair-wise portions and then utilize those directly, than to form the whole list-of-lists and Flatten it.
The special-evaluation rules of the seq command allows for its first argument to not be evaluated until after k attains concrete numeric values.
This allow you to adjust your first method and extract the operands of the pair-wise inner lists, using the op command.
seq(op([u__1[k], u__2[k]]), k = 0 .. 5);
u__1[0], u__2[0], u__1[1], u__2[1],
u__1[2], u__2[2], u__1[3], u__2[3],
u__1[4], u__2[4], u__1[5], u__2[5]
seq([u__1[k], u__2[k]][], k = 0 .. 5);
u__1[0], u__2[0], u__1[1], u__2[1],
u__1[2], u__2[2], u__1[3], u__2[3],
u__1[4], u__2[4], u__1[5], u__2[5]
The trailing [] in [...][] acts like op([...]).
using Flatten gave me the desired solution
I have a list of Futures and I want to get the first one completed with a certain condition.
Here is an example of a possible code:
val futureList: Future[List[T]] = l map (c => c.functionWithFuture())
val data = for {
c <- futureList
}yield c
data onSuccess {
case x => (x filter (d=> d.condition)).head
}
But it's not efficient, because I'll take only one element of the list, but computed all of them with a lot of latency.
I know firstCompletedOf but it's not what I'm searching.
(Sorry for my bad English.)
Try using a Promise and calling trySuccess on it as soon as a future that satisfies the condition completes. The first to call trySuccess will complete the future, the following ones will have no effect (as opposed to calling success, which can only be called once on a Promise).
Keep in mind that if no future in the list satisfies the condition, you will never have a result, i.e. the promise future will never complete.
import scala.concurrent.{ Await, Future, Promise }
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Random
def condition(x: Int) = x > 50
val futures = (1 to 10) map (x => Future {
// wait a random number of ms between 0 and 1000
Thread.sleep(Random.nextInt(1000))
// return a random number < 100
Random.nextInt(100)
})
val p = Promise[Int]()
// the first one that satisfies the condition completes the promise
futures foreach { _ filter condition foreach p.trySuccess }
val result = p.future
// Watch out: the promise could never be fulfilled if all the futures are <=50
println("The first completed future that satisfies x>50 is: " + Await.result(result, 10.seconds))
I have the following simple example of an inter-thread communication problem: I want to run arbitrary "anytime" algorithms in a background thread. An anytime algorithm performs some computation of result type T incrementally, i.e., it sporadically produces newer, more precise results. In Nim parlance, they are probably best represented by an iterator. In the main thread, I now want to wrap such iterators each in its own thread, with the possibility to query the threads for things like "is there a new value available" or "what is the current computation result".
Since I'm not familiar with Nim's concurrency concepts I have trouble to implement the required inter-thread communication. My idea was to use a TChannel for the communication. According to this forum post, a TChannel cannot be used in combination with spawn but requires to use createThread. I managed to get the following to compile and run:
import os, threadpool
proc spawnBackgroundJob[T](f: iterator (): T): TChannel[T] =
type Args = tuple[iter: iterator (): T, channel: ptr TChannel[T]]
# I think I have to wrap the iterator to pass it to createThread
proc threadFunc(args: Args) {.thread.} =
echo "Thread is starting"
let iter = args.iter
var channel = args.channel[]
for i in iter():
echo "Sending ", i
channel.send(i)
var thread: TThread[Args]
var channel: TChannel[T]
channel.open()
let args = (f, channel.addr)
createThread(thread, threadFunc, args)
result = channel
# example use in some main thread:
iterator test(): int {.closure.} =
sleep(500)
yield 1
sleep(500)
yield 2
var channel = spawnBackgroundJob[int](test)
for i in 0 .. 10:
sleep(200)
echo channel.peek()
echo "Finished"
Unfortunately, this does not have the expected behavior, i.e., I never receive anything in the main thread. I was told on IRC that the problem is that I do not use global variables. But even after a long time thinking I neither do see exactly why this fails, nor if there is a way to solve it. The problem is that I cannot simply make the variables thread and channel global, since they depend on the type T. I also want to avoid restricting this to only run a single anytime algorithm (or some other fixed number N). I was also told that the approach does not really make sense overall, so maybe I'm just missing that this problem has an entirely different solution?
Reason:
You're using two different channels in send and recv.
object assign in Nim is deep copy, they're different object.
var channel = args.channel[]
and
result = channel
To explain it, see code snippet below:
type
A = object
x: int
y: int
var a,b: A
var c = cast[ptr A](allocShared0(sizeof(A))) # shared memory allocation
a = c[]
b = c[]
echo a.x, a.y, b.x, b.y, c.x, c.y # output: 000000
a.x = 1
a.y = 2
echo a.x, a.y, b.x, b.y, c.x, c.y # output: 120000
b.x = 3
b.y = 4
echo a.x, a.y, b.x, b.y, c.x, c.y # output: 123400
Solution to pass channel in and out proc:
To pass Channel as parameter and return value, please refer to Jehan's Answer in Nim forum.
paste Jehan's Answer here for quick reference, and make it compile pass in Nim 0.11.2
type SharedChannel[T] = ptr TChannel[T]
proc newSharedChannel[T](): SharedChannel[T] =
result = cast[SharedChannel[T]](allocShared0(sizeof(TChannel[T])))
open(result[])
proc close[T](ch: var SharedChannel[T]) =
close(ch[])
deallocShared(ch)
ch = nil
proc send[T](ch: SharedChannel[T], content: T) =
ch[].send(content)
proc recv[T](ch: SharedChannel[T]): T =
result = ch[].recv
proc someThread(ch: (SharedChannel[string], SharedChannel[bool])) {.thread.} =
let (mainChannel, responseChannel) = ch
while true:
let s = mainChannel.recv
if s == nil:
break
echo s
responseChannel.send(true)
responseChannel.send(false)
proc main() =
var
mainChannel = newSharedChannel[string]()
responseChannel = newSharedChannel[bool]()
th: TThread[(SharedChannel[string], SharedChannel[bool])]
createThread(th, someThread, (mainChannel, responseChannel))
for i in 0..2:
echo("main thread send: " & $i)
mainChannel.send($i)
if not responseChannel.recv:
break
mainChannel.send(nil)
joinThread(th)
close(mainChannel)
close(responseChannel)
main()
Output:
main thread send: 0
0
main thread send: 1
1
main thread send: 2
2
One more step, solution to this question:
import os, threadpool, macros
template spawnBackgroundJob(t: typedesc, chan:ptr TChannel[t], iter: expr): stmt {.immediate.}=
block:
proc threadFunc(channel: ptr TChannel[t]) {.thread.} =
echo "Thread is starting"
for i in iter:
echo "Sending ", i
channel[].send(i)
channel[].open()
var thread: TThread[ptr TChannel[t]]
createThread(thread, threadFunc, chan)
#joinThread(thread)
# example use in some main thread:
iterator testJob(): int =
yield 0
sleep(500)
yield 1
sleep(500)
yield 2
var channel: ptr TChannel[int]
channel = cast[ptr TChannel[int]](allocShared0(sizeof(TChannel[int])))
spawnBackgroundJob(type(int), channel, testJob())
for i in 1 .. 10:
sleep(200)
echo channel[].peek()
channel[].close()
I've wrote the following spec
"An IP4 address" should "belong to just one class" in {
val addrs = for {
a <- Gen.choose(0, 255)
b <- Gen.choose(0, 255)
c <- Gen.choose(0, 255)
d <- Gen.choose(0, 255)
} yield s"$a.$b.$c.$d"
forAll (addrs) { ip4s =>
var c: Int = 0
if (IP4_ClassA.unapply(ip4s).isDefined) c = c + 1
if (IP4_ClassB.unapply(ip4s).isDefined) c = c + 1
if (IP4_ClassC.unapply(ip4s).isDefined) c = c + 1
if (IP4_ClassD.unapply(ip4s).isDefined) c = c + 1
if (IP4_ClassE.unapply(ip4s).isDefined) c = c + 1
c should be (1)
}
}
That is very clear in its scope.
The test passes successfully but when I force it to fail (for example by commenting out one of the if statements) then ScalaCheck correctly reports the error but the message doesn't mention correctly the actual value used to evaluate the proposition. More specifically I get:
[info] An IP4 address
[info] - should belong to just one class *** FAILED ***
[info] TestFailedException was thrown during property evaluation.
[info] Message: 0 was not equal to 1
[info] Location: (NetSpec.scala:105)
[info] Occurred when passed generated values (
[info] arg0 = "" // 4 shrinks
[info] )
where you can see arg0 = "" // 4 shrinks doesn't show the value.
I've tried to add even a simple println statement to review the cases but the output appears to be trimmed. I get something like this
192.168.0.1
189.168.
189.
1
SOLUTION
import org.scalacheck.Prop.forAllNoShrink
import org.scalatest.prop.Checkers.check
"An IP4 address" should "belong to just one class" in {
val addrs = for {
a <- Gen.choose(0, 255)
b <- Gen.choose(0, 255)
c <- Gen.choose(0, 255)
d <- Gen.choose(0, 255)
} yield s"$a.$b.$c.$d"
check {
forAllNoShrink(addrs) { ip4s =>
var c: Int = 0
if (IP4.ClassA.unapply(ip4s).isDefined) c = c + 1
if (IP4.ClassB.unapply(ip4s).isDefined) c = c + 1
if (IP4.ClassC.unapply(ip4s).isDefined) c = c + 1
if (IP4.ClassD.unapply(ip4s).isDefined) c = c + 1
if (IP4.ClassE.unapply(ip4s).isDefined) c = c + 1
c == (1)
}
}
}
This is caused by ScalaCheck's test case simplification feature. ScalaCheck just sees that your generator produces a string value. Whenever it finds a value that makes your property false, it tries to simplify that value. In your case, it simplifies it four times until it ends up with an empty string, that still makes your property false.
So this is expected, although confusing, behavior. But you can improve the situation in three different ways.
You can select another data structure to represent your IP addresses. This will make ScalaCheck able to simplify your test cases in a more intelligent way. For example, use the following generator:
val addrs = Gen.listOfN(4, Gen.choose(0,255))
Now ScalaCheck knows that your generator only produces lists of length 4, and that it only contains numbers between 0 and 255. The test case simplification process will take this into account and not create any values that couldn't have been produced by the generator from start. You can do the conversion to string inside your property instead.
A second method is to add a filter directly to your generator, which tells ScalaCheck how an IP address string should look like. This filter is used during test case simplification. Define a function that checks for valid strings and attach it to your existing generator this way:
def validIP(ip: String): Boolean = ...
val validAddrs = addrs.suchThat(validIP)
forAll(validAddrs) { ... }
The third method is to simply disable the test case simplification feature altogether by using forAllNoShrink instead of forAll:
Prop.forAllNoShrink(addrs) { ... }
I should also mention that the two first methods require ScalaCheck version >= 1.11.0 to function properly.
UPDATE:
The listOfN list length is actually not respected by the shrinker any more, due to https://github.com/rickynils/scalacheck/issues/89. Hopefully this can be fixed in a future version of ScalaCheck.
I ve got the following class and I want to write some Spec test cases, but I am really new to it and I don't know how to start. My class do loke like this:
class Board{
val array = Array.fill(7)(Array.fill(6)(None:Option[Coin]))
def move(x:Int, coin:Coin) {
val y = array(x).indexOf(None)
require(y >= 0)
array(x)(y) = Some(coin)
}
def apply(x: Int, y: Int):Option[Coin] =
if (0 <= x && x < 7 && 0 <= y && y < 6) array(x)(y)
else None
def winner: Option[Coin] = winner(Cross).orElse(winner(Naught))
private def winner(coin:Coin):Option[Coin] = {
val rows = (0 until 6).map(y => (0 until 7).map( x => apply(x,y)))
val cols = (0 until 7).map(x => (0 until 6).map( y => apply(x,y)))
val dia1 = (0 until 4).map(x => (0 until 6).map( y => apply(x+y,y)))
val dia2 = (3 until 7).map(x => (0 until 6).map( y => apply(x-y,y)))
val slice = List.fill(4)(Some(coin))
if((rows ++ cols ++ dia1 ++ dia2).exists(_.containsSlice(slice)))
Some(coin)
else None
}
override def toString = {
val string = new StringBuilder
for(y <- 5 to 0 by -1; x <- 0 to 6){
string.append(apply(x, y).getOrElse("_"))
if (x == 6) string.append ("\n")
else string.append("|")
}
string.append("0 1 2 3 4 5 6\n").toString
}
}
Thank you!
I can only second Daniel's suggestion, because you'll end up with a more practical API by using TDD.
I also think that your application could be nicely tested with a mix of specs2 and ScalaCheck. Here the draft of a Specification to get you started:
import org.specs2._
import org.scalacheck.{Arbitrary, Gen}
class TestSpec extends Specification with ScalaCheck { def is =
"moving a coin in a column moves the coin to the nearest empty slot" ! e1^
"a coin wins if" ^
"a row contains 4 consecutive coins" ! e2^
"a column contains 4 consecutive coins" ! e3^
"a diagonal contains 4 consecutive coins" ! e4^
end
def e1 = check { (b: Board, x: Int, c: Coin) =>
try { b.move(x, c) } catch { case e => () }
// either there was a coin before somewhere in that column
// or there is now after the move
(0 until 6).exists(y => b(x, y).isDefined)
}
def e2 = pending
def e3 = pending
def e4 = pending
/**
* Random data for Coins, x position and Board
*/
implicit def arbitraryCoin: Arbitrary[Coin] = Arbitrary { Gen.oneOf(Cross, Naught) }
implicit def arbitraryXPosition: Arbitrary[Int] = Arbitrary { Gen.choose(0, 6) }
implicit def arbitraryBoardMove: Arbitrary[(Int, Coin)] = Arbitrary {
for {
coin <- arbitraryCoin.arbitrary
x <- arbitraryXPosition.arbitrary
} yield (x, coin)
}
implicit def arbitraryBoard: Arbitrary[Board] = Arbitrary {
for {
moves <- Gen.listOf1(arbitraryBoardMove.arbitrary)
} yield {
val board = new Board
moves.foreach { case (x, coin) =>
try { board.move(x, coin) } catch { case e => () }}
board
}
}
}
object Cross extends Coin {
override def toString = "x"
}
object Naught extends Coin {
override def toString = "o"
}
sealed trait Coin
The e1 property I've implemented is not the real thing because it doesn't really check that we moved the coin to the nearest empty slot, which is what your code and your API suggests. You will also want to change the generated data so that the Boards are generated with an alternation of x and o. That should be a great way to learn how to use ScalaCheck!
I suggest you throw all that code out -- well, save it somewhere, but start from zero using TDD.
The Specs2 site has plenty examples of how to write tests, but use TDD -- test driven design -- to do it. Adding tests after the fact is suboptimal, to say the least.
So, think of the most simple case you want to handle of the most simple feature, write a test for that, see it fail, write the code to fix it. Refactor if necessary, and repeat for the next most simple case.
If you want help with how to do TDD in general, I heartily endorse the videos about TDD available on Clean Coders. At the very least, watch the second part where Bob Martin writes a whole class TDD-style, from design to end.
If you know how to do testing in general but are confused about Scala or Specs, please be much more specific about what your questions are.