How to find the intersection of two NFA - algorithm

In DFA we can do the intersection of two automata by doing the cross product of the states of the two automata and accepting those states that are accepting in both the initial automata.
Union is performed similarly. How ever although i can do union in NFA easily using epsilon transition how do i do their intersection?

You can use the cross-product construction on NFAs just as you would DFAs. The only changes are how you'd handle ε-transitions. Specifically, for each state (qi, rj) in the cross-product automaton, you add an ε-transition from that state to each pair of states (qk, rj) where there's an ε-transition in the first machine from qi to qk and to each pair of states (qi, rk) where there's an ε-transition in the second machine from rj to rk.
Alternatively, you can always convert the NFAs into DFAs and then compute the cross product of those DFAs.
Hope this helps!

We can also use De Morgan's Laws: A intersection B = (A' U B')'
Taking the union of the compliments of the two NFA's is comparatively simpler, especially if you are used to the epsilon method of union.

There is a huge mistake in templatetypedef's answer.
The product automaton of L1 and L2 which are NFAs :
New states Q = product of the states of L1 and L2.
Now the transition function:
a is a symbol in the union of both automatons' alphabets
delta( (q1,q2) , a) = delta_L1(q1 , a) X delta_L2(q2 , a)
which means you should multiply the set that is the result of delta_L1(q1 , a) with the set that results from delta_L2(q1 , a).
The problem in the templatetypedef's answer is that the product result (qk ,rk) is not mentioned.

Probably a late answer, but since I had the similar problem today I felt like sharing it. Realise the meaning of intersection first. Here, it means that given the string e, e should be accepted by both automata.
Consider the folowing automata:
m1 accepting the language {w | w contains '11' as a substring}
m2 accepting the language {w | w contains '00' as a substring}
Intuitively, m = m1 ∩ m2 is the automaton accepting the strings containing both '11' and '00' as substrings. The idea is to simulate both automata simultaneously.
Let's now formally define the intersection.
m = (Q, Σ, Δ, q0, F)
Let's start by defining the states for m; this is, as mentioned above the Cartesian product of the states in m1 and m2. So, if we have a1, a2 as labels for the states in m1, and b1, b2 the states in m2, Q will consist of following states: a1b1, a2b1, a1b2, a2b2. The idea behind this product construction is to keep track of where we are in both m1 and m2.
Σ most likely remains the same, however in some cases they differ and we just take the union of alphabets in m1 and m2.
q0 is now the state in Q containing both the start state of m1 and the start state of m2. (a1b1, to give an example.)
F contains state s IF and only IF both states mentioned in s are accept states of m1, m2 respectively.
Last but not least, Δ; we define delta again in terms of the Cartesian product, as follows: Δ(a1b1, E) = Δ(m1)(a1, E) x Δ(m2)(b1, E), as also mentioned in one of the answers above (if I am not mistaken). The intuitive idea behind this construction for Δ is just to tear a1b1 apart and consider the states a1 and b1 in their original automaton. Now we 'iterate' each possible edge, let's pick E for example, and see where it brings us in the original automaton. After that, we glue these results together using the Cartesian product. If (a1, E) is present in m1 but not Δ(b1, E) in m2, then the edge will not exist in m; otherwise we'll have some kind of a union construction.

An alternative to constructing the product automaton is allowing more complicated acceptance criteria. Ordinarily, an NFA accepts an input string when it has reached any one of a set of accepting final states. That can be extended to boolean combinations of states. Specifically, you construct the automaton for the intersection like you do for the union, but consider the resulting automaton to accept an input string only when it is in (what corresponds to) accepting final states in both automata.

Related

How to implement a union-find (disjoint set) data structure in Coq?

