Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Where is a free prolog code beautifier that doesn't destroy comments?

713 views
Skip to first unread message

R Kym Horsell

unread,
Apr 10, 2016, 1:42:14 AM4/10/16
to
Douglas R. Miles/LogicMoo <logi...@gmail.com> wrote:
> Where is a free prolog code beautifier that doesn't destroy comments?
>
> +1 if written in Prolog (with source avail)

Usually emacs has all these things as add-on packages.
I haven't checked for years, but I assume SWI includes an .el emacs
macro as well as its own devel env for writing pl progs.
I certainly have used a pl pretty print in emacs (years ago), just don't know
where it might have come from.

--
Big testes are sign that a species has history of infanticide
UPI.com, 13 Nov 2014 23:12Z
"Once sperm competition has become so intense that no male can be certain of
his own paternity, infanticide disappears," said Dieter Lukas.
Female primates sleep around to stop infanticide, study finds -- Telegraph.co.uk
Why Some Mammals Kill Babies of Their Own Kind -- Smithsonian

Markus Triska

unread,
Apr 10, 2016, 5:12:25 AM4/10/16
to
R Kym Horsell <k...@kymhorsell.com> writes:

> Usually emacs has all these things as add-on packages.

I second this. Emacs and Stefan Bruda's Prolog mode for Emacs let you do
many things you need in connection with formatting Prolog code. It's
fast and convenient, and you can also connect it with Prolog directly.

--
comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/

Jan Burse

unread,
Apr 12, 2016, 1:17:19 PM4/12/16
to
Douglas R. Miles/LogicMoo schrieb:
> Where is a free prolog code beautifier that doesn't destroy comments?
>
> +1 if written in Prolog (with source avail)
>

I got a beautifier for Jekejeke Prolog, but its written partly
in Java and partly in Prolog. And sadly currently Java does
the main part of the work.

Its just a simple extension of the normal pretty printer for
Prolog terms that is for example also found in SWI-Prolog
not only Jekejeke Prolog.

For example you can easily make the following test, namely
enter a clause and do some listing. You will see that the
clause is already a little reformatted (here SWI-Prolog):

Input:

?- [user].
app([], X, X).
app([X|Y], Z, [X|T]) :- app(Y, Z, T).

Output (look see what happens with the (:-)/2):

?- listing(app/3).
app([], A, A).
app([A|B], C, [A|D]) :-
app(B, C, D).

To get a beautifier you need annotations or extra data structures
that delivers you more information from reading a term, and
also the pretty printer needs then take this information into
account.

Typically the following information is sufficient to give
a relatively good beautifier:

1) The variable names of the original clause need to be
carried over
2) Some syntax operators need special treatment, like the
','/2 is written without a space in front.
3) Some predicates need special treatment, a workable approach
is to look at the meta-predicate definitions
4) Some lists or numbers might need to be carried
over unformatted
5) Some compounds might need to be carried over with block comment
information interspersed
6) Some compounds might need to be carried over with line comment
information interspersed
7) Even the original clause might need to carry over block comment
or line comment at the front or at the back of the clause
8) HTML Links to the home of a predicate
9) HTML Anchors for the home of a predicate

In Jekejeke Prolog I use the following approach for the many
requirements from above:

a) For 1) I use the ISO variable_names option of the read_term
and write_term predicate.
b) For 2) syntax operators can have properties, this is a non-ISO
extension
c) For 3) there are additional meta argument specifiers not found
everywhere, such as the new (::)/1 for object orientation.
d) For 4) lists like "abc" or numbers like 0xabc are mapped to
atoms, and the atom has a hint property
e) For 5) and 6) the functor of a compound has a filler
property
f) For 7) the clause is wrapped into an additional functor '.'/1,
so app([], X, X) is read as '.'(app([],X,X)) and app([X|Y], Z,
[X|T]) :- app(Y, Z, T) is read as '.'(app([X|Y], Z, [X|T]) :-
app(Y, Z, T)). The filler property of the '.'/1 functor is then
used carry over line and block comments.
g) For 8) and 9) each predicate has a usage property, the
property is automatically set during consult or assert

