Is there a difference in my code and output? - stack

Just a quick question regarding stack.
I hope there wouldn't be any down vote.
S1 = stack()
s2 = stack()
does S2.push(s1.pop()) is the same as S1.pop(S2.push())
I'm trying to invert the stack of S1 with the help of S2
Eg. if the number 3 is at the top of the stack S1, after calling s1.invert(), 3 will be at the bottom of s1

Related

PDA for {a^n b^m | n<=m<=2n}

Can someone help me design PDA for {a^n b^m | n<=m<=2n}. Can you please design one with explanation.
The idea here is this: read every a and push a symbol onto the stack for each one. Then, when you start reading b's, at each step, nondeterministically choose whether to read a single b and pop one stack symbol, or whether two read two b's and pop one stack symbol. Then, make the PDA accept if the input is exhausted and the stack is empty.
if you always choose to pop one stack symbol for each b read, then you get m = n
if you always choose to pop one stack symbol for every pair of b read, then you get m = 2n
if you sometimes choose to read one b and sometimes two, then you end up with n < m < 2n; n < m because sometimes you read more b than you had stack symbols for, m < 2n because sometimes you only read one b and popped from the stack
NPDAs accept if at least one path ends up accepting; so, as long as some pattern of guessing to read one or two b's for each stack symbol gets the right value of m, the string is accepted. It should be clear that for any value of m such that n <= m <= 2n, there is a solution to the linear system:
x + 2y = m
x + y = n
Here, x is the number of times the NPDA should guess that it reads one b, and y is the number of times the NPDA should guess that it reads two b's. We can subtract the 2nd from the 1st:
y = m - n
Because y must be nonnegative, we get our first condition, n <= m. Plugging this back into the 2nd origination equation gives:
x + m - n = n
<=> x = 2n - m
Again, because x must be nonnegative, this gives our second condition, m <= 2n.
Nondeterministically, push one or two as into the stack in each reading of an a and then match the incoming bs with the pushed as.

Rules to convert a CFG to a NDPA?

I have to define an FA by using this grammar:
S -> aSb
S -> c
S -> dA
A -> Sd
How do I manage the first rule and the last one?
For the second one I think I have to create another state (the final one) and link S and this new state. For the third one instead, I think I have to create the state "A" and link it to S by passing "d".
There are algorithms you can use to get a PDA from a CFG: look into top-down and bottom-up parsers, for instance. What I think of as the usual proof that PDAs accept languages generated by CFGs, and vice versa, uses such a construction.
An alternative is to understand the language generated by the grammar, and to design a PDA for it directly. This is less mechanical but has the potential to yield a more concise PDA. If you want to go this route, we can first simplify the grammar by recognizing the nonterminal A can safely be replaced by the RHS of the only production for it:
S -> aSb
S -> c
S -> dSd // removed A -> Sd and replaced here
How does this grammar work?
You have c in the middle by the 2nd production;
You have matching ds on the left and right of the c;
You have as on the left matching bs on the right of c.
A PDA should work as follows:
Read as and ds until you see a c. Push everything on the stack as you go. When you see a c, go to the next state, but don't push the c.
Read bs and ds, popping as and ds from the stack, until:
The topmost stack symbol doesn't match input; crash.
You run out of input with symbols still on the stack; crash.
You run out of stack symbols with input remaining; crash.
You run out of stack and input simultaneously; accept.
Here's a transition table:
q s x q' s'
------------------------------
q0 a,d,Z a q0 aa,ad,aZ
q0 a,d,Z d q0 da,dd,dZ
q0 a,d,Z c q1 a,d,Z
q1 a b q1 -
q1 d d q1 -
If we accept in q1 by empty stack, these transitions are enough. If we want to accept by empty stack or accepting state, we could add a transition like f(q1, Z, -) = (q2, Z) and make q2 accepting; the PDA would transition there nondeterministically and would crash unless the input were also exhausted.

Cypher query become very slow on a medium size dataset (with loop)

