Trying out a new formatting style

For today I have switched to this style:

This comes from Elm (for example: groceries ) and I also saw it somewhere on Rosettacode.

express2_dl(Tip,Fin,Str) :-
    Tip =@= Fin  % "structurally equal"
   ,var(Fin)     % and this must also be true
   ,!           
   ,Str="Empty difflist: ∅"
   .

… turns out to be relatively neat as you can easily remove or add lines, check whether commas and dots are there and whether there is a ; lurking in the jungle of the suffixes.

It is just a bit sad that the compiler doesn’t like a comma before the first conjunctive element (which is the cut a conjunctive element btw, it should be in comma position?), that would be even neater:

express2_dl(Tip,Fin,Str) :-
   ,Tip =@= Fin  % "structurally equal"
   ,var(Fin)     % and this must also be true
   ,!           
   ,Str="Empty difflist: ∅"
   .

Just gives

Syntax error: Operator expected

Curses!

(Btw, I thought SWI-Prolog indexes clauses on more than the first argument? I found that adding an integer as first argument makes my program semideterministic. Moved the integer argument to the last position immediately.)

1 Like

It seems there must be some unwritten book on the journey of finding better ways to comment out lines as I did that for a few days many years ago but now prefer to add just true as needed and typically as the last goal, e.g.

express2_dl(Tip,Fin,Str) :-
   Tip =@= Fin,  % "structurally equal"
   var(Fin),     % and this must also be true
   !,           
   Str="Empty difflist: ∅",
   true.

This also works with -> ;, e.g.

foo(A,B) :-
   (
      test
   ->
      bar_1(A),
      true
   ;
      bar_2(B),
      true
   ),
   true.
1 Like

Note that can degrade the performance of what otherwise would be a tail-recursive predicate definition.

1 Like

I thought that SWI-Prolog optimized away true? (At least, with the -O flag.)

1 Like

It does. That’s why I wrote “can” instead of “will” :slight_smile:

Ooof no! :wink:

The following code is taken from a parallel logic programming language interpreter’s top-level loop. I don’t think I write Prolog code any more complicated than this. ‘Normal’ Prolog formatting works just fine.

%%%
%%% Test code
%%%
test_loop :-
        ask_query(test_query, [], [], A),
        Term0-Vars = A,
        '$expand_term'(Term0, Term1), 
        (   demo(Term1),        
            (   Vars = [] ->
                print_message(informational, 'Yes.')    
            ;   phrase(substitution_message(Vars), QueryText), 
                '$savecp'(CP),
                repeat,
                ask_query(test_solution, 
                          QueryText, 
                          ['";" - backtrack for another solution.'-[], nl, 
                          '<return> - continue.'-[], nl],
                          A2), 
                (   A2 = yes -> 
                    print_message(informational, 'Yes.')
                ;   '$cutto'(CP),   % remove the choicepoint created by repeat/0 above
                    fail
                )
            )
        ;   print_message(informational, 'No.')         
        ),
        test_loop.

I think dtonhofer may have chosen a title that is misleading. When I read the title I thought what you are alluding to but in reading the context noticed that it was more about a poor man’s way of bug hunting by commenting out lines. When the lines start with a comma or have a predicate or section that ends with true then it is very easy to just comment out one or more line(s) and with the editor I use it is a quick Ctrl-/ to turn commenting for those line(s) on or off again and again.

Glad you described it as the “poor man’s way”. Anybody who spends time making that sort of work easy is misguided. The effort is better spent learning to use the debugger. I’m sorry if that statement sounds harsh but, hey, can anybody really argue against it?

Another variation on it is using it as a poor man’s GitHub. Instead of pushing after every failed attempt so you can go back to the last revision that was closest to working, you just keep piling up lines of code that don’t work. I do use this means on occasions to spot a pattern in the predicates that work as they are lined up in the code on top of each other and then get an understanding of what the predicate does. Usually only have to use it on predicates where I don’t have access to the source code and it is a black box, but yes I prefer other ways of not only finding the bugs but figuring out how to correctly implement or model the problem.

1 Like