The main loop for the beautifier is as follows.

Step 1) Consult all the files you want to beautify, this is needed
for requirement 8) and 9) otherwise you don't know what links
and anchors should be placed. Please note in Prolog you can easily
make forward references of predicates.

Step 2) Read the clauses of the files with the extra data, and
write the clauses with the extra data. This loop looks as follows
in Jekejeke Prolog:

copy_text(InName, OutName) :-
absolute_file_name(InName, SrcPin),
setup_call_cleanup(open(InName, read, InStream),
setup_call_cleanup(open(OutName, write, OutStream),
(repeat,
read_term(InStream, Term, [annotation(true),
variable_names(Names),
source(SrcPin), line_no(U)]),
term_variables(Term, Vars),
sys_term_singletons(Term, Anons),
sys_number_variables(Vars, Names, Anons, NamesAndAnons),
write_term(OutStream, Term, [annotation(true), context(-1),
quoted(true), format(true), variable_names(NamesAndAnons),
source(SrcPin), line_no(U)]),
(Term = end_of_file -> !; fail)),
close(OutStream)),
close(InStream)).

The following read/write options come into play:
- annotation/1: So that the extra information is read or written,
and the '.'/1 wrapping is done respectively undone.
- format/1: Different levels of formatting, true=use all
extra information
- context/1: Start with a clause
- source/1, line_no/1: So that the HTML anchor is generated.

You need the development environment to play with it, the
runtime library doesn't understand annotation/1, format/1.

Bye

Douglas R. Miles/LogicMoo

unread,
Apr 19, 2016, 10:52:16 AM4/19/16
to
Thank you,
Emacs has been treating me well!

Douglas R. Miles/LogicMoo

unread,
Apr 21, 2016, 6:11:36 PM4/21/16
to
Thank you for the great info!

Jan Burse

unread,
Apr 23, 2016, 7:59:40 AM4/23/16
to
Jan Burse schrieb:
> 8) HTML Links to the home of a predicate
> 9) HTML Anchors for the home of a predicate

There is also a certain relationship between the
pretty printer and how he generates HTML anchors,
and indexing tools. The indexing tool might respect
the coding of predicate names and syntax operators.

Currently I only have explored the coding of modules
in my indexer. It is still a preliminary solution
since I don't have yet a proper javadoc for the
Prolog system. So the API documentation is not yet
generated from the Prolog source as is done in
in SWI-Prolog via some mark-up.

But either way there will be some HTML anchors,
not only for predicates but also possibly for
syntax operators.

Ciao Prolog pioneers to a great deal a web-site
which is not only appealing and has a good user
experience. But this web-site shows a consequential
organization of predicates along modules plus a
good cross linking between the web pages.

I have recently tried to improve my own web-site.
I am now automatically generating the following
indexes:
- Public Predicates: Alphabetical Index
- Package Local Predicates: Alphabetical Index
- Non-Private Meta-Predicates: Alphabetical Index
- Non-Private Closure-Predicates: Alphabetical Index
- Non-Private Syntax Operators: Level Index

Here is an example:
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/10_docu/02_reference/10_indexes/package.html

Here is a discussion what is needed:
http://plus.google.com/+JekejekeCh/posts/LYJhrWCnoey

Jan Burse

unread,
Apr 23, 2016, 8:02:18 AM4/23/16
to
Jan Burse schrieb:
> I have recently tried to improve my own web-site.
> I am now automatically generating the following
> indexes:
> - Public Predicates: Alphabetical Index
> - Package Local Predicates: Alphabetical Index
> - Non-Private Meta-Predicates: Alphabetical Index
> - Non-Private Closure-Predicates: Alphabetical Index
> - Non-Private Syntax Operators: Level Index

I tried first bagof/3 in the indexer,
but then resorted to keysort/2 since it
gives better control on what is sorted and
what not.

