<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace">Some Prolog systems offer a so-called "soft cut".</div><div class="gmail_default" style="font-family:monospace,monospace">For example, in SWI Prolog, GNU Prolog, Jekejeke Prolog, and I think Yap:</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">%%  Â  Â  Â  Â A  Â  Â  Â  Â  Â  Â  Â  Â  Â  B</div><div class="gmail_default" style="font-family:monospace,monospace">?- ((X = 1 ; X = 2) *-> Y = yes ; Y = no).<br>X = 1,<br>Y = yes ;<br>X = 2,<br>Y = yes.<br></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">The soft cut removed the choice point at B but not the choice point at A.</div><div class="gmail_default" style="font-family:monospace,monospace">Colour me stupid, but I've never quite figured out what this *means*.</div><div class="gmail_default" style="font-family:monospace,monospace">I always felt that you should think of (A -> B ; C) as a more efficient</div><div class="gmail_default" style="font-family:monospace,monospace">(A , B ; \+(A), C) so that if \+(A) was semantically dodgy, you should</div><div class="gmail_default" style="font-family:monospace,monospace">not do that, but should restructure your Prolog code in some way.</div><div class="gmail_default" style="font-family:monospace,monospace">But that, of course, is Prolog.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">What the manual is saying here is that</div><div class="gmail_default" style="font-family:monospace,monospace">(A -> B ; C) in Mercury is like (A -> B ; C) in Prolog</div><div class="gmail_default" style="font-family:monospace,monospace">and</div><div class="gmail_default" style="font-family:monospace,monospace">(if A then B else C) in Mercury is like (A *-> B ; C) in many Prologs.</div><div class="gmail_default" style="font-family:monospace,monospace">C will be executed only if A has no solutions, otherwise it acts like</div><div class="gmail_default" style="font-family:monospace,monospace">(A, B).</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">In your particular example, where Char is ground, Char = '(' has at most</div><div class="gmail_default" style="font-family:monospace,monospace">one solution, and the same for Char = ')', so there shouldn't be any</div><div class="gmail_default" style="font-family:monospace,monospace">difference between the -> ; version and the if then else version.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 5 Jul 2019 at 22:29, emacstheviking <<a href="mailto:objitsu@gmail.com">objitsu@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">OK, I read everybodies comments, read all the suggested links and I amended my code to be like so:<div><br></div><div><font face="courier new, monospace">:- pred char_type(char::in, chartype::out) is det.<br><br>char_type(Char, Type) :-<br>  Â  ( Â  if Â  Â  Â Char = '(' then Type = p_open<br>  Â  Â  Â  else if Char = ')' then Type = p_close<br>  Â  Â  Â  else Â  Â Type = c_general<br>  Â  ).<br></font></div><div><br></div><div>This works as desired and as expected which is great, but....understanding why! I can see that by using the if-then-else that the final else clause has no mention of Char, whereas before I had "Char = _"...  Â  meaning that multiple solutions where available. In the polog-mercury transition docs, section 6 cuts and indexing it says:</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Mercury allows if-then-elses to be written not just as â€˜C -> T ; E’, but also as â€˜if C then T else E’. In Mercury, an if-then-else prunes away either the â€˜else’ goal (if the condition succeeded) or the â€˜then’ goal (if the condition failed), but if there are multiple solutions to the condition, they will all be found on backtracking, and the â€˜then’ goal will be executed for each of those solutions. By contrast, an if-then-else in Prolog prunes away all solutions of the condition except the first.</blockquote><div><br></div><div>But I find this hard to decipher. I can see the equivalence between the two expression forms, that's the easier part, but I am confused where it says "but if there are multiple..." because if the if-the-else is syntactic sugar...? But it says something about pruning away the else goal or the then goal(s) etc. I think I nearly have it but I find my brain feeling like trying to climba greasy pole at time and I really really want to understand this.</div><div><br></div><div>All I seek is some clarification over why the if-then-else works as I expected it too and I can assimilate that and move on!</div><div><br></div><div>Thanks again,</div><div>Sean.</div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 5 Jul 2019 at 05:17, Julian Fondren <<a href="mailto:jfondren@minimaltype.com" target="_blank">jfondren@minimaltype.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 2019-07-04 17:46, emacstheviking wrote:<br>
> Thanks Richard!<br>
> <br>
> That is so obvious when you see it. I am thinking like a Haskell<br>
> hacker this evening for sure.<br>
> I changed it to "cc_multi" and it compiled ANd did what I expected /<br>
> wanted.<br>
<br>
It may do you what you want, but this is by accident. It is legal for<br>
the cc_multi version of your code to report that '(' is a c_general<br>
rather than a p_open.<br>
<br>
Consider:<br>
<br>
<a href="https://mercurylang.org/information/doc-latest/mercury_ref/Semantics.html" rel="noreferrer" target="_blank">https://mercurylang.org/information/doc-latest/mercury_ref/Semantics.html</a><br>
<br>
Or this chapter of the Prolog to Mercury guide:<br>
<br>
<a href="https://mercurylang.org/information/doc-latest/mercury_trans_guide/Commits.html" rel="noreferrer" target="_blank">https://mercurylang.org/information/doc-latest/mercury_trans_guide/Commits.html</a><br>
<br>
I don't know Prolog well at all, and wouldn't've benefited from that<br>
chapter since I'm not familiar with that pattern of cuts and a<br>
catch-all, but I've run into your exact problem of wanting to say<br>
<br>
  Â char_type(')', p_open).<br>
  Â char_type('(', p_close).<br>
  Â char_type(_, c_general).<br>
<br>
because functional languages with pattern-matching all do it in an<br>
ordered way that permits very similar constructs. This is probably<br>
what you meant by "thinking like a Haskell hacker" but even C's<br>
switch() statement permits this sort of thing. For Mercury you can try<br>
viewing your code through the lens of the strict commutative<br>
semantics.<br>
<br>
So when looking at that code, imagine<br>
<br>
  Â char_type(_, c_general).<br>
  Â char_type(')', p_open).<br>
  Â char_type('(', p_close).<br>
<br>
or<br>
<br>
  Â char_type(')', p_open).<br>
  Â char_type(_, c_general).<br>
  Â char_type('(', p_close).<br>
<br>
or<br>
<br>
  Â char_type('(', p_close).<br>
  Â char_type(_, c_general).<br>
  Â char_type(')', p_open).<br>
<br>
...<br>
<br>
If any variation doesn't look like something you'd want, your original<br>
code isn't what you want either.<br>
_______________________________________________<br>
users mailing list<br>
<a href="mailto:users@lists.mercurylang.org" target="_blank">users@lists.mercurylang.org</a><br>
<a href="https://lists.mercurylang.org/listinfo/users" rel="noreferrer" target="_blank">https://lists.mercurylang.org/listinfo/users</a><br>
</blockquote></div>
_______________________________________________<br>
users mailing list<br>
<a href="mailto:users@lists.mercurylang.org" target="_blank">users@lists.mercurylang.org</a><br>
<a href="https://lists.mercurylang.org/listinfo/users" rel="noreferrer" target="_blank">https://lists.mercurylang.org/listinfo/users</a><br>
</blockquote></div>