I am quite new to Coq, but for my project I have to use a union-find data structure in Coq. Are there any implementations of the union-find (disjoint set) data structure in Coq?
If not, can someone provide an implementation or some ideas? It doesn't have to be very efficient. (no need to do path compression or all the fancy optimizations) I just need a data structure that can hold an arbitrary data type (or nat if it's too hard) and perform: union and find.
Thanks in advance
If all you need is a mathematical model, with no concern for actual performance, I would go for the most straightforward one: a functional map (finite partial function) in which each element optionally links to another element with which it has been merged.
If an element links to nothing, then its canonical representative is itself.
If an element links to another element, then its canonical representative is the canonical representative of that other element.
Note: in the remaining of this answer, as is standard with union-find, I will assume that elements are simply natural numbers. If you want another type of elements, simply have another map that binds all elements to unique numbers.
Then you would define a function find : UnionFind → nat → nat that returns the canonical representative of a given element, by following links as long as you can. Notice that the function would use recursion, whose termination argument is not trivial. To make it happen, I think that the easiest way is to maintain the invariant that a number only links to a lesser number (i.e. if i links to j, then i > j). Then the recursion terminates because, when following links, the current element is a decreasing natural number.
Defining the function union : UnionFind → nat → nat → UnionFind is easier: union m i j simply returns an updated map with max i' j' linking to min i' j', where i' = find m i and j' = find m j.
[Side note on performance: maintaining the invariant means that you cannot adequately choose which of a pair of partitions to merge into the other, based on their ranks; however you can still implement path compression if you want!]
As for which data structure exactly to use for the map: there are several available.
The standard library (look under the title FSets) has several implementations (FMapList, FMapPositive and so on) satisfying the interface FMapInterface.
The stdpp libray has gmap.
Again if performance is not a concern, just pick the simplest encoding or, more importantly, the one that makes your proofs the simplest. I am thinking of just a list of natural numbers.
The positions of the list are the elements in reverse order.
The values of the list are offsets, i.e. the number of positions to skip forward in order to reach the target of the link.
For an element i linking to j (i > j), the offset is i − j.
For a canonical representative, the offset is zero.
With my best pseudo-ASCII-art skills, here is a map where the links are { 6↦2, 4↦2, 3↦0, 2↦1 } and the canonical representatives are { 5, 1, 0 }:
6 5 4 3 2 1 0 element
↓ ↓ ↓ ↓ ↓ ↓ ↓
/‾‾‾‾‾‾‾‾‾↘
[ 4 ; 0 ; 2 ; 3 ; 1 ; 0 ; 0 ] map
\ \____↗↗ \_↗
\___________/
The motivation is that the invariant discussed above is then enforced structurally. Hence, there is hope that find could actually be defined by structural induction (on the structure of the list), and have termination for free.
A related paper is: Sylvain Conchon and Jean-Christophe Filliâtre. A Persistent Union-Find Data Structure. In ACM SIGPLAN Workshop on ML.
It describes the implementation of an efficient union-find data structure in ML, that is persistent from the user perspective, but uses mutation internally. What may be more interesting for you, is that they prove it correct in Coq, which implies that they have a Coq model for union-find. However, this model reflects the memory store for the imperative program that they seek to prove correct. I’m not sure how applicable it is to your problem.
Maëlan has a good answer, but for an even simpler and more inefficient disjoint set data structure, you can just use functions to nat to represent them. This avoids any termination stickiness. In essence, the preimages of any total function form disjoint sets over the domain. Another way of looking at this is as representing any disjoint set G as the curried application find_root G : nat -> nat since find_root is the essential interface that disjoint sets provide.
This is also analogous to using functions to represent Maps in Coq like in Software Foundations. https://softwarefoundations.cis.upenn.edu/lf-current/Maps.html
Require Import Arith.
Search eq_nat_decide.
(* disjoint set *)
Definition ds := nat -> nat.
Definition init_ds : ds := fun x => x.
Definition find_root (g : ds) x := g x.
Definition in_same_set (g : ds) x y :=
eq_nat_decide (g x) (g y).
Definition union (g : ds) x y : ds :=
fun z =>
if in_same_set g x z
then find_root g y
else find_root g z.
You can also make it generic over the type held in the disjoint set like so
Definition ds (a : Type) := a -> nat.
Definition find_root {a} (g : ds a) x := g x.
Definition in_same_set {a} (g : ds a) x y :=
eq_nat_decide (g x) (g y).
Definition union {a} (g : ds a) x y : ds a :=
fun z =>
if in_same_set g x z
then find_root g y
else find_root g z.
To initialize the disjoint set for a particular a, you need an Enum instance for your type a basically.
Definition init_bool_ds : ds bool := fun x => if x then 0 else 1.
You may want to trade out eq_nat_decide for eqb or some other roughly equivalent thing depending on your proof style and needs.

Translate to RA: bi-implication/equivalence