Yes. Was it O’Keefe that wrote there was no substitute to understanding your problem? When code gets altered until it starts ‘working’ then it is always messy and almost always a result of panic. Sometimes you’ve just got to take a step back, brew a nice cup of tea, then start thinking of the bigger picture.

MMORPGs are my place where the unconscious brain often solves many of my problems and finds many connections to closed world problems, I especially like Hamiltonian Paths.

With regards to debugging Prolog we have Bug hunting toolbox, feel free to edit or add to it.

That’s a useful resource which I hopefully would have good use of as a beginner. However, there’s little or nothing in that list which I use today. To the programmer who wants to advance I would suggest they write their own debugger for specific debug tasks. You start with a simple metacircular interpreter and build in tracing printouts like this:

my_debugger(true) :- !.
my_debugger((G1, G2)) :- !, my_debugger(G1), my_debugger(G2).
my_debugger((G1; G2)) :- !, (my_debugger(G1); my_debugger(G2)).                                                                             
my_debugger(G) :- pre(G), clause(G, C), my_debugger(C), post(G).
pre(G) :- write(call), tab(1), write(G), nl.
pre(G) :- write(fail), tab(1), write(G), nl, fail.
post(G) :- write(exit), tab(1), write(G), nl.
post(G) :- write(redo), tab(1), write(G), nl, fail.

Then when you notice interesting predicates you add clauses to my_debugger/1 to hone in on them and give them special treatment. Basically you build a bespoke debugger for your specific problem.

1 Like

I am not sure this is so much poor man's debugging, since some of the well known people in the prolog world use a technique called ‘failure slicing’ or ‘program slicing’, which is similar to commenting out goals. One of the tricks posted in old prolog lists (I think it was Ulf from ISO) is this:

:- op(920,fy, *).
*_.

Then you can use * in front of a goal to comment it out. Like this:

1 ?- [user].
|:  a :- 
|:    b,
|:    c,
|:    d.
|: 
|:  a1 :-
|:    b,
|:    *c,
|:    d.
|: b. d.
|: 
|:  c :- false.
|: % user://1 compiled 0.02 sec, 5 clauses
true.

2 ?- a.
false.

3 ?- a1.
true.
 

Prolog is amazing in terms of the kind of things you can do.

1 Like

I have to admit that was nice. I wouldn’t use it for debugging though… :slight_smile:

Yes I am aware that Ulrich Neumerkel uses it often on StackOverflow.

Here are more operators for using it and here is the paper for it.

Oh I see its from “Metacircular Interpreter (Prolog)” in your notes.
In these notes, some propositonal provers are burried:

Computational Logic Notes

How about a prover that can also do FOL? Do I need to combine
skolemization with something? But resolution says propositional only?

P.S.: Its an open challenge here Terminology: "true", "entailed", "provable", "holds" - #15 .
Here Schubert's Steamroller in Prolog - #5 by bwat something was first negation as failure,
but then Eco Logic came into play, the later I didn’t understand.

I do that with lists of things in Haskell, it’s pretty common. However, I am now a reasonably firm practitioner of the guidelines by Covington et al. It’s clean and simple and fashions come and go but this just keeps me happy.

1 Like

Since I haven’t re-read Coding Guidelines for Prolog (PDF) in a few months re-read it again and noticed that it needs to be updated to include tabling .

1 Like

No, the debugger is from the manual. The metacircular interpreter in my notes is an actual metacircular interpreter for a pure Prolog, i.e., it is capable of interpreting itself.

Those are just my private notes I keep online for access anywhere. I wouldn’t bother reading them if I were you as you’ve no doubt got better sources of knowledge available.

I am more interested in code than knowledge. I guess this one is also a
goldie but oldie. But does it have an accompanying code repository?

Chapter 8
The Connection Graph Proof Procedure
Logic for Problem Solving - Robert Kowalski - 1979
https://www.researchgate.net/publication/277669992

How old is Robert Kowalski. Does LPA have some code base? I just
noticed that micro-Prolog is now on GitHub:

Disassembled code of SPECTRUM
The first versions were implemented at Imperial College London
under the supervision of Robert Kowalski between 1979 and 1980.
https://github.com/oldcompcz/micro-PROLOG

If you have tapes, dump them quickly into something
modern before its dust in the wind.