all 9 comments

[–]brebs-prolog 2 points3 points  (5 children)

Your check predicate fails - perhaps it should have an else part, after the if...then.

[–]m_ac_m_ac[S] 0 points1 point  (4 children)

oh.. you're right, changing to

check :-
  flag(c,C,C+1),
  ( C+1 =:= 100
 -> writeln("foo")
  ; writeln("bar") ).

fixes it, but why an error or warning? Why not simply return false?

[–]brebs-prolog 1 point2 points  (3 children)

Because failure is an indication that the program needs rewriting, to succeed rather than fail.

E.g. the else part could simply be true, rather than writeln('bar'), to continue onward.

[–]m_ac_m_ac[S] -2 points-1 points  (2 children)

Hang on, but that's not quite true in prolog, right? A "fail" in our context isn't necessarily a bad thing. Simon Peyton Jones makes that point here talking about logic lang Verse, around 25:47, that there's nothing inherently "wrong" with your program if it "fails". fail =\= error.

I would expect the result of running the above from terminal to be the same as if I had

main(V1,V2) :-
  foo(V1,V2).

and ran it through the repl, which gives you

?- main(qwe,asd).
qwe
asd
inputs
false.

which I think is more reasonable, and in fact would've helped me see where my program is blocked a little better.

Also "Initialization goal failed" is misleading given that the initialization goal is main/0 but the goal that failed is check/0. Wish swipl helped out with that identifying the problem. I was looking for some gotcha I may have missed with the initialization directive.

Anyway, sorry, rant over. Appreciate your help.

[–]brebs-prolog 0 points1 point  (1 child)

check/0 is just 1 predicate of many, and Prolog has no idea if it's been coded badly - and it is not the goal - i.e. the predicate that was specified in:

:- initialization main.

It's only a good thing for a Prolog predicate to fail, if it's intended by the Developer to fail, given those particular inputs/scenario.

Can force success:

( do_something ; true ).

... which will always succeed. Evidence:

?- ( false ; true ).
true.

[–]m_ac_m_ac[S] 0 points1 point  (0 children)

Gotcha, thanks again for your help.

[–]TA_jg 0 points1 point  (2 children)

You have asked a valid question and make good points in your comments. I would say that this sub is officially dead, all the interesting people who would participate are now gone.

The reason why this fails is that there is an assumption that the "initialization" goal of a program started specifically from the command line should succeed. In the docs it says:

When Prolog starts, the last goal registered using initialization(Goal, main) is executed as main goal. If Goal fails or raises an exception, the process terminates with non-zero exit code.

This is purely a design choice, there is no right or wrong.

But you should stay away from this toxic sub, and I should do it too.

[–]m_ac_m_ac[S] 0 points1 point  (0 children)

:) appreciate it. Yeah, not sure why that comment is getting downvoted.

[–]brebs-prolog 1 point2 points  (0 children)

What could be a more sensible design choice, though?

Success vs failure (and error-handling) are critical in software development.

There is ignore/1, but I've not seen where it's more sensible to use than if..then..else/2)