(No this isn't one of those translate SQL to RA questions ;-) I have a formula in First-Order Logic that I want to express in RA. That ought to be easy: Codd's 1972 approach in the Relational Completeness paper is to show each FOL operator can be equivalently expressed in RA.
Given relation SP:
Heading {S# CHAR, P# CHAR, QTY INT}
Key {S#, P#}
Characteristic predicate SP(s, p, q) = 'Supplier s supplies Part p in quantity q.'
Express: 'Supplier 'S1' and Supplier 'S2' supply exactly the same set of Parts (disregarding quantities).'
Formula:
∀p. (∃q1. SP('S1', p, q1) ) ⇔ (∃q2. SP('S2', p, q2) )
Note in case of S1 supplying no parts at all, this formula is true just in case S2 also supplies no parts.
This is a Yes/No question (the formula has no free variables); so I'd expect the RA expression must result in a relation with no attributes, returning an empty relation if the two Suppliers do not supply the same set of Parts (formula evaluates to False); otherwise the non-empty relation with no attributes (formula evaluates to True).
To explain a bit further: usually queries return a list of something -- such as the list of Parts supplied by S1, disregarding quantities: SP WHERE (S# = 'S1') {P#} (or in Greek π{P#}(σS# = 'S1'(SP))). For a Yes/No question, we're interested only in whether the query returns something vs nothing, e.g. does Supplier S1 supply Part P456?: SP WHERE (S# = 'S1' AND P# ='P456') {} (π{}(σS# = 'S1'(σP# = 'P456'(SP)))).
You'll notice I'm using a variant of RA: Tutorial D from Date & Darwen. This is easier to read and typeset than Codd's original RA (I've also included the Greek characters and subscripts form). I'll limit myself to Tutorial D operators that correspond to Codd's RA.
I can do the inverse of the query I want: 'Are there any Parts Supplied by S1 but not by S2, or vice versa?'
Firstly a couple of shorthands for common subexpressions
WITH S1P := SP WHERE (S# = 'S1'){P#},
S2P := SP WHERE (S# = 'S2'){P#} :
( S1P MINUS S2P )
UNION
( S2P MINUS S1P );
For those who prefer Greek:
S1P := π{P#}(σS# = 'S1'(SP))
S2P := π{P#}(σS# = 'S2'(SP))
(S1P \ S2P) ∪ (S2P \ S1P)
This'll return an empty result just in case the two Suppliers supply exactly the same set of Parts. So all that remains to do is project that result on to no attributes, and flip empty result to non-empty and vice versa. But Codd's RA doesn't have a way to express that flip, AFAICT.
Applying Codd's 1972 method to the formula, the outermost operation is a forall quantifier, so convert that to a negation of an existential:
¬∃p. ¬( (∃q1. SP('S1', p, q1) ) ⇔ (∃q2. SP('S2', p, q2) ) )
But now the outermost operation is negation. Codd's method only allows negation to appear nested inside conjunction.
I'm stuck. Any ideas?
There is no RA expression that answers the question, if we limit to RA operators and semantics per Codd's 1972 specification.
Even if we add the operators commonly included in RA these days, we can't answer the question as posed. For example, the operators covered in wikipedia such as Rename aka ρ, Extend (for calculated columns), Grouping/Aggregation, Outer Joins.
From the discussion, arguably, the desired result (a degree-zero relation) is not countenanced by Codd. I say "arguably" because Codd never rigorously defines 'relation'. There's Codd 1970 footnote 1 "R is a subset of the Cartesian product S1 x S2 x ... x Sn."; but no lower bound given for n. Clearly it's intended to include the degenerate 'product' for n is 1, then why not allow zero?
For example SQL does not support degree-zero tables. SQL does support pseudo-extending a would-be degree-zero table with a dummy column:
SELECT 'Yes' AS Dummy FROM SP WHERE...
Even allowing that, I claim the question as posed can't be answered in SQL. (Consider the case where SP is empty: then the two Suppliers do supply the same set of Products, viz. the empty set; but the FROM SP ... can only return an empty relation.)
Various non-standard operators or primitives have been suggested (see Comments on q and on other answers). AFAICT there is no authoritative reference that 'blesses' any particular approach. For example, the Alice Book seems not to consider relations of degree zero.
To briefly survey the possible operators/primitives. (Any one of these is expressively equivalent to any other, in the sense that if we have one we can define the others in terms of it -- except for the last.)
Those returning true/false:
Relational comparison: subset ⊆, which can be used to define equality of relations ==. (These require the operands to be 'Union Compatible'.)
IS_EMPTY( ) (which appears in Tutorial D).
The difficulty with returning true/false is that there are no such primitives in RA. (RA operators are usually described as "closed over relations".) Alternatively these operators could return a degree-zero relation; but then why not go to that direct?
Those returning a degree-zero relation:
A complement operation, valid only applied to a degree-zero relation. (This is the "flip" operation discussed in the q.)
Make Dee a primitive -- that is, the non-empty degree-zero relation. Then Dum =df Dee MINUS Dee; and in general complement of r (which must be degree-zero) =df Dee MINUS r
Provide primitive(s) to express a relation literal/constant value, just as most programming languages support expressing numeric or String literals, or more complex data structures. Then Dum/Dee are just two amongst the many relation constants.

Problem implementing Attentive Pooling Network for Question Answering

I'm following this paper to implement and Attentive Pooling Network to build a Question Answering system. In chapter 2.1, it speaks about the CNN layer:
where q_emb is a question where each token (word) has been embedded using word2vec. q_emb has shape (d, M). d is the dimension of the word embedding and M the length of the question. In a similar way, a_emb is the embedding of the answer with shape (d, L).
My question is: how is the convolution done and how is it possible that W_1 and b_1 are the same for both the operations? In my opinion at least b_1 should have a different dimension in each case (and it should be a matrix, not a vector....).
At the moment I've implemented this operation in PyTorch:
### Input is a tensor of shape (batch_size, 1, M or L, d*k)
conv2 = nn.Conv2d(1, c, (d*k, 1))
I find that the authors of the paper are trusting the readers to assume/figure out a lot of things here. From what I read, here is what I could gather:
W1 should be a 1 X dk matrix because that is the only shape that would make sense in order to get Q as c X M matrix.
Assuming this, b1 need not be an matrix. From the above, you could get a c X 1 X M matrix which could be reshaped to c X M matrix easily and b1 could be a c X 1 vector which could be broadcasted and added to the rest of the matrix.
Since, c, d and k are hyper parameters, you could easily have the same W1 and b1 for both Q and A.
This is what I think so far, I will re read and edit in case anythings amiss.

Efficient Union Find with Existential Quantifier?

Is there a classical algorithm to solve the following problem.
Assume the union find algorithm without existential quantifiers
has the following input:
x1 = y1 /\ .. /\ xn = yn
It will then build some datastructure u, so that I can check
u.root(x)==u.root(y), to decide whether x and y are in the same
subgraph.
The input can be characterized by the following grammar:
Input :== Var = Var | Input /\ Input
Assume now we also allow existential quantifiers:
Input :== Var = Var | Input /\ Input | exists Var Input
What union find algorithm could deal with such an input.
I am still assuming that the algorithm builds some datastructure
u, where I can check via u.root(x)==u.root(y) whether x and
y are in the same subgraph.
Additionally u.root(x) should throw an exception when used
with a bound variable. These variables should all have been
eliminated and not anymore part of datastructure. Means
the subgraph should have been accordingly reduced, without
changing the validity of the result.
Bye
Here is a sketch of an algorithm. It will traverse the AST, and
feed a special union find algorithm. First the traversal:
traverse((X = Y)) :- add_conn(X, Y).
traverse(exists(X,I)) :- push_var(X), traverse(I), pop_var_remove_conn(X).
traverse((A /\ B)) :- traverse(A), traverse(B).
The special union find algorithm works with a list. This list defines
the weight of the nodes, the head of list has weight 0, the second element
weight 1, etc... add_conn(X,Y) first computes X'=root(X) and Y'=root(Y). The
less weighted of X' and Y' is connected to the more weighted one.
push_var(X) adds X to the front of the list. Making it the less weighted
node. pop_var_remove_conn(X) removes X again from the list, and removes a
possibly established connection from X to some other node as well.

Necessary and Sufficient vs Soundness and Completeness

I am trying to learn proof. I came across these 4 terms. I am trying to relate all.
A: X>Y B: Y<X
Necessary Condition
B implies A
Sufficient Condition
A implies B
And
A = { set of statements} Q= a statement
Soundness
if A derives Q then A is a logical consequence of Q
Completeness
if A is a logical consequence of Q then A derives Q.
What is relation between all?
Help is appreciated.
Necessary / sufficient doesn't have much to do with soundness and completeness so I'll explain the two concepts separately.
Necessary / sufficient:
In your example, the two statements are equivalent: X>Y if and only if Y<X. So it is indeed the case that B implies A and A implies B. A better example would perhaps be:
A: X>Y+1
B: X>Y
Here A would imply B, i.e. A would be sufficient for B to hold. The other way would not hold: B does not imply A (since you could have X=10 and Y=9 in which case only B would hold). This means that A is not necessary for B.
Completeness/soundness:
This took a while for me to wrap my head around when I first encountered it. But it's really simple!
Suppose you have the following:
A = { X>Y, Y>Z }
Q = X>Z
Now, soundsess says that we can't reach crazyness by sticking to the statements of A. More formally, if Q does not hold, it can't be derived from A. Or, only valid things can be derived from A.
It's easy to create an unsound set of statements. Take for instance
A = { x<Y, X>Y }
They contradict each other, so we can for instance derive X>X (which is false) by using proof by contradiction.
Completeness says the dual: All valid things can be derived from A. Suppose that X, Y and Z are the only variables in the world, and > is the only relation in the world. Then a set of statements such as
A = { X>Y, Y>Z }
is complete, since for any two given variables, a and b, we can derive a>b if and only if a>b in fact holds.
If we would only have
A = { X>Y } (and no knowledge about Z)
then the set of statements would not be complete since there would be true statements about Z which we could say nothing about.
In a nutshell: Soundness says that you can't come to crazy conclusions, and completeness says that you can reach all sensible conclusions.

Resources