yossigil / Protolog

Spartan implementation of prolog
1 stars 0 forks source link

Prolog generators #5

Open yossigil opened 2 years ago

yossigil commented 2 years ago

Write Prolog terms and functors to express the Prolog syntax, e.g., term(Atom, list of Terms). rule(Right, Left).

And then write a program that goes over the term and produces random Prolog programs.

orel-adivi commented 2 years ago

Hi,

I am suggesting the following code for solving the issue:

For identifying the correct syntax of Prolog programs, I am suggesting the following code, based on

/* Structure Analysis: */

prolog([]).                     % empty string a a valid program
prolog([rule(_,_)|Rs]) :- prolog(Rs).
prolog([query(_)|Rs]) :- prolog(Rs).

query(Xs) :- terms(Xs).

rule(X,[]) :- atom_prolog(X).               % rule has to have a L-side, but not necessarily a R-side (fact)
rule(X,Xs) :- compound_prolog(X), terms(Xs).

compound_prolog([X|Xs]) :- functor(X), terms(Xs).   % nullary relations are not allowed

terms([X]) :- term(X).
terms([X|Xs]) :- term(X), terms(Xs).

term([X]) :- rule(X,[]).                % is it correct?
term([X|Xs]) :- rule(X,Xs).

atom_prolog(X) :- constant(X).
atom_prolog(X) :- variable(X).

/* String Analysis: */

constant(S) :- atom_concat(X,Xs,S),
    check_in(X,['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']),
    check_all_in(Xs,['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9']).

variable(S) :- atom_concat(X,Xs,S),
    check_in(X,['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']),
    check_all_in(Xs,['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9']).
variable(S) :- atom_concat('_',Xs,S),
    check_all_in(Xs,['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9']).

functor(S) :- atom_concat(X,Xs,S),
    check_in(X,['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']),              % should we allow capitalization?
    check_all_in(Xs,['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','<','>','!','@','#','$','%','^','&','*','-','\\','=','+','\'','"','/']).

/* Auxiliary String Analysis: */

check_all_in("",_).
check_all_in(S,L) :- atom_concat(X,Xs,S), check_in(X,L), check_all_in(Xs,L).

check_in(X,[X|_]).                      % it should work even when X is the last character in the list
check_in(X,[_|Ls]) :- check_in(X,Ls).

The code is also available at the following link. The structural analysis in the code is based on the BNF presented in the discussion of #1 . It is probably not the simplest way to solve the issue, but it is similar to the inheritance hierarchy that already exists in the project.

I have tested the code on some examples, for instance:

I am not sure that the code treats nullary relations correctly, it might be worth checking.

If this code satisfies the constraints, the issue can be closed.