This question further extends the idea on the question:
Cypher: how to find all the chains of single nodes not repeated?
For example, in a graph like this:
(a1:TestNode)-[:REL]->(r1:Route)-[:REL]->(a2:TestNode)-[:REL]->(s1:Route)-[:REL]->(a1:TestNode)
(a2:TestNode)-[:REL]->(r2:Route)-[:REL]->(a3:TestNode)-[:REL]->(s2:Route)-[:REL]->(a2:TestNode)
(a3:TestNode)-[:REL]->(r3:Route)-[:REL]->(a4:TestNode)-[:REL]->(s3:Route)-[:REL]->(a3:TestNode)
Graphically:
s3 ← a4
↙ ↗
s2 ← a3 → r3
↙ ↗
s1 → a2 → r2
↙ ↗
a1 → r1
Cypher code:
CREATE (a1:TestNode {name:'a1'})-[:REL]->(r1:Route {name:'r1'})-[:REL]->(a2:TestNode {name:'a2'})-[:REL]->(s1:Route {name:'s1'})-[:REL]->(a1),
(a2)-[:REL]->(r2:Route {name:'r2'})-[:REL]->(a3:TestNode {name:'a3'})-[:REL]->(s2:Route {name:'s2'})-[:REL]->(a2),
(a3)-[:REL]->(r3:Route {name:'r3'})-[:REL]->(a4:TestNode {name:'a4'})-[:REL]->(s3:Route {name:'s3'})-[:REL]->(a3)
Afterwards, we can find a route from a4 to a1 by this command:
MATCH p = (a4:TestNode {name: 'a1'})-[r:REL*]->(a1:TestNode {name: 'a4'})
WITH [a4] + nodes(p) AS ns, p
WHERE ALL (n IN ns
WHERE 1=SIZE(FILTER(m IN TAIL(ns)
WHERE m = n)))
RETURN p
Question:
1. If I extend the above create query to have 2,000 'a' nodes, i.e. up to
(a2000)-[:REL]->(r2000:Route {name:'r2000'})-[:REL]->(a2001:TestNode {name:'a2001'})-[:REL]->(s2000:Route {name:'s2000'})-[:REL]->(a2000),
I found that my computer becomes very slow, and 2GB of memory is occupied by neo4j. Is it normal?
Then I want to find a route from a2001 to a1. The system cannot find the solution (which is obvious a2001->a2000->a1999.....->a1). I guess it is because of the loops in between. In the previous question mentioned above, the query should have avoided loops because duplicates are not allowed.
My purpose is to extend this idea such that possible routes between 2 locations can be identified on a connected graph. Many thanks.

automata: using only Equivalence class to proove regularity

I have tried to go about this problem in several ways, and looked in several places with no answer. the question is as follow:
[Question]
Given two regular languages (may be referred to as finitely described languages ,idk) L1 and L2, we define a new language as such:
L = {w1w2| there are two words, x,y such that : xw1 is in L1, w2y is in L2}
I am supposed to use to show that L is regular, however I have the following restrictions:
I must use Equivalence class, and no other way
I cannot use Rank(L), as in show a limit to the number of equivalence class, instead I must show them
I may use the Closure properties that all regular languages hold
I am not expecting a full proof (though that would be appreciated) but an explanation to how to go about such a thing.
thanks in advance.
L = {w1w2| there are two words, x,y such that : xw1 is in L1, w2y is in L2} is regular if L1 and L2 are regular languages.
Lsuff = { w1 | xw1 ∈ L1 }
Lpref = { w2 | w2y ∈ L2 }
And,
L = LsuffLpref
We can easily proof by construction Finite Automata for L.
Suppose Finite Automata(FA) for L1 is M1 and FA for L2 is M2.
[SOLUTION]
Non-Deterministic Finite Automata(NFA) for L can be drawn by introducing NULL-transition (^-edge) form every state in M1 to every state in M2. then NFA can be converted into DFA.
e.g.
L1 = {ab ,ac} and L2 = {12, 13}
L = {ab, ac, 12, 13, a12, a2, ab12, ab2, a13, a3, ab13, ab3, ............}
Note: w1 and w2 can be NULL
M1 =is consist of Q = {q0,q1,qf} with edges:
q0 ---a----->q1,
q1 ---b/c--->qf
Similarly :
M2 =is consist of Q = {p0,p1,pf} with edges:
p0 ---1----->p1,
p1 ---2/3--->pf
Now, NFA for L called M will be consist of Q = {q0,q1,qf, p0,p1,pf} Where Final state of M is pf and edges are:
q0 ---a----->q1,
q1 ---b/c--->qf,
p0 ---1----->p1,
p1 ---2/3--->pf,
q0 ----^----> p0,
q1 ----^----> p0,
qf ----^----> p0,
q0 ----^----> p1,
q1 ----^----> p1,
qf ----^----> p1,
q0 ----^----> pf,
q1 ----^----> pf,
qf ----^----> pf
^ means NULL-Transition.
Now, A NFA can easily convert into DFA.(I leave it for you)
[ANSWER]
DFA for L is possible hence L is Regular Language.
I will highly encourage you to draw DFA/NFA figures, then concept will be clear.>
Note
I am writing this answer, because I believe that the current available doesn't really satisfy the post requirements, i.e.
I must use Equivalence class, and no other way
Answer
A more direct and simple approach is to not construct a DFA/NFA because of time reasons, but to just check if #EquivalenceClasses < ∞ holds. Specifically, you would have the following ones here:
[w1] = {all w1 in L1}
[e]
[w1w2] = L
So ind(R), the index of the equivalence relation, is 3, therefore finite. Hence, L is regular. Q.E.D.
To make it more clear, just have a look at the definition of the equivalence relation for languager, i.e. R_L.
Moreover, regular languages are closed under concatenation. De facto you just need to concatenate the two DFA/NFA's into one.

