Skip to content

Conversation

dougransom
Copy link

A few examples on using reif.


Review the summary at 25:45 [Power of Prolog meta_predicate declarations](https://www.youtube.com/watch?v=m3cbgebcKng). You will need some understanding of meta_predicate declarations.

Typically, reif predicates provided as arguments typically require the last additional argument will be a reified binary value.
Copy link
Contributor

@hurufu hurufu Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"typically" that is followed by another "typically" in the same sentence. Also it isn't "typically" but "always" :), but there was a proposal to extend this: #2722 (reply in thread)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed typically.


## Introduction and meta_predicate Review

Review the summary at 25:45 [Power of Prolog meta_predicate declarations](https://www.youtube.com/watch?v=m3cbgebcKng). You will need some understanding of meta_predicate declarations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think a beginner should really know about meta-predicates to use reif? What was your feeling? I thought that you should only know how partial goals work, like: call(length("123"), N) and that's all.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are correct.

Fortunatley, you don't need to understand that mechanism to use the reif module. Below there examples of how to use if_.


Also, don't be confused when something like this works:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall lamenting style might give wrong impression for a novice reader. IMHO, API reference should be very dry and to the point, but tutorials might have more inviting style.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the wording a bit, better?

Comment on lines 111 to 118
length(L1,2),length(L2,2),memberd_t(A,L1,X), memberd_t(A,L2,Y), dif(X,Y).
L1 = [A,_C], L2 = [_A,_B], X = true, Y = false, dif:dif(_A,A), dif:dif(_B,A)
; L1 = [_A,A], L2 = [_B,_C], X = true, Y = false, dif:dif(_A,A), dif:dif(_B,A), dif:dif(_C,A)
; L1 = [_A,_B], L2 = [A,_C], X = false, Y = true, dif:dif(_A,A), dif:dif(_B,A)
; L1 = [_A,_B], L2 = [_C,A], X = false, Y = true, dif:dif(_A,A), dif:dif(_B,A), dif:dif(_C,A)
; false.
?-
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have more examples like this in general, because it is difficult to realize versatility of even the simplest of predicates. #2971 (reply in thread)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you wan to add some, before or after this PR is merged?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that was a general comment.

Comment on lines 169 to 170
greater_than_two(Y,T) :- Y #> 2 ,T=true.
greater_than_two(Y,T) :- Y #< 2 ,T=false.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not greater_than_two(Y, true) :- Y #> 2.? Also seconds clause should use #=< relation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

tfilter(C_2, Es, Fs).
```

The meta_predicate directive is important. It specifies the first parameter to tfilter is a predicate needing two more arguments. The first required argument is the value to be compared from the list, and the second is the reified result of the comparison (true, or false).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meta_predicate is and isn't important at the same time. It is a hint to the Prolog system, but this code will work without meta-predicate declaration too (just not always as expected ;) )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed discussion of meta predicates.

Comment on lines 139 to 143
## if_/3

if_1 calls predicate If_1, adding on the last argument the predicate expects, which is a boolean value, T.
if T then calls the predicate Then_0
otherwise, calls the predicate Else 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an expert, but IMO the point of if_/3 is "indexing" it doesn't do any magic you can do everything it does while using dif/2, but it cleverly reduces amount of choice points – which is a real deal.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am less of an expert. I understand these predicates are also likely to be more monotonic or pure and therefore harder to write incorrect programs as well as some efficiency considerations. You want to add some language?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I don’t think “indexing” is explained adequately either.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal at this point is to provide enough examples that make it easier to get going using reif for the basics.

I might (or any other contributor might) add more examples with an explanation of benefits such as efficiency or monotonicity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal at this point is to provide enough examples that make it easier to get going using reif for the basics.

Totally. That's why I don't think it helps to explain in terms of jargon like "indexing". I think you're right that if_ should be understand in terms of what it gets YOU, the programmer, in terms of correctness.

@dougransom dougransom requested a review from hurufu September 26, 2025 14:23
Copy link

@UWN UWN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to read the cited article first. Not conforming to the naming convention, starting with an incorrect example is not helpful for a tutorial. Instead the major focus should be on using the existing conditions.

```prolog

```
pound_gt(X,Y,true):- X #>Y,!.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-relational.

?- pound_gt(3,1,false).
   true.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

But (in my system at the time of writing) #>/2 exists, but there is no #>/3.
A workaround is to define a three-arity predicate to do the comparison (it could be #>/3, but I choose pound_gt):
```prolog

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name is inappropriate, if it is reifying, then the last argument is either _t, or it is an operator.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. Is there a reference to that convention?

Copy link

@UWN UWN Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the link in library(reif)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attempted to update the names throughout to be consistent with the convention.


```prolog
```
?- memberd_t('c',"branch free",true).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No single quotes needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.

?-
'''
```
What is happening is that reif has provided =/3, and that is what is being used in tfilter (not the usual =/2).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's (=)/2 and not =/2 which is just invalid syntax

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attempted to correct syntax for operators throughout the document, where they were not correctly surrounded by parenthesis.


```prolog
```
length(L1,2),length(L2,2),memberd_t(A,L1,X), memberd_t(A,L2,Y), dif(X,Y).
Copy link

@UWN UWN Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing ?-

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected.

## (=)(A,B,T).
```

## (=)(A,B,T).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntactically incorrect.

## Introduction

Review the summary at 25:45 [Power of Prolog meta_predicate declarations](https://www.youtube.com/watch?v=m3cbgebcKng). You will need some understanding of meta_predicate declarations.
reif predicates will have as an argument a predicate requiring at least one additional argument. That predicate's last argument will be the reified value of the predicate.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, what are reif predicates?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed that language.

@rotu
Copy link
Contributor

rotu commented Oct 1, 2025

You keep using the term "reify" in many different senses, which complicates understanding. Are we reifying a predicate? A goal? A condition? A truth value? A definition? A concept?

I would stick to only talking about "reified predicates" or predicates "reified by a variable".

In reif the further conventions hold (and I think this is what you mean by the phrase "reif predicates"):

  1. There are two truth values, corresponding to the atoms true and false. This is not trivial - the SICStus manual defines a reified constraint as having truth value 0 or 1.
  2. The predicates in reif are all reified to their last argument.

@dougransom
Copy link
Author

You keep using the term "reify" in many different senses, which complicates understanding. Are we reifying a predicate? A goal? A condition? A truth value? A definition? A concept?

I would stick to only talking about "reified predicates" or predicates "reified by a variable".

In reif the further conventions hold (and I think this is what you mean by the phrase "reif predicates"):

  1. There are two truth values, corresponding to the atoms true and false. This is not trivial - the SICStus manual defines a reified constraint as having truth value 0 or 1.
  2. The predicates in reif are all reified to their last argument.

I think I have made this more clear.

@dougransom
Copy link
Author

Ouptput from doclog, so you don't have to run it yourself:

reif_examples.html

@dougransom dougransom requested review from UWN and rotu October 6, 2025 00:14
@dougransom
Copy link
Author

Is this ok now for a first cut? I plan to add to it in another version one i understand how to use (,) and (;). I’d like to get this published first.

@triska
Copy link
Contributor

triska commented Oct 8, 2025

Is there any need to mention (->)/2 in this text, especially so close to the beginning? Or (is)/2, which is mentioned even earlier? These constructs are very hard to understand, and (->)/2 easily leads to elementary mistakes in programs.

@dougransom
Copy link
Author

Is there any need to mention (->)/2 in this text, especially so close to the beginning? Or (is)/2, which is mentioned even earlier? These constructs are very hard to understand, and (->)/2 easily leads to elementary mistakes in programs.

Probably not. Honestly i never tried (->) before writing this tutorial. I’ll address that. I may reintroduce-> and (is) in a later version to illustrate the problems with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants