Can you show me how to implement an algorithm in PROLOG to generate all combinations of N balanced brackets? ( brackets which close correctly )
-
Have you tried anything? – Gaurav Jeswani Nov 13 '19 at 07:12
-
No, we cannot. This site is primarily about helping you to debug code that you've written, but it isn't working. Please attempt this, show us your code, and then ask for help to fix it. – Enigmativity Nov 13 '19 at 07:17
-
Yes , but without much success, I've been learning prolog for just a couple of days – Nov 13 '19 at 07:17
-
Just show us what you've done and we'll see what we can do. At least give us the data input and the expected output, and anything that you can do in between. – Enigmativity Nov 13 '19 at 07:21
-
The input data should be a natural number N , and the expected output would be all combinations of N round brackets , with the condition of being correctly balanced – Nov 13 '19 at 08:34
-
Start with writing a program that *tests* whether a given sequence of brackets is correctly balanced! – jschimpf Nov 13 '19 at 11:28
4 Answers
This is what dcgs are best for. We define a grammar for balanced round brackets and then enumerate them accordingly.
:- set_prolog_flag(double_quotes, chars).
balanced --> "".
balanced --> "(", balanced, ")", balanced.
Now, when asking for concrete sentences, it is best to use library(double_quotes)
see this for more.
We can ask for sentences of a fixed length:
?- length(T, 6), phrase(balanced, T).
T = "()()()"
; T = "()(())"
; T = "(())()"
; T = "(()())"
; T = "((()))"
; false.
Or just abound any sentence:
?- length(T, N), phrase(balanced, T).
T = [], N = 0
; T = "()", N = 2
; T = "()()", N = 4
; T = "(())", N = 4
; T = "()()()", N = 6
; T = "()(())", N = 6
; T = "(())()", N = 6
; T = "(()())", N = 6
; T = "((()))", N = 6
; T = "()()()()", N = 8
; T = "()()(())", N = 8
; T = "()(())()", N = 8
; T = "()(()())", N = 8
; T = "()((()))", N = 8
; ... .

- 10,264
- 13
- 101
- 209
Here is another solution to get the Catalan numbers.
It places the parenthesis similar to the DCG solution:
catalan(L) :-
append(['('|A], [')'|B], L),
length(A, N), 0 =:= N mod 2,
catalan(A),
catalan(B).
catalan([]).
Example, verifies 3 entries from A000108:
?- length(L, 18), findall(L, catalan(L), R),
length(R, N), write(N), nl, fail; true.
4862
?- length(L, 20), findall(L, catalan(L), R),
length(R, N), write(N), nl, fail; true.
16796
?- length(L, 22), findall(L, catalan(L), R),
length(R, N), write(N), nl, fail; true.
58786
here is a backtracking solution
paran(N, N, N, []).
paran(N, O, C, ['('|R]) :-
C1 is C + 1,
C1 =< N,
paran(N, O, C1, R).
paran(N, O, C, [')'|R]) :-
O1 is O + 1,
O1 =< C,
paran(N, O1, C, R).
generate(N, R) :- paran(N, 0, 0, R).
paran is the main function, first argument is the number of balanced brackets, second and third are the number of opened and closed brackets respectively, and in R we store the result. generate will call paran with 0 as second argument and also third argument since we start with 0 opened and 0 closed brackets, and the algorithm stops when we get to n
opened and n
closed brackets
?- generate(2, R).
R = ['(', '(', ')', ')'] ;
R = ['(', ')', '(', ')'] ;
false.
if you want all the results in a list, you can use it with findall
?- findall(R, generate(2, R), L).
L = [['(', '(', ')', ')'], ['(', ')', '(', ')']].

- 1
- 1
#include<iostream>
using namespace std;
void parenthesis(int open, int close, string brak)
{
if (open == 0 && close == 0)
cout<<brak;
if (open>close)
return;
if (open > 0)
parenthesis(open - 1, close,brak + "(");
if (close > 0)
parenthesis(open, close-1 ,brak + ")");
}
void printPar(int n)
{
parenthesis(n,n,"\n");
}
int main()
{
int n = 3;
printPar(n);
return 0;
}

- 1
- 5
-
Please provide some context to your answer so that others can easily understand your approach. – Pawara Siriwardhane Apr 23 '21 at 07:31