Jan Burse

unread,
May 21, 2016, 6:12:00 PM5/21/16
to
Hi,

Douglas R. Miles/LogicMoo schrieb:
> Where is a free prolog code beautifier that doesn't destroy comments?
>
> +1 if written in Prolog (with source avail)
>

You can combine a code coverage analyzer with a beautifier as well.
I made a little experiment right now, with Jekejeke Prolog:

- The new code coverage analyzer module:

http://www.jekejeke.ch/idatab/doclet/blog/en/docs/10_dev/02_reference/testing/analyze.html

- The beautifer in action that colors clauses:
https://plus.google.com/+JekejekeCh/posts/4EP29tzxWp9

Unfortunately coloring itself still hybrid Java and Prolog. Can
be extended in the future for finer metrics.

Force to do it came from some pain with the current CLP(FD)
test cases. Was never sure how much I covered or not.

New module analyze will be published with the upcoming
release 1.1.4 of Jekejeke Prolog.

Bye




j4n bur53

unread,
May 30, 2016, 5:07:35 PM5/30/16
to
I am currently experimenting with moving some parts of the
pretty printer from Java to Prolog. Main reason is the coverage
analysis which needs more complex analysis, that I would like
to do in Prolog and not in Java.

I was takling the writing of the HTML anchor for a predicate.
So I had the following 3 algorithms which are all quadratic
but nevertheless work for small files:

1) Java Algorithm:
for X in predicates
for Y in X.context
if Y.source==S & Y.line_no==L
write HTML anchor for X

2) Prolog Algorithm I:
current_provable(X),
predicate_property(X, sys_context(S, _, L)),
write_anchor(X).

3) Prolog Algorithm II:
source_property(S, sys_context(X, _, L)).
write_anchor(X).


Timings were 1) 500 ms, 2) 180000 ms, 3) 700 ms. The timing of 2)
is cause by some overhead inside current_provable and
predicate_property, i.e. generating a predicate indicator
and then looking up the predicate indicator, since the Prolog
solution 2) shows a factor 360 over the solution 1) which
does the same.

So I went with solution 3). For this purpose I dropped the
sys_context/3 property from predicates altogether and introduced
this property with switched roles of the first argument for
sources. And started using this new modelling also in the coverage
analysis tool, so that I can pin down the coverage analysis down
to the predicate level.

The first results are encouraging:

Preview: Coverage analysis on predicate level. (Jekejeke)
https://plus.google.com/+JekejekeCh/posts/gA4Cgxbs3Qm

But now there is a new old problem. Namely in the coverage
analysis tool I only know the clause boundaries A and B.
What I then need to do is something along:

source_property(S, sys_context(X, _, R)).
A =< R, R < B

But every SQL programmer knows that an ordinary relational
database can do this in a blink. Just create an appropriate
index on R. And let the query evaluator do an index range
scan with the boundaries A and B.

But Prolog will have a hard time to do it!

Generally indexing in Prolog seldom supports range scans,
since the Prolog system will not have any info about requested
ranges, and it might need further info that clauses can
be reordered.

But CLP(*) could come to a rescue. The constraint store has
information about variable domains and thus ranges. So I should
be able to do this:

Convert the following:
p(R),
A =< R, R < B

Into the following I:
A #=< R, R #< B
p(R),

If A and B are bound, and R unbound, the invokation of p/1 should
pick an index, which understands range scans. For example a hash
index usually cannot do it, but a tree index might do it. And
then by using this index not waste any time on irrelevant clauses
of p/1. Go directly to the range.

With CLP(Z) maybe we could even do this:

Into the following I:
A =< R, R < B
p(R).

So making constraint ubiquitious could have a totally new benefit.
Not only that I can reorder. But also indexes that werent possible
in Prolog before could become possible.

Some Prolog systems around that combine CLP(*) with indexing this way?

Bye





Jan Burse schrieb:
0 new messages