4
votes

What's the most idiomatic approach to output prolog code from a prolog program (as a side effect)?

For instance, in a simple case, I might want to write a Program that, given a text input, yields another Prolog program representing the text as a directed graph.

I understand this question is somewhat vague, but I've resigned to consulting Stackoverflow after failing to find a satisfying answer in the available Prolog Meta-Programming literature, which mostly covers applications of meta-circular interpreters.

If you feel this question might be better articulated some other way, please edit it or leave a comment.

2
At the very least, give a concrete example of the text input and the Prolog representation you want as output. A non-idiomatic approach that does that would also improve your question. - user1812457
Generate the rules, assert them and use "listing/1" or similar: swi-prolog.org/pldoc/man?section=listing - pasaba por aqui
Did you do some progress ? I'm also interested in automated code generation in Prolog (Ergo/Flora preferrably), but on mainstream languages (C++,..) Did you do some tries in area of code synthesis on hypergraph networks (opencog/hypergraphdb) ? - Dmitry Ponyatov
@DmitryPonyatov Unfortunately, I haven't had time to do much Prolog recently! Your work sounds really interesting. - David Shaked

2 Answers

3
votes

The most idiomatic way is always to stay pure and avoid side effects.

Let the toplevel do the writing for you!

To generate a Prolog program, you define a relation that says for example:

program(P) :- ...

and then states, in terms of logical relations, what holds about P.

For example:

program(P) :-
        P = ( Head :- Body ),
        Head = head(A, B),
        Body = body(A, B).

Example query and answer:

?- program(P).
P =  (head(_G261, _G262):-body(_G261, _G262)).

So, there's your program, produced in a pure way.

If you want to write it, use portray_clause/1:

?- program(P), portray_clause(P).
head(A, B) :-
        body(A, B).
...

This can be useful in a failure driven loop, to produce many programs automatically.

1
votes

writeq/1 (or format('~q', [...])) produces output that can be read back. Usually you need also to put a full stop after a clause body. For instance, try

?- A_Clause = (X is 1+Y, write('X is '), write(X), nl), format('~q.~n', [A_Clause]).

Readability of code suffers from loosing variables 'nice names', but the functionality is there...

edit

as noted by @false, a space before the dot will avoid a bug in case the output term would finish with a dot