Re: [Haskell-cafe] ANN: atom-0.1.3

2010-01-18 Thread miaubiz


Tom Hawkins-2 wrote:
> 
> Would you explain what you are trying to do a bet more clearly?
> 

Certainly.  I am writing an autonomous rover.  To choose the direction to
drive towards, the car compares the direction it wants to go with the
direction it is actually facing.  To avoid continuously zigzagging I have
hysteresis set around the target direction.

1. I have a set of test inputs
2. I want to run my atoms
3. I want to verify that the state of my atom matches a specific state after
each iteration

t2 = defaultTest {
  testbench = steeringVsBearing
 ,declCode = header fakeHeaders
 ,cycles = (length testData)
}

steeringVsBearing :: Atom () -- this is only a test
steeringVsBearing = do
  steering <- word8' "steering"
  targetHeadings <- array "targetHeadings"  ([target | (target, _, _) <-
testData])
  actualHeadings <- array "actualHeadings"  ([actual | (_, actual, _) <-
testData])
  expectedSteerings <- array "expectedSteerings" ([steerings |(_, _,
steerings) <- testData]) 
  targetHeading <== targets !. clock
  compass <== actuals !. clock

  navigate --this is my production atom
  assert "steeringWorks" $ (value steering) ==. (expectedSteerings !. clock)

navigate = do
  steering <- word8' "steering"
  
  period 1 $ atom "figureOutWhichWayToGo" $ do
 --calculate steering based on target heading and actual heading
 --blah blah
steering' <- do return $ mux l1 (mux r1 75 90) 105
steering <== steering'


Tom Hawkins-2 wrote:
> 
>> output <- word16' "output"
>> input <- word16' "input"
>>
>> input <== inputs !. clock
> 
> There are a few potential problems with this statement.  First,
> 'input' in an external variable -- which is fine, just be sure nothing
> is being assigned to it in the external c code.  Note, if 'input' is
> not referenced by external code, then 'word16 "input" 0' would be a
> better variable declaration.
> 

I used an external variable because I wanted to reference it both in
steeringVsBearing which is a test function, and the actual function
navigate.  


Tom Hawkins-2 wrote:
> 
> The second problem is a bit more serious.  By using the 'clock' as an
> array index, it will eventually go outside the bounds of the array.
> Beware: Atom provides no array checks, such as index-out-of-bounds, or
> assigning the same array location multiple times within the same
> atomic action.
> 

ok.  I am using clock as an index in the test function only. 


Tom Hawkins-2 wrote:
> 
>> doStuff
>> assert "fiveIsAdded" $ (value output) ==. (expected !. clock)
> 
> Keep in mind than multiple rules will fire in one 'clock' cycle, and
> assertions are checked between the execution of each rule.  In this
> case, the assertion will be checked before the top level rule that
> contains the assignment 'input <== inputs !. clock', and before the
> "addFive" rule.  In both cases 'clock' will have the same value, which
> will probably lead to an assertion violation.
> 

I am unable to come up with any assertions that would be valid all the time,
which would allow me to feed test data into my atoms and then verifying them
against some known inputs.

I have some other asserts that I find helpful, such as (minus the spaces):

  assert "target is closer than 1800 to actual" (target' - actual' <=. 1800)
  assert "target is closer than 1800 to actual'" (actual' - target' <=.
1800)

but checking that the steering is valid is more difficult because it depends
on the previous state of steering due to hysteresis.

I don't want to replicate the logic of hysteresis in the assertion:

assert "steeringWorks" $ mux (previousSteering `lt_` 90) mux
(currentSteering `gt_` 90) etc etc etc.


Tom Hawkins-2 wrote:
> 
>>
>> doStuff
>>  atom "addFive" $ period 1 $ do
>>    output <== (value input 5) + 5
> 
> This last statement should yield a type violation.  "(value input 5)".
> 

that was a typo on my part. 

I assume I am totally off on my testing attempt, and if you could point me
in the right direction I would greatly appreciate it.

Br, 
Miau

-- 
View this message in context: 
http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27212766.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: atom-0.1.3

