Not able to apply guard expression in query list comprehension - erlang

I am trying a query list comprehension:
> (set xs '(1 2 3 4 5 6 7 8))
> (lc ((<- x xs) (when (> x 5))) x)
But I am getting the error exception error: undefined function when/1.
Is it possible to apply guard statements to lc?

According to the LFE User Guide, within a list comprehension qualifier, the guard must precede the list expression:
(<- pat {{guard}} list-expr)
This means your example should be written as follows:
lfe> (set xs '(1 2 3 4 5 6 7 8))
(1 2 3 4 5 6 7 8)
lfe> (lc ((<- x (when (> x 5)) xs)) x)
(6 7 8)
You could alternatively treat the greater-than expression as a normal boolean expression qualifier:
lfe> (lc ((<- x xs) (> x 5)) x)
(6 7 8)

Related

Interacting in agda-mode with agda?

It feels super awkward to interact with agda.
Consider the proof state:
_ = begin
5 ∸ 3
≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ { 2 <cursor-goes-here> }0
When I type C-c C-l (type-check), it says
?0 : 2 ∸ 0 ≡ _y_131
_y_131 : ℕ [ at /home/bollu/work/plfa/src/plfa/part1/Naturals.lagda.md:586,5-10 ]
which doesn't seem like a great error? Nor does a refine (C-c C-r) give me a good error message: It only tells me:
cannot refine
How do I get adga to tell me:
You've finished the proof, except for a missing \qed
In general, what is the "preferred mode of interaction" when building proofs?
The overall issue
Your post starts by the following assumption:
It feels super awkward to interact with agda.
The reason that could explain your feeling is that you seem to assume that Agda can both infer a term and its type, in other words, both the property you wish to prove and a proof of it. Agda can often do one of these, but asking for both does not make much sense. As a comparison, imagine being on a bench in a park, when a complete strangers comes and sits next to you, saying nothing. You can see he would very much enjoy to ask you something, but, despite your efforts at making him speak, he remains silent. After a few minutes, the stranger yells at you that, despite him being thirsty, you did not bring the drink he was expected. In this metaphor, the stranger is you, and you are Agda. There is no way you could have known he was thirsty, and even less bring him his drink.
Concretely
You gave the following piece of code:
_ = begin
5 ∸ 3 ≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ { 2 <cursor-goes-here> }0
This piece of code lacks a type signature which will allow Agda to help you more. Agda tells you so when you type check by providing you with the inferred type of the goal:
?0 : 2 ∸ 0 ≡ _y_131
_y_131 : ℕ [ at /home/bollu/work/plfa/src/plfa/part1/Naturals.lagda.md:586,5-10 ]
Here Agda says that your proof goal is that 2 ∸ 0 is equal to some unknown natural number y. This number being unknown there is very little chance Agda can help you go further in your proof effort because it does not even know what you wish to prove. As far as it knows, your goal could turn out to be 5 ∸ 3 ≡ 3 for wish there exists no proof term.
Getting back to our metaphor, you lacks the statement "I am thirsty". Should the stranger provide this piece of information, you could - possibly - react, which means Agda can try and help.
The solution
I'm assuming you wish to prove that the result of your subtraction is two, in which case the code is as follows:
test : 5 ∸ 3 ≡ 2
test = begin
5 ∸ 3 ≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ {!!}
In this case, you can interact with Agda in various ways, which all lead to Agda providing you with a sound proof term:
You can call Agsy to solve the problem for you (CTRL-c CTRL-a), which leads to:
test : 5 ∸ 3 ≡ 2
test = begin
5 ∸ 3 ≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ refl
You can try and refine the goal directly (CTRL-c CTRL-r), asking Agda if there exists any unique constructor which has the right type, which leads to the same:
test : 5 ∸ 3 ≡ 2
test = begin
5 ∸ 3 ≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ refl
If you wish to wrap up your proof using \qed you can try and input _∎ into the hole after which refining (CTRL-c CTRL-r) gives:
test : 5 ∸ 3 ≡ 2
test = begin
5 ∸ 3 ≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ {!!} ∎
Calling Agsy in the resulting goal naturally gives:
test : 5 ∸ 3 ≡ 2
test = begin
5 ∸ 3 ≡⟨⟩
4 ∸ 2 ≡⟨⟩
3 ∸ 1 ≡⟨⟩
2 ∸ 0 ≡⟨⟩ 2 ∎

Total sum across wide range of specific cells

Okay, so suppose we have the data set up like so:
Area 1 10 sq m
Wall 1 5 sq m
Wall 2 6 sq m
Wall 3 5 sq m
Wall 4 6 sq m
Area 2 21 sq m
Wall 1 7 sq m
Wall 2 4 sq m
Window 1 2 sq m
Wall 3 7 sq m
Window 2 2 sq m
Wall 4 4 sq m
And in another sheet, the data is to be presented like so:
Total interior wall area __ sq m
Area 1 __ sq m
Area 2 __ sq m
Total floor area __ sq m
Area 1 __ sq m
Area 2 __ sq m
How would I do this automatically?
What I was thinking is:
Look for cells with a specific tag (like "wall") in them
Get the number value to the right, under the "AREA" column
Get the sum of all those values
My problem with this algorithm is that I do not know how to execute it, not knowing the specific functions needed. Or, maybe there are other ways to do this with specific functions that I do not know of. Thank you very much to those who would answer, this is my first question on this website.
=ARRAYFORMULA({SUM(FILTER(D1:D, REGEXMATCH(LOWER(B1:B), "wall")));
QUERY({IF(A1:A<>"", A1:A, IF(B1:B="",,VLOOKUP(ROW(A1:A),
IF(A1:A<>"", {ROW(A1:A), A1:A}), 2, 1))), B1:B, D1:D},
"select sum(Col3)
where lower(Col2) contains 'wall'
group by Col1
label sum(Col3)''", 0)})

Dask distributed executes tasks sequentially

I have a pipeline working with LocalCluster:
from distributed import Client
client = Client()
list_of_queries = [...] # say 1_000 queries
loaded_data = client.map(sql_data_loader, list_of_queries)
processed_data = client.map(data_processor, loaded_data)
writer_results = client.map(data_writer, processed_data)
results = client.gather(writer_results)
Everything works, but not quite as I would expect.
Looking at dashboard's status page I see somethings like this:
sql_data_loader 900 / 1000
data_processor 0 / 1000
data_writer 0 / 1000
I.e. tasks are executed sequentially as opposed to "in parallel". As a result data_processor does not start executing until all 1000 queries have been loaded. And data_writer waits until 'data_processor' finishes processing all its futures.
Based on previous experience with dask where dask.delayed was used instead of client.map
expected behavior would be something like:
sql_data_loader 50 / 1000
data_processor 10 / 1000
data_writer 5 / 1000
Is this a false expectation or is there something I am missing with how to set up pipeline to ensure behavior that would be similar to dask.delayed?
If you run the maps one after the other then everything should pipeline nicely.
There is some tension between two desired objectives:
Tasks should pipeline, as you like
Tasks that are submitted first should have higher priority
To balance between these two objectives Dask assigns policies based on the delay between calls. If two map calls happen right after each other then Dask assumes that they're part of the same computation, however if they are separated by a significant amount of time then Dask assumes that they are different computations, and so prioritizes the earlier tasks. You can control this with the fifo_timeout keyword
client.map(f, ..., fifo_timeout='10 minutes')
Here is the relevant documentation page
Here is an example showing the behavior you want if you bundle map calls together:
In [1]: from dask.distributed import Client
In [2]: client = Client(processes=False)
In [3]: import time
In [4]: def f(x):
...: time.sleep(0.1)
...: print('f', x)
...: return x
...:
In [5]: def g(x):
...: time.sleep(0.1)
...: print('g', x)
...: return x
...:
In [6]: futures = client.map(f, range(20))
...: futures = client.map(g, futures)
...:
In [7]: f 0
f 1
f 2
f 3
f 5
f 4
f 6
f 7
g 0
g 1
g 3
g 2
g 4
g 5
g 6
g 7
f 8
f 9
f 10
f 11
f 12
g 8
f 13
g 9
g 10
g 11
g 12
f 14
g 13
f 15
f 16
f 17
g 14
f 18
g 15
f 19
g 16
g 17
g 18
g 19

Infix to postfix for negative numbers

How do I convert negative numbers from infix to postfix ?
Suppose I have a expression
a = - b - (-c-d)
In some places I read that you can parathesize the negative numbers like
a = (-b) - (-c-d)
But here if I do that, I will get a term like "ab-" at the beginning of the postfix expression which means a-b and is incorrect.
How do I convert this ?
In infix notation, you must distinguish between the binary subtraction operator sub and the unary negation operator neg. Both are represented by a minus sign, but the context tells you which is which.
You've got a negation, when the minus as at the beginning of the expression, or after an opening parenthesis or after a binary operator:
    − (x + y)   →   x y add neg
    4 × − x   →   4 x neg mult
    2 × (− x + y)   →   2 x neg y add mult
You've got a subtraction when the minus is after a closing parenthesis or after a symbol, i.e. after a variable or number:
    1 − x   →   1 x sub
    (4 ∗ x) − 1   →   4 x mult 1 sub
Take care that the unary operator neg just takes one argument off the stack. If you want to stick with binary operators, you can push a zero before the second operand and use binary sub:
    − (x + y)   →   0 x y add sub
    4 x neg mult   →  4 0 x sub mult
    2 x neg y add mult   →   2 0 x sub y add mult
Finally, you can apply a similar logic to unary plus, which you can just ignore:
    + x   →   x
    + (x + y)   →   x y add

When converting from infix to postfix, how do you specify between a uniary and a binary +/-

Under this grammar:
^ + - * / < > = <= >= and or not
I'm using a function (shunting-yard algorithm) to convert from infix to postfix and it works! Except it doesn't include the unary - meaning negate and the unary + which doesn't really do much of anything.
Once converted to post fix, a unary + will be a p and a unary - with be a m. For example:
3 + 3 -> 3 3 +
+3 + 3 -> 3 p 3 +
-(3-3) -> 3 3 - m
So if I am reading an infix expression, how do I specify between a unary and binary plus and minus?
It seems to me that the following rule would apply.
The first + or - following a non-operator is a binary operator. Subsequent occurrences (or an occurrence at the start of an expression) are unary.
So, in your (and a couple of extra) examples:
3 + 3 --> 3 binary+ 3
+ 3 + 3 --> unary+ 3 binary+ 3
- ( 3 - 3) --> unary- ( 3 binary- 3)
-9--4 --> unary- 9 binary- unary- 4

Resources