Rasterization of image - agda

I have a function ℚ -> ℚ -> Bool taking a Cartesian coordinate, where true stands for black and false for white. Is there any existing library that I can use to "rasterize" it into a bitmap image?

The PBM file format is a pretty simple text-based image file format. See https://en.wikipedia.org/wiki/Netpbm for a description. It's easy to write code to produce PBM files.
For the function λ x y → x ≤ᵇ y, the below code outputs the following PBM file contents:
P1
20 10
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
The lines mean the following:
P1 is a magic number that identifies the file format.
20 10 are the width and height of the image.
Each of the remaining lines represents one line of the image. 1 represents a black pixel and 0 a white pixel.
Put the above contents in a .pbm file (say, test.pbm) and you have something that you can open in image processing tools that support PBM files.
The makePBM function takes the width and height of the image to be produced, the x and y starting points in ℚ, the step to make in ℚ for each pixel in the x and y direction, and the ℚ → ℚ → Bool function to be evaluated.
--guardedness is only required, because I use IO for demonstration purposes.
{-# OPTIONS --guardedness #-}
module Raster where
open import Data.Bool using (Bool ; if_then_else_)
open import Data.Nat using (ℕ ; zero ; suc)
open import Data.Nat.Show using (show)
open import Data.Rational using (ℚ ; 0ℚ ; 1ℚ ; _+_ ; _≤ᵇ_)
open import Data.String using (String ; _++_)
open import IO using (Main ; run ; putStrLn)
-- width height offset-x offset-y step-x step-y function
makePBM : (w h : ℕ) → (ox oy sx sy : ℚ) → (ℚ → ℚ → Bool) → String
makePBM w h ox oy sx sy f = header ++ bitmap h oy
where
header : String
header = "P1\n" ++ show w ++ " " ++ show h ++ "\n"
row : (n : ℕ) → (x y : ℚ) → String
row zero x y = "\n"
row (suc n) x y = pixel ++ " " ++ row n (x + sx) y
where pixel = if f x y then "1" else "0"
bitmap : (n : ℕ) → (y : ℚ) → String
bitmap zero y = ""
bitmap (suc n) y = row w ox y ++ bitmap n (y + sy)
testPBM : String
testPBM = makePBM 20 10 0ℚ 0ℚ 1ℚ 1ℚ (λ x y → x ≤ᵇ y)
main : Main
main = run (putStrLn testPBM)

I'd be very surprised if there were. I'm not aware of any work on image manipulations in Agda.
Having said that, it should be relatively easy to do.
Create a m x n matrix of type Vector (Vector ℕ m) n from Data.Vec.Functional containing (i,j) at the ith row and jth column.
Map each (i,j) to the desired range of coordinates in the image.
Map the function f : ℚ -> ℚ -> Bool over each the entire matrix.

Related

Deedle - what is most efficient (fastest) way to replace an item in a column based on value of another item in another column on the same row

I have this data frame
AutoStat_1 AutoStat_2 Mode_1 Mode_2 Setpoint_1 Setpoint_2
0 -> 0 0 1 1 23 24
1 -> 0 1 1 0 23 27
2 -> 1 1 3 0 26 27
3 -> 1 0 3 1 26 24
4 -> 0 0 1 2 24 24
5 -> 0 0 1 2 24 24
6 -> 2 3 0 4 24 26
7 -> 2 3 0 4 25 26
The requirement is that if AutoStat_i is not 0 then Mode_i and Setpoint_i will be the value of the above (in-front) of which AutoStat_i is 0
The result should be (notice the column Setpoint_i and Mode_i are different than above)
AutoStat_1 AutoStat_2 Mode_1 Mode_2 Setpoint_1 Setpoint_2
0 -> 0 0 1 1 23 24
1 -> 0 1 1 1 23 24
2 -> 1 1 1 1 23 24
3 -> 1 0 1 1 23 24
4 -> 0 0 1 2 24 24
5 -> 0 0 1 2 24 24
6 -> 2 3 1 2 24 24
7 -> 2 3 1 2 24 24
What've I tried:
My idea is for each set i of (AutoStat_i, Mode_i, Setpoint_i), scan each row if AutoStat_i is <> 0 then set the other values to NaN, after that I will just do the fillMissing with Direction.Forward. Below is the impementation
let calculateNonSFi (df:Frame<_,string>) idx =
let autoStatusName = sprintf "AutoStat_%d" idx
let setpointName = sprintf "Setpoint_%d" idx
let modeName = sprintf "Mode_%d" idx
let setMissingOnMode (s:ObjectSeries<string>) =
let s2 = s.As<float>()
if s2.[autoStatusName] <> 0. then
Series.replaceArray [|setpointName;modeName|] Double.NaN s2
else
s2
df.Rows
|> Series.mapValues setMissingOnMode
|> Frame.ofRows
|> Frame.fillMissing Direction.Forward
|> Frame.fillMissing Direction.Backward
// for each set i do the folding
[0..150]
|> List.fold calculateNonSFi df
It gave me the expected results, however, for 150sets of 8000rows, it took more than 30 minutes to complete. I kinda see where it's wrong as for every set it acts on the whole dataset but I cannot think of a better way.
The logic is quite simple. I believe there should be a better way, do advice, thanks.
UPDATE
Here is the code for reproduction
open Deedle
open System
let df =
[
{| AutoStat_1=0;Setpoint_1=23;Mode_1=1;AutoStat_2=0;Setpoint_2=24;Mode_2=1|}
{| AutoStat_1=0;Setpoint_1=23;Mode_1=1;AutoStat_2=1;Setpoint_2=24;Mode_2=1|}
{| AutoStat_1=1;Setpoint_1=23;Mode_1=1;AutoStat_2=1;Setpoint_2=24;Mode_2=1|}
{| AutoStat_1=1;Setpoint_1=23;Mode_1=1;AutoStat_2=0;Setpoint_2=24;Mode_2=1|}
{| AutoStat_1=0;Setpoint_1=24;Mode_1=1;AutoStat_2=0;Setpoint_2=24;Mode_2=2|}
{| AutoStat_1=0;Setpoint_1=24;Mode_1=1;AutoStat_2=0;Setpoint_2=24;Mode_2=2|}
{| AutoStat_1=2;Setpoint_1=24;Mode_1=1;AutoStat_2=3;Setpoint_2=24;Mode_2=2|}
{| AutoStat_1=2;Setpoint_1=24;Mode_1=1;AutoStat_2=3;Setpoint_2=24;Mode_2=2|}
] |> Frame.ofRecords
df.Print()
let calculateNonSFi (df:Frame<_,string>) idx =
let autoStatusName = sprintf "AutoStat_%d" idx
let setpointName = sprintf "Setpoint_%d" idx
let modeName = sprintf "Mode_%d" idx
let setMissingOnMode (s:ObjectSeries<string>) =
let s2 = s.As<float>()
if s2.[autoStatusName] <> 0. then
Series.replaceArray [|setpointName;modeName|] Double.NaN s2
else
s2
df.Rows
|> Series.mapValues setMissingOnMode
|> Frame.ofRows
|> Frame.fillMissing Direction.Forward
let df1 =
[1..2]
|> List.fold calculateNonSFi df
df1.Print()
Advice/Answer from Tomas
df
|> Frame.mapRows (fun _ o ->
[ for i in 0 .. 150 do
let au = o.GetAs<float>("AutoStat_" + string i)
yield "AutoStat_" + string i, au
yield "Mode_" + string i, if au <> 0. then nan else o.GetAs("Mode_" + string i)
yield "Setpoint_" + string i, if au <> 0. then nan else o.GetAs("Setpoint_" + string i) ]
|> series )
|> Frame.ofRows
|> Frame.fillMissing Direction.Forward
which yields correct result but in different column order hence my mistake in the earlier edit
AutoStat_1 Mode_1 Setpoint_1 AutoStat_2 Mode_2 Setpoint_2
0 -> 0 1 23 0 1 24
1 -> 0 1 23 1 1 24
2 -> 1 1 23 1 1 24
3 -> 1 1 23 0 1 24
4 -> 0 1 24 0 2 24
5 -> 0 1 24 0 2 24
6 -> 2 1 24 3 2 24
7 -> 2 1 24 3 2 24
First of all, I think your strategy of setting Mode_i and Setpoint_i to NA when AutoStat_i is not 0 and then filling the missing values is a nice approach.
You can certainly make it a bit faster by moving the fillMissing call outside of the calculateNonSFi function - the fillMissing operation will run on the whole frame, so you need to run this once at the end.
The second thing would be to find a way of setting the NA values that only iterates over the frame once. One option (I have not tested this) would be to use Frame.mapRows and, inside the function, iterate over all the columns (rather than iterating over all the columns and calling mapRows repeatedly). Something like:
df
|> Frame.mapRows (fun _ o ->
[ for i in 0 .. 150 do
let au = o.GetAs<float>("AutoStat_" + string i)
yield "AutoStat_" + string i, au
yield "Mode_" + string i, if au = 0. then nan else o.GetAs("Mode_" + string i)
yield "Setpoint_" + string i, if au = 0. then nan else o.GetAs("Setpoint_" + string i) ]
|> series )
|> Frame.ofRows

Changing to a horizontal stack display with GNU dc?

GNU DC displays the stack vertically, (f displays the stack)
1 2 3 4
f # to display the stack
4
3
2
1
Is there a way to change this to be more like FORTH? While GNU FORTH displays the stack horizontally, (.s displays the stack)
1 2 3 4 ok
.s <4> 1 2 3 4 ok
You can create custom function in ~/.dcrc which is read each time dc start.
cat ~/.dcrc
[
# if the stack is empty
[ 2 + [stack empty] p 0 :- Q ]s-
z d 0 =- 0 :-
# keep the stack in indexed array -
[ z :- z 0 <- ]s-
l-x
# restore the stack
[ 0 ;- 1 + d ;- ;- r d ;- 1 + r :- 0 ;- d 1 + ;- r !<- ]s-
1 0 ;- 1 + :-
l-x
# displays the stack horizontally
[ 0 ;- d 1 + d ;- ;- n [ ] n d d ;- 1 + r :- ;- !>- ]s-
1 0 ;- 1 + :- l-x [ ok] p 0 :-
]s-
You call it this way :
echo '7 16 8 9' | dc -f - -e 'l-x f'
and you get :
7 16 8 9 ok
9
8
16
7
You cannot use register -

Construct DFA for L = {(na(w)-nb(w)) mod 3>0}

As per the title:
L = {(na(w)-nb(w)) mod 3>0}
Alphabet = {a,b}
I found two answers to this problem:
In this solution, our language is accepted.
However,
w = b
is accepted as well.
In the next solution:
Our problem of
w = b
is solved here but
w = aaab
is not accepted.
How do I approach this problem? I couldn't find a suitable answer for it on the internet.
Assume we have the following definition of mod:
x mod y = { x, if 0 <= x < y
(x - y) mod y, if 0 < y <= x
x, if -y < x < 0
(x + y) mod y, if x <= -y < 0
-(-x mod -y) if y < 0
}
So our modulus works like this:
3 mod 5 = 3
6 mod 5 = 6-5 mod 5 = 1 mod 5 = 1
-3 mod 5 = -3
-6 mod 5 = -6+5 mod 5 = -1 mod 5 = -1
-6 mod -5 = -(6 mod 5) = -1
6 mod -5 = -(-6 mod 5) = -(-1) = 1
Our language is L = {(n_a(w) - n_b(w)) mod 3 > 0}
Let's define A := n_a(w) and B := n_b(w). So we need to solve (A - B) mod 3 > 0 using our definition of mod. We have five cases:
if 0 <= A - B < 3, meaning B <= A < B + 3, then (A - B) mod 3 = A - B. By hypothesis it is at least zero, and can only be zero then if A = B. We can confirm that when A = B we are always in case #1 and we always have (A - B) mod 3 > 0 false, so we can throw that possibility out.
if 0 < 3 <= A - B, meaning B < 3 + B <= A or simply A >= 3 + B, then (A - B) mod 3 = (A - B - 3) mod 3. By the hypothesis, A - B - 3 >= 3 + B - B - 3 >= 0, so we are still in either case 1 or 2. If we remain in case 2, we can repeat this until we eventually reach case 1, and we will see that we cannot have A - B - 3k = 0; that is, it cannot be that A = B + 3k for any positive k.
if -3 < A - B < 0, or B - 3 < A < B, then (A - B) mod 3 = A - B. By the hypothesis it is less than zero, and so we must throw out all of these possibilities.
if A - B <= -3 < 0, meaning A <= B - 3 < B or simply A <= B - 3 then (A - B) mod 3 = (A - B + 3) mod 3. By the hypothesis, A - B + 3 <= B - 3 - B + 3 = 0, so we are still in either case 3 or 4. If we remain in case 4, we can repeat this until we eventually reach case 3, and we will see nothing remains.
We cannot be in this case since 3 > 0.
We had to throw out the following strings from our language:
A = B
A = B + 3k
A < B.
So we keep only strings with more a's than b's where A - B is not divisible by 3. Suppose this language were regular. Consider the string (b^p)(a^(p+1)) in the language. By the pumping lemma, we should be able to pump the number of bs; but then we could get more bs than as. So the language cannot be regular.
If we take what is maybe a more usual definition for x mod y (not more correct, necessarily):
x mod y = { x , if 0 <= x < y
(x - y) , if 0 < y <= x
(x + y) mod y , if -y < x < 0
-(-x mod -y) , if y < 0
}
By this definition:
in case 1, we throw out A = B
in case 2, we throw out A = B + 3k
in case 3, we throw out A = B - 3k
since 3 > 0, case 4 doesn't apply
Now we have only thrown out the cases where A mod B = 0 (mod 3). This language is regular and has DFA:
+------------a-------------+
| |
| +---b----+ +---b----+ |
| | | | | |
V V | V | |
(q0)---a--->(q1)---a--->(q2)
--->(q0)
(q0)---b--->(q3)---b--->(q4)
^ ^ | ^ | |
| | | | | |
| +---a----+ +---a----+ |
| |
+------------b-------------+

How to convert this grammar to LL(1)?

S → Y | 1X
X → 1X | 0
Y → Y 0 | 1X1 | 2X2
I do not understand how to do factoring or substitution when there are more than one of the same symbol. Thanking you.
X → 1 X | 0
refers to a 0-or-more 1 followed by 0, so it's equivalent to
X → 1* 0
The same approach can be used to remove your left-recursion. You can rewrite
S → Y | 1 X
X → 1 X | 0
Y → Y 0 | 1 X 1 | 2 X 2
as
S → Y | 1 X
X → 1* 0
Y → ( 1 X 1 | 2 X 2 )* 0
In EBNF:
S → Y | 1 X
X → 1* 0
Y → A* 0
A → 1 X 1 | 2 X 2
In BNF:
S → Y | 1 X
X → 1* 0
Y → A* 0
A → 1 X 1 | 2 X 2
1* → 1 1* | Ɛ
A* → A A* | Ɛ
If all you wanted to do was to eliminated left-recursion, you're done.
If you want to eliminate common prefixes too, you're not done because both sub-rules of S can start with 1 X. To fix this, inline and distribute to obtain the following:
S → 0
| 1 X 1 Y
| 2 X 2 Y
| 1 X
X → 1* 0
Y → A* 0
A → 1 X 1 | 2 X 2
Now, we're finally in a position to factor out the common 1 X.
S → 0
| 1 X ( 1 Y )?
| 2 X 2 Y
X → 1* 0
Y → A* 0
A → 1 X 1 | 2 X 2
In EBNF:
S → 0 | 1 X B? | 2 X 2 Y
X → 1* 0
Y → A* 0
A → 1 X 1 | 2 X 2
B → 1 Y
In BNF:
S → 0 | 1 X B? | 2 X 2 Y
X → 1* 0
Y → A* 0
A → 1 X 1 | 2 X 2
B → 1 Y
B? → B | Ɛ
1* → 1 1* | Ɛ
A* → A A* | Ɛ

Truth table to prove an argument true/false

Can someone help me out with truth tables? I would like to create a truth table to prove whether or not this is true.
A B C B∧C A∨(B∧C) A ∨ B A ∧ C (A ∨ B) ∨ (A ∧ C)
0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 1 0 0 0 1 0 1
0 1 1 1 1 1 0 1
1 0 0 0 1 1 0 1
1 0 1 0 1 1 1 1
1 1 0 0 1 1 0 1
1 1 1 1 1 1 1 1
When A=0, B=1 and C=0
A ∨ (B ∧ C) = 0
(A ∨ B) ∨ (A ∧ C) = 1 ∨ 0 = 1
So A ∨ (B ∧ C) = A ∨ B) ∨ (A ∧ C) is false.
A = 0, B = 0, C = 0
A ∨ (B ∧ C) = 0 ∨ (0 ∧ 0) = 0 ∨ 0 = 0
(A ∨ B) ∨ (A ∧ C) = 0
Do the similar for the 7 more combination of A, B and C.
A = 0, B = 0, C = 1
A = 0, B = 1, C = 0
//// etc.
If you find both end same for all the eight then that is proved. Otherwise the are not same.
Also visit the Wikipedia entry for truth table for the details. Application section contains an example proof of another equation.
Note: Sounds like a homework. So not providing the full solution.
You only have three boolean variables, which means a 2^3=8 entry truth table will suffice. I suggest breaking down columns in your table to produce one boolean result at a time. If the two columns of the two sides of your boolean equation match, them you proved they are the same, otherwise you will have one or more counter-examples.
If the two expressions match, then you can try to prove they are equal using the rules of Boolean algebra. Karnaugh maps could even be used to point the way.

Resources