Construct a context free grammar for a language in Chomsky Normal Form - theory

I'm trying to construct a CFG in Chomsky Normal Form with as few productions as possible that accepts the language containing the only string a^21.
I understand that I could just convert
S -> AAAAAAAAAAAAAAAAAAAAA
A -> a
but is there any other way to shorten that language then convert it into Chomsky Normal Form?

We can pretty easily show that we need at least six symbols to hope to generate a CFG in CNF for this language by recognizing we can at best double the generated string length with each production and we must start with 2^0:
A_21 := ...
A_16 := A_16 A_16
A_8 := A_4 A_4
A_4 := A_2 A_2
A_2 := A_1 A_1
A_1 := a
We can then show there is no grammar in CNF with six productions that generates our target language. We start the argument by building the grammar from the bottom up.
We must have A_1 := a to get any strings.
We must have A_2 := A_1 A_1 to get any string with length greater than 1.
We can now generate either A_3 or skip that and generate A_4, or both. We consider each of these cases below.
Case 1: A_3
We add A_3 := A_2 A_1.
We already have 3 productions, and know we need one of the form A_21 := X Y. So we can add up to two more. Even if we add the biggest productions that are now possible - A_6 and A_12 - we can't produce A_21 as required (we can produce at most A_18 := A_6 A_12. So adding A_3 can't get us a grammar that generates our language in six productions.
Case 2: A_4
We add A_4 := A_2 A_2.
We already have 3 productions, and know we need one of the form A_21 := X Y. So we can add up to two more. Our options currently are A_5, A_6 and A_8. A_5 and A_6 will fail for the same reason we stated for Case 1 above. A_8, however, does not fail by that reasoning, so we add A_8 := A_4 A_4.
We now have only one production and need it to be either A_20, A_19, A_17 or A_13. We cannot generate any of these using our existing productions.
We have thus ruled out a grammar with 6 productions. If you try to find a grammar with 7 productions using the above reasoning, you will find several. Since we know there are grammars in CNF with 7 productions and none with 6, you're done. Here are a few of the 7-production grammars:
S := A_18 A_3
A_18 := A_9 A_9
A_9 := A_6 A_3
A_6 := A_3 A_3
A_3 := A_2 A_1
A_2 := A_1 A_1
A_1 := a
S := A_17 A_4
A_17 := A_9 A_8
A_9 := A_8 A_1
A_8 := A_4 A_4
A_4 := A_2 A_2
A_2 := A_1 A_1
A_1 := a
S := A_16 A_5
A_16 := A_8 A_8
A_8 := A_4 A_4
A_5 := A_4 A_1
A_4 := A_2 A_2
A_2 := A_1 A_1
A_1 := a
S := A_15 A_6
A_15 := A_9 A_6
A_9 := A_6 A_3
A_6 := A_3 A_3
A_3 := A_2 A_1
A_2 := A_1 A_1
A_1 := a
S := A_14 A_7
A_14 := A_7 A_7
A_7 := A_4 A_3
A_4 := A_3 A_1
A_3 := A_2 A_1
A_2 := A_1 A_1
A_1 := a
S := A_13 A_8
A_13 := A_8 A_5
A_8 := A_5 A_3
A_5 := A_3 A_2
A_3 := A_2 A_1
A_2 := A_1 A_1
A_1 := a
S := A_12 A_9
A_12 := A_9 A_3
A_9 := A_6 A_3
A_6 := A_3 A_3
A_3 := A_2 A_1
A_2 := A_1 A_1
A_1 := a
S := A_11 A_10
A_11 := A_10 A_1
A_10 := A_8 A_2
A_8 := A_4 A_4
A_4 := A_2 A_2
A_2 := A_1 A_1
A_1 := a
And there are lots more. The hard part was showing there weren't any with 6 productions.

Related

Rotation of "Array of Array" (Matrix)

So, I'm a beginner. I'm trying to make a program, which determines if two matrices, which the user puts in, have a corresponding transformation (rotation), from the first matrix to the second matrix.
The output would be like this (keep in mind that the brackets "[...]" are used to show the input of the user),
Please input the value of N : [3]
Matrix A
[1] [2] [3]
[4] [5] [6]
[7] [8] [9]
Matrix B
[7] [4] [1]
[8] [5] [2]
[9] [6] [3]
Matrix B is 90 degree rotated Matrix A
------------------------------------------
Please input the value of N : [3]
Matrix A
[1] [2] [3]
[4] [5] [6]
[7] [8] [9]
Matrix B
[9] [8] [7]
[6] [5] [4]
[3] [2] [1]
Matrix B is 180 degree rotated Matrix A
Assume the matrix rotates to the right. If Matrix B is the same as Matrix A, then the output would be a 0 degree rotated matrix.
Here is my attempt in Pascal:
Program Matrix_Rotation;
Var
TabA,TabB : Array [1..9] of Array [1..9] of integer;
i,j,n,checker1,checker2,checker3,checker4 : integer;
Begin
Write('Please input the value of N : '); Readln(n);
If ((n > 0) and (n < 10)) then
Begin
Writeln('Matrix A');
For i := 1 to n do
Begin
For j := 1 to n do
Begin
Read(TabA[i][j]);
End;
Writeln;
End;
Writeln('Matrix B');
For i := 1 to n do
Begin
For j := 1 to n do
Begin
Read(TabB[i][j]);
End;
Writeln;
End;
checker1 := 0;
checker2 := 0;
checker3 := 0;
checker4 := 0;
For i := 1 to n do
Begin
For j := 1 to n do
Begin
If TabA[i][j] = TabB[j][n+1-i] then
Begin
checker1 := checker1 + 1;
End else if TabA[i][j] = TabB[n+1-i][n+1-j] then
Begin
checker2 := checker2 + 1;
End else if TabA[i][j] = TabB[n+1-j][i] then
Begin
checker3 := checker3 + 1;
End else if TabA[i][j] = TabB[i][j] then
Begin
checker4 := checker4 + 1;
End else
Begin
checker1 := checker1;
checker2 := checker2;
checker3 := checker3;
checker4 := checker4;
End;
End;
End;
If checker1 = (n * n) then
Begin
Writeln('Matrix B is 90 degree rotated matrix A');
End else if checker2 = (n * n) then
Begin
Writeln('Matrix B is 180 degree rotated matrix A');
End else if checker3 = (n * n) then
Begin
Writeln('Matrix B is 270 degree rotated matrix A');
End else if checker4 = (n * n) then
Begin
Writeln('Matrix B is 0 degree rotated matrix A');
End else
Begin
Writeln('Matrix B doesn't correspond with matrix A');
End;
End else
Begin
Writeln('The value of N must be between 1 and 9');
End;
End.
I tried to input 4 as the value of N, and my Matrix A and Matrix B are like this:
Matrix A
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
Matrix B
4 3 2 1
4 3 2 1
4 3 2 1
4 3 2 1
I didn't get the output wanted, which is "Matrix B is 180 rotated matrix A". Instead, I got the message, "Matrix A doesn't correspond with matrix B". The same case with 270 rotated matrix A.
I thought this was caused by not unique matrix elements. But if that were true, how should I change the codes so that it would work on matrix with several similar matrix elements? I'm stuck on this. Please make the codes as simple as possible.
I didn't get the output wanted, which is "Matrix B is 180 rotated matrix A". […]
In your code the control structure
if X = 123 then
begin
foo;
end
else if X = 456 then
begin
bar;
end
else
begin
boing;
end;
is equivalent to
case X of
123:
begin
foo;
456:
begin
bar;
end;
otherwise
begin
boing;
end
end;
Like in a case structure, each branch (foo/bar/boing) is taken alternatively.
Your program is currently assuming that two matrices are either the same, rotated left/right, upside down, or not the same, but only one of which can be true.
With a case (or in your code if … then else if … then else structure) it is impossible to cover the case that multiple rotations apply.
I hope this is enough of a hint. Besides, please don’t do ”null assignments“ (checker1 := checker1;).

Unique number assignment to a two dimensional array

I am trying to write R*C/2-1 unique numbers into an array , but the random function gives multiple times the same value.
It should be filled with each number 2 times at a random position.
Like:
( 1 2 3 4 )
( 5 6 7 8 )
( 1 2 3 4 )
( 5 6 7 8 )
My code so far:
...
R=4
C=4
...
var
somearray : array [0 .. (C- 1), 0 .. (R- 1)] of integer;
...
for Row := 0 to (R - 1) do
for Col := 0 to (C - 1) do
begin
somearray [Col, Row] := RandomRange(0, 9);
end;
...
EDIT1:
second array
...
var
maxnum: array [0 .. (C * R) div 2 - 1] of integer;
max := (C * R) div 2;
for i := 0 to max - 1 do
maxnum[i] := i;
...
maxnum has numbers from 0..7 / 1-8
You have two ways of doing this that I can see:
Random Position
Iterate through the numbers and then place each one at a random position. If you hit a conflict position then you would have to have some logic to find the next position for that value.
Using your code we would get:
// Initialize the array
for Row := 0 to (R - 1) do
for Col := 0 to (C - 1) do
somearray[Col, Row] := 0;
// Populate the random numbers
for randomCount := 1 to 2 do
for randomNumber := 1 to ((R * C) div 2) do
begin
randomPosition := Random(R * C);
while somearray[randomPosition div C, randomPosition mod C] <> 0 do
begin
Inc(randomPosition);
if randomPosition >= (R * C) then
randomPosition := 0;
end;
somearray[randomPosition div C, randomPosition mod C] := randomNumber;
end;
Putting this in a more generic form:
type
T2DArray = array of array of Integer;
procedure RandomPopulate1(aTheArray: T2DArray);
var
col: Integer;
colCount: Integer;
randomCount: Integer;
randomNumber: Integer;
randomPosition: Integer;
row: Integer;
rowCount: Integer;
begin
// Initialize the array
colCount := Length(aTheArray);
if colCount = 0 then
Exit;
rowCount := Length(aTheArray[0]);
for col := 0 to colCount - 1 do
for row := 0 to rowCount - 1 do
aTheArray[col, row] := 0;
// Populate the random numbers
for randomCount := 1 to 2 do
for randomNumber := 1 to ((colCount * rowCount) div 2) do
begin
randomPosition := Random(colCount * rowCount);
while aTheArray[randomPosition div colCount, randomPosition mod colCount] <> 0 do
begin
Inc(randomPosition);
if randomPosition >= (colCount * rowCount) then
randomPosition := 0;
end;
aTheArray[randomPosition div colCount, randomPosition mod colCount] := randomNumber;
end;
end;
To use this:
var
somearray: T2DArray;
begin
Randomize;
SetLength(somearray, 4, 4);
RandomPopulate1(somearray);
end;
Using random position changing
You could set the values in the array and then randomize the positions. So perform a number of random swaps. This is the easier option.
// Initialize the array
for Row := 0 to (R - 1) do
for Col := 0 to (C - 1) do
somearray[Col, Row] := ((Col * C + Row) div 2) + 1;
// Now randomize the positions
for randomLoop := 0 to (R * C) - 1 do
begin
randomPosition := Random(R * C);
randomNumber := somearray[randomLoop div C, randomLoop mod C];
somearray[randomLoop div C, randomLoop mod C] := somearray[randomPosition div C, randomPosition mod C];
somearray[randomPosition div C, randomPosition mod C] := randomNumber;
end;
As before we can have a more generic version:
procedure RandomPopulate2(aTheArray: T2DArray);
var
col: Integer;
colCount: Integer;
randomLoop: Integer;
randomNumber: Integer;
randomPosition: Integer;
row: Integer;
rowCount: Integer;
begin
// Initialize the array
colCount := Length(aTheArray);
if colCount = 0 then
Exit;
rowCount := Length(aTheArray[0]);
for col := 0 to colCount - 1 do
for row := 0 to rowCount - 1 do
aTheArray[col, row] := ((col * colCount + row) div 2) + 1;
// Now randomize the positions
for randomLoop := 0 to ((colCount * rowCount) div 2) do
begin
randomPosition := Random(colCount * rowCount);
randomNumber := aTheArray[randomLoop div colCount, randomLoop mod colCount];
aTheArray[randomLoop div colCount, randomLoop mod colCount] :=
aTheArray[randomPosition div colCount, randomPosition mod colCount];
aTheArray[randomPosition div colCount, randomPosition mod colCount] := randomNumber;
end;
end;
The random function is not designed for this type of use.
Instead:
create a list (array) of the values desired, presumably 1 .. R*C/2.
randomly rearrange them.
fill the array with the randomly arranged values.
You can try the following.
Create a dynamic array (or TList<integer>) with the number of items equal to the number of cells in your 2d array.
Fill this array with sequential integers. For example, assign 1 to Item [0], 2 to Item[1] etc.
Generate a r:=Random(List.Count). Assign the List[r] value to your 2d array member and delete the member from the list.
This will result in decrement of List.Count and the new r generation will give you a i) Distinct item value even if the index is the same. ii) The random function will ever give you an item index within the remaining part of the primary array until Length(List)=0.