2010-01-18 Thread Tom Hawkins
On Mon, Jan 18, 2010 at 3:19 PM, miaubiz  wrote:
>
> how should I feed test data into my system?
>
> I am having quite a bit of trouble with testing an atom with hysteresis
> because I always end up having an assertion fire before and after my test
> data is updated.

Would you explain what you are trying to do a bet more clearly?

>
> I have essentially the following code:
>
> inputs = [1, 2, 3, 4, 5]
> expected = [6, 7, 8, 9, 10]

I'm assuming you mean:

inputs <- array [1,2,3,4,5]

>
> output <- word16' "output"
> input <- word16' "input"
>
> input <== inputs !. clock

There are a few potential problems with this statement.  First,
'input' in an external variable -- which is fine, just be sure nothing
is being assigned to it in the external c code.  Note, if 'input' is
not referenced by external code, then 'word16 "input" 0' would be a
better variable declaration.

The second problem is a bit more serious.  By using the 'clock' as an
array index, it will eventually go outside the bounds of the array.
Beware: Atom provides no array checks, such as index-out-of-bounds, or
assigning the same array location multiple times within the same
atomic action.

> doStuff
> assert "fiveIsAdded" $ (value output) ==. (expected !. clock)

Keep in mind than multiple rules will fire in one 'clock' cycle, and
assertions are checked between the execution of each rule.  In this
case, the assertion will be checked before the top level rule that
contains the assignment 'input <== inputs !. clock', and before the
"addFive" rule.  In both cases 'clock' will have the same value, which
will probably lead to an assertion violation.

>
> doStuff
>  atom "addFive" $ period 1 $ do
>    output <== (value input 5) + 5

This last statement should yield a type violation.  "(value input 5)".


If your intention is to copy an array, and add 5 to each element, here
is some code they may be what you're looking for:

inputs <- array "inputs" [0, 1, 2, 3, 4]
outputs <- array "outputs" [0, 0, 0, 0, 0]

index <- word8 "index" 0

atom "copyElement" $ do
  cond $ (value index) <. 5   -- Only copy elements if the index is
within the bounds of the array.
  outputs ! (value index) <== inputs !. (value index) + 5
  incr index


Another rule could then reset the index when new data is available to
be copied.  This will then wakeup the copyElement rule to start the
copy process again.

atom "restartCopy" $ do
  cond newDataReady
  index <== 0
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: atom-0.1.3

2010-01-18 Thread miaubiz


Tom Hawkins-2 wrote:
> 
> If you are using the latest version of Atom, asserts are checked
> between the execution of every rule.  The way you've coded it, it may
> appear as if the assertions are checked along with the associated
> rules, but this is not the case.  And not only are the assertions not
> checked with the rules, they don't follow the period or phase
> constraints either.  So what you have is essentially 2 assertions that
> are being checked at every time instance and between every atom state
> update.
> 

how should I feed test data into my system?

I am having quite a bit of trouble with testing an atom with hysteresis
because I always end up having an assertion fire before and after my test
data is updated.

I have essentially the following code:

inputs = [1, 2, 3, 4, 5]
expected = [6, 7, 8, 9, 10]

output <- word16' "output"
input <- word16' "input"

input <== inputs !. clock
doStuff
assert "fiveIsAdded" $ (value output) ==. (expected !. clock)

doStuff
  atom "addFive" $ period 1 $ do
output <== (value input 5) + 5
...

the only way I am able to write assertions is to duplicate the logic of
hysteresis into the assertions, which is not a reasonable way to go for me.  


Tom Hawkins-2 wrote:
> 
>> because covered is the second word of the line from the log, the name of
>> cover must be a single word. assertions and atoms can contain spaces as
>> far
>> as I can tell.
> 
> No, they really shouldn't.  I've been meaning to add some checks to
> enforce some naming rules, but haven't gotten around to it.
> 

good to know.  thanks for the heads up.

br, 
miau
-- 
View this message in context: 
http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27211086.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: atom-0.1.3

2010-01-17 Thread Tom Hawkins
On Sun, Jan 17, 2010 at 1:16 PM, miaubiz  wrote:
>
> I am trying to generate a square wave.  Here's the code:
>
>    square <- bool "square" False
>
>    period 2 $ atom "square high" $ phase 0 $ do
>        square <== true
>        assert "square is low" $ not_ $ value square
>
>    period 2 $ atom "square low" $ phase 1 $ do
>        square <== false
>        assert "square is high" $ value square
>
>
> The tests fail every cycle because after each rule one of them is wrong.

If you are using the latest version of Atom, asserts are checked
between the execution of every rule.  The way you've coded it, it may
appear as if the assertions are checked along with the associated
rules, but this is not the case.  And not only are the assertions not
checked with the rules, they don't follow the period or phase
constraints either.  So what you have is essentially 2 assertions that
are being checked at every time instance and between every atom state
update.

>
> What would be the right way to formulate this code? Use cond on the rules?
>
>    period 2 $ atom "square high" $ phase 0 $ do
>        cond $ not_ $ value square
>        square <== true
>        cover "lowSquare" true
>        assert "square is low" $ not_ $ value square
>
>    period 2 $ atom "square low" $ phase 1 $ do
>        cond $ value square
>        square <== false
>        cover "highSquare" true
>        assert "square is high" $ value square
>
>

Yes, guard conditions would help.  Guards are hierarchical; they apply
to all the sub Atom rules and assertions.  As such ...

  cond $ not_ $ value square
  assert "squareIsLow" $ not_ $ value square

.. is a redundant because the guard condition is the same as the
assertion.  The guard will only allow the assertion to be checked if
'square' is false, and if it does, the assertion is guaranteed to
pass.

An easier way to write a square wave is this...

square <- bool "square" False

period 2 $ atom "toggle" $ do
  square <== not_ (value square)


> as an aside, in Unit.hs:
>         covered = [ words line !! 1 | line <- lines log, isPrefixOf
> "covered:" line ]
>
> because covered is the second word of the line from the log, the name of
> cover must be a single word. assertions and atoms can contain spaces as far
> as I can tell.

No, they really shouldn't.  I've been meaning to add some checks to
enforce some naming rules, but haven't gotten around to it.

I hope this helps.

-Tom

>
> br, miau
> --
> View this message in context: 
> http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27198213.html
> Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: atom-0.1.3

2010-01-17 Thread miaubiz



Tom Hawkins-2 wrote:
> 
> period 20 $ atom "checkSomeStuff" $ do
>   cond ok
>   assert "A" a
>   assert "B" b
>   cover  "C" c
> 

I am trying to generate a square wave.  Here's the code:

square <- bool "square" False

period 2 $ atom "square high" $ phase 0 $ do
square <== true
assert "square is low" $ not_ $ value square

period 2 $ atom "square low" $ phase 1 $ do
square <== false
assert "square is high" $ value square


The tests fail every cycle because after each rule one of them is wrong.

What would be the right way to formulate this code? Use cond on the rules?

period 2 $ atom "square high" $ phase 0 $ do
cond $ not_ $ value square
square <== true
cover "lowSquare" true
assert "square is low" $ not_ $ value square

period 2 $ atom "square low" $ phase 1 $ do
cond $ value square
square <== false
cover "highSquare" true
assert "square is high" $ value square


as an aside, in Unit.hs:
 covered = [ words line !! 1 | line <- lines log, isPrefixOf
"covered:" line ]

because covered is the second word of the line from the log, the name of
cover must be a single word. assertions and atoms can contain spaces as far
as I can tell.

br, miau
-- 
View this message in context: 
http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27198213.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] ANN: atom-0.1.3

2009-12-03 Thread Tom Hawkins
This release of Atom slightly changes the semantics of assertions and
coverage.  Assertion and coverage are now checked between the
execution of every rule, instead of only when the rules containing
assertions are fired.  They are still subject to parental guard
conditions, but not period or phase constraints.  This means...

period 20 $ atom "checkSomeStuff" $ do
  cond ok
  assert "A" a
  assert "B" b
  cover  "C" c

... A, B, and C are checked all the time "ok" is true, not just every
20th cycle.

Checking between every rule execution obviously impacts simulation
time, but the increased testing rigor is worth it.

I also added 'linear' to Common, which does linear interpolation and
extrapolation on a line given two points.  (I found I was replicating
this function everywhere for sensor calibrations, control limits,
etc.)

http://hackage.haskell.org/package/atom
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe