Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a string is contained in a language (Prolog)

This is the CFG:

S -> T | V
T -> UU
U -> aUb | ab
V -> aVb | aWb
W -> bWa | ba

so this will accept some form of:

{a^n b^n a^m b^m | n,m >= 1} U {a^n b^m a^m b^n | n,m >= 1}

And here is the code I'm working with:

in_lang([]).  
in_lang(L) :-
    mapS(L), !.

mapS(L) :-
    mapT(L) ; mapV(L),!.

mapT(L) :-
    append(L1, mapU(L), L), mapU(L1), !.

mapU([a|T]) :-
    ((append(L1,[b],T), mapU(L1)) ; (T = b)),!.

mapV([a|T]) :-
    ((append(L1,[b],T), mapV(L1)) ; 
     (append(L1,[b],T), mapW(L1))),
    !.

mapW([b|T]) :-
    ((append(L1,[a],T), mapW(L1)) ;
     (T = a)),
    !.

As of right now, this is returning false for the following three strings:

[a,a,b,b,a,b] // this should be true
[a,a,a,b,b,a,a,b,b,b] // this should be true as well
[a,a,a,b,b,a,b,b,b] // this one IS false

Any help or insight would be greatly appreciated, I'm not too comfortable with Prolog so debugging this by myself has been a challenge.

like image 371
csh1579 Avatar asked Feb 08 '23 04:02

csh1579


1 Answers

Simply use a dcg! And library(double_quotes).

:- set_prolog_flag(double_quotes, chars).

s --> t | v.
t --> u, u.
u --> "a",u,"b" | "ab".
v --> "a",v,"b" | "a",w,"b".
w --> "b",w,"a" | "ba".

?- use_module(library(double_quotes)).

?- length(L,N), phrase(s, L).
   L = "abab", N = 4
;  L = "abab", N = 4
;  L = "aabbab", N = 6
;  L = "abaabb", N = 6
;  L = "aababb", N = 6
;  L = "abbaab", N = 6
;  L = "aaabbbab", N = 8
;  L = "aabbaabb", N = 8
;  L = "abaaabbb", N = 8
;  L = "aaababbb", N = 8
;  ... .
like image 149
false Avatar answered Feb 20 '23 03:02

false