Parallel implementation of Gauss Elimination with pthreads

I need to implement parallel version of following Gauss elimination algorithm using pthreads.
procedure GAUSSIAN ELIMINATION (A, b, y)
begin
for k := 0 to n − 1 do /* Outer loop */
begin
for j := k + 1 to n − 1 do
A[k, j] := A[k, j]/A[k, k]; /* Division step */
y[k] := b[k]/A[k, k];
A[k, k] := 1;
for i := k + 1 to n − 1 do
begin
for j := k + 1 to n − 1 do
A[i, j] := A[i, j] − A[i, k] × A[k, j]; /* Elimination step */
b[i] := b[i] − A[i, k] × y[k];
A[i, k] := 0;
endfor; /* Line 9 */
endfor; /* Line 3 */
end GAUSSIAN ELIMINATION
I understand the sequential implementation and pthreads but not getting a single hint on how to construct logic for parallel version of it (Thread work distribution criteria, which loops to parallelize etc). Any clue or starting point would help me to continue.
The work for each row in the matrix requires all the previous rows to be finished, so you can't divide up the work that way.
However, within a single row, each column can be processed in parallel (with the caveat that original value of the k-th column must be saved and used in the calculation of the other columns). This corresponds to your j values.
I believe you can rearrange the algorithm to make this easier, so that there's only one loop over j:
procedure GAUSSIAN ELIMINATION (A, b, y)
begin
for k := 0 to n − 1 do /* Outer loop */
begin
for j := k + 1 to n − 1 do
begin
A[k, j] := A[k, j]/A[k, k]; /* Division step */
for i := k + 1 to n − 1 do
A[i, j] := A[i, j] − A[i, k] × A[k, j]; /* Elimination step */
endfor;
y[k] := b[k]/A[k, k];
A[k, k] := 1;
for i := k + 1 to n − 1 do
begin
b[i] := b[i] − A[i, k] × y[k];
A[i, k] := 0;
endfor;
endfor;
end GAUSSIAN ELIMINATION
Note that the body of the loop over j only accesses values in columns j and k - this is the loop that can be done in parallel. You can then further note that the second part of the outer loop does not depend on the first part, so you can break the outer loop into two:
procedure GAUSSIAN ELIMINATION (A, b, y)
begin
for k := 0 to n − 1 do /* Outer loop */
begin
for j := k + 1 to n − 1 do
begin
A[k, j] := A[k, j]/A[k, k]; /* Division step */
for i := k + 1 to n − 1 do
A[i, j] := A[i, j] − A[i, k] × A[k, j]; /* Elimination step */
endfor;
endfor;
for k := 0 to n − 1 do /* Outer loop, second pass */
begin
y[k] := b[k]/A[k, k];
A[k, k] := 1;
for i := k + 1 to n − 1 do
begin
b[i] := b[i] − A[i, k] × y[k];
A[i, k] := 0;
endfor;
endfor;
end GAUSSIAN ELIMINATION
You can create threads up front, each one responsible for executing the loop over j for a subset of the j values from 0 to n - 1. These threads will need a synchronisation barrier after each row is processed, because the results of all columns for the previous row are required to process the next row. You can use pthread_barrier_wait() for this.
You will note that not every column (value of j) has equal work. Column j is processed by that loop j times (so column 0 executes 0 times, and column n - 1 executes n - 1 times). You will want to assign column numbers to threads so that each thread has as close to equal work to do for each row as possible - this can be done by assigning the columns in round-robin fashion. Eg. if you have three threads A, B and C and 10 columns from 0 to 9, you would assign them:
Thread A: 0, 3, 6, 9
Thread B: 1, 4, 7,
Thread C: 2, 5, 8,
The thread function would then look something like:
for k := 0 to n − 1 do /* Outer loop */
begin
call pthread_barrier_wait(row_barrier);
for j := k + 1 + thread_number to n − 1 step n_threads do
begin
A[k, j] := A[k, j]/A[k, k]; /* Division step */
for i := k + 1 to n − 1 do
A[i, j] := A[i, j] − A[i, k] × A[k, j]; /* Elimination step */
endfor;
endfor;
call pthread_barrier_wait(phase1_barrier);
and the main function would look something like:
procedure GAUSSIAN ELIMINATION (A, b, y)
begin
call start_threads;
call pthread_barrier_wait(phase1_barrier);
for k := 0 to n − 1 do /* Outer loop, second pass */
begin
y[k] := b[k]/A[k, k];
A[k, k] := 1;
for i := k + 1 to n − 1 do
begin
b[i] := b[i] − A[i, k] × y[k];
A[i, k] := 0;
endfor;
endfor;
end GAUSSIAN ELIMINATION

Adding elements to an array - Pascal

program Primes(input,output);
var
candidates, primes : Array[0..999] of Integer;
n, i, j : Integer;
begin
for i := 0 to 999 do
begin
candidates[i] := 1;
end;
candidates[0] := 0;
candidates[1] := 0;
i := 0;
while i < 1000 do
begin
while (i < 1000) and (candidates[i] = 0) do
begin
i := i + 1;
end;
if i < 1000 then
begin
j := 2;
while i*j < 1000 do
begin
candidates[i*j] := 0;
j := j + 1;
end;
i := i + 1;
end;
end;
for i := 0 to 999 do
begin
if candidates[i] <> 0 then
begin
primes[i] := i;
end;
end;
for i := 0 to 999 do
begin
writeln(primes[i]);
end;
readln();
end.
The code works properly for finding primes, what I need is a new array that holds only the primes. When printing this one, it has zeros since it's the same size. Any help is appreciated. Thanks.
Only update primes when it's actually needed. Keep track of the number of entries you've updated, and only output that number of entries at the end:
j := 0;
for i := 0 to 999 do
begin
if candidates[i] <> 0 then
begin
primes[j] := i;
Inc(j);
end;
end;
for i := 0 to j - 1 do
WriteLn(primes[i]);
readln;
For i:=1 to 999 do
Begin
if primes[i] <> 0 then
begin
writeln(primes[i]);
end;
end;
If you still need help try this

Creating 2-dimensional array (nxn) *Pascal

Does anyone know how to create Matrix using array function in Pascal?
Output will be something like this:
00100
01110
11111
01110
00100
Thanks.
Edit:
This is my Code sofar:
program borlpasc;
var a:array[1..100,1..100] of integer;
i,j,n:integer;
begin write('Enter the Number N='); {Example: 5}
readln(n);
for i:=1 to n do
for j:=1 to n do
begin a[i,j]:=0;
if n mod 2 = 1 then begin
a[n div 2 + 1, j] := 1;
a[i, n div 2 + 1] := 1;
end;
end;
for i:=1 to n do
begin for j:=1 to n do write(a[i,j]:2);
writeln
end;
readln
end.
but only get this:
00100
00100
11111
00100
00100
You don't need arrays for this, just two nested FOR loops. Here is an example which writes a grid of 1s - see if you can modify this to give the output that you need (hint: you need to add an IF statement).
program Grid;
procedure DrawGrid(nx: integer; ny: integer);
var
x, y: integer;
begin
for y := 1 to ny do
begin
for x := 1 to nx do
begin
write('1');
end;
writeln;
end;
end;
begin
DrawGrid(5, 5);
end.

Resources