Why does Seq give stack overflow when iterating through large csv file

I have a csv file with the following structure :
The first line is a header row
The remaining lines are data lines,
each with the same number of commas, so we can think of the data in
terms of columns
I have written a little script to go through each line of the file and return a sequence of tuples containing the column header and the length of the largest string of data in that column :
let getColumnInfo (fileName:string) =
let delimiter = ','
let readLinesIntoColumns (sr:StreamReader) = seq {
while not sr.EndOfStream do
yield sr.ReadLine().Split(delimiter) |> Seq.map (fun c -> c.Length )
}
use sr = new StreamReader(fileName)
let headers = sr.ReadLine().Split(delimiter)
let columnSizes =
let initial = Seq.map ( fun h -> 0 ) headers
let toMaxColLengths (accumulator:seq<int>) (line:seq<int>) =
let chooseBigger a b = if a > b then a else b
Seq.map2 chooseBigger accumulator line
readLinesIntoColumns sr |> Seq.fold toMaxColLengths initial
Seq.zip headers columnSizes;
This works fine on a small file. However when it trys to process a large file (> 75 Mb) it blows fsi with a StackOverflow exception. If I remove the line
Seq.map2 chooseBigger accumulator line
the program completes.
Now, my question is this : why is F# using up the stack? My understanding of sequences in F# is that the entire sequence is not held in memory, only the elements that are being processed. Therefore I expected that the lines that had already been processed would not remain on the stack. Where is my misunderstanding?
I think this is a good question. Here's a simpler repro:
let test n =
[for i in 1 .. n -> Seq.empty]
|> List.fold (Seq.map2 max) Seq.empty
|> Seq.iter ignore
test creats a sequence of empty sequences, calculates the max by rows, and then iterates over the resulting (empty) sequence. You'll find that with a high value of n this will cause a stack overflow, even though there aren't any values to iterate over at all!
It's a bit tricky to explain why, but here's a stab at it. The problem is that as you fold over the sequences, Seq.map2 is returning a new sequence which defers its work until it's enumerated. Thus, when you try to iterate through the resulting sequence, you end up calling back into a chain of computations n layers deep.
As Daniel explains, you can escape this by evaluating the resulting sequence eagerly (e.g. by converting it to a list).
EDIT
Here's an attempt to further explain what's going wrong. When you call Seq.map2 max s1 s2, neither s1 nor s2 is actually enumerated; you get a new sequence which, when enumerated, will enumerate both of them and compare the yielded values. Thus, if we do something like the following:
let s0 = Seq.empty
let s1 = Seq.map2 max Seq.emtpy s0
let s2 = Seq.map2 max Seq.emtpy s1
let s3 = Seq.map2 max Seq.emtpy s2
let s4 = Seq.map2 max Seq.emtpy s3
let s5 = Seq.map2 max Seq.emtpy s4
...
Then the call to Seq.map2 always returns immediately and uses constant stack space. However, enumerating s5 requires enumerating s4, which requires enumerating s3, etc. This means that enumerating s99999 will build up a huge call stack that looks sort of like:
...
(s99996's enumerator).MoveNext()
(s99997's enumerator).MoveNext()
(s99998's enumerator).MoveNext()
(s99999's enumerator).MoveNext()
and we'll get a stack overflow.
Your code contains so many sequences it's hard to reason about. My guess is that's what's tripping you up. You can make this much simpler and efficient (eagerness is not all bad):
let getColumnInfo (fileName:string) =
let delimiter = ','
use sr = new StreamReader(fileName)
match sr.ReadLine() with
| null | "" -> Array.empty
| hdr ->
let cols = hdr.Split(delimiter)
let counts = Array.zeroCreate cols.Length
while not sr.EndOfStream do
sr.ReadLine().Split(delimiter)
|> Array.iteri (fun i fld ->
counts.[i] <- max counts.[i] fld.Length)
Array.zip cols counts
This assumes all lines are non-empty and have the same number of columns.
You can fix your function by changing this line to:
Seq.map2 chooseBigger accumulator line |> Seq.toList |> seq
why is F# using up the stack? My understanding of sequences in F# is that the entire sequence is not held in memory, only the elements that are being processed. Therefore I expected that the lines that had already been processed would not remain on the stack. Where is my misunderstanding?
The lines themselves are not eating up your stack space. The problem is you've accidentally written a function that builds up a huge unevaluated computation (tree of thunks) that stack overflows when it is evaluated because it makes non-tail calls O(n) deep. This tends to happen whenever you build sequences from other sequences and don't force the evaluation of anything.

Resources