# Library(yall) appears to be confusing predicate\_property/2, clause/3

**URL:** <https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150>\
**Category:** Help!\
**Tags:** bug\
**Created:** [July 9, 2021, 5:15pm UTC](https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150 "2021-07-09T17:15:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 9, 2021, 5:15pm UTC](https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150/1 "2021-07-09T17:15:06Z")

</div>

_Ignore this_ – I figured out my mistake.

I’m working on protobufs.pl and hacking `test_cover.pl` to make sure my test cases are sufficient. None of the code directly uses library(yall), but apparently it’s getting imported indirectly.

Questions:

1. How do I figure out what is importing library(yall)?
2. How do I turn off the weird behavior of yall’s (/)/2 predicate?

Here are details from a session, with some comments interspersed.

```prolog
$ /usr/bin/swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.26)

?- [library(protobufs)].
true.

```

The code for `write_type/5` consists of 6 facts and is here: [contrib-protobufs/protobufs.pl at 42ff818ff8603b129daea44ff986de6f97ede219 · SWI-Prolog/contrib-protobufs · GitHub](https://github.com/SWI-Prolog/contrib-protobufs/blob/42ff818ff8603b129daea44ff986de6f97ede219/protobufs.pl#L99) … I confirm this by:

```prolog
?- forall(protobufs:wire_type(T,V), writeln(wiretype(T,V))).
wiretype(varint,0)
wiretype(fixed64,1)
wiretype(length_delimited,2)
wiretype(start_group,3)
wiretype(end_group,4)
wiretype(fixed32,5)
true.

```

So, there should be 6 results from clause/3 … but no:

```prolog
?- clause(protobufs:wire_type/2, Body, Ref).
false.

```

So, I try to find the predicate properties. Note the following strange values:  
`imported_from(yall)`  
`file(/usr/lib/swi-prolog/library/yall.pl)`  
`number_of_clauses(1)` – should be 6.  
`line_count(275)` – discussed below

```prolog
?- forall(predicate_property(protobufs:wire_type/2, P), writeln(P)).
interpreted
visible
static
imported_from(yall)
transparent
meta_predicate? / 0
file(/usr/lib/swi-prolog/library/yall.pl)
line_count(275)
number_of_clauses(1)
number_of_rules(1)
last_modified_generation(5556)
defined
size(384)
true.

```

And now clause/3 succeeds – although with a strange `Body`:

```prolog
?- clause(protobufs:wire_type/2, Body, Ref).
Body = (lambda_free(wire_type), copy_term_nat(wire_type+2, wire_type+_548), call(_548)),
Ref = <clause>(0x560e3a6f4720).

```

As for `line_count(275)`: it corresponds to this: [swipl-devel/yall.pl at 5772c803985cb8f88b0f96052abf8c939f8b8c23 · SWI-Prolog/swipl-devel · GitHub](https://github.com/SWI-Prolog/swipl-devel/blob/5772c803985cb8f88b0f96052abf8c939f8b8c23/library/yall.pl#L275)

```prolog
'/'(Free, Lambda) :-
    lambda_free(Free),
    copy_term_nat(Free+Lambda, Free+LambdaCopy),
    call(LambdaCopy).

```

which is exported by library(yall).

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 9, 2021, 5:31pm UTC](https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150/2 "2021-07-09T17:31:20Z")

</div>

Arrrggghhhh!!!

I yet again got confuseded by `foo/2` vs `foo(_,_)` when looking up predicate properties.

Is there a standard way of describing these two ways of referring to predicates?

As for converting the forms: library(prolog\_code) pi\_head/2.

_Edit:_ What’s especially confusing is that current\_predicate/2 uses the `foo/2` form but predicate\_property/2 uses the `foo(_,_)` form.

---

<div class="post-metadata">

**Author:** ![dgelessus](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dgelessus/32/3106_2.png) [@dgelessus](https://swi-prolog.discourse.group/u/dgelessus)\
**Post date:** [July 9, 2021, 5:55pm UTC](https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150/3 "2021-07-09T17:55:53Z")

</div>

> [@peter.ludemann](#):
>
> Is there a standard way of describing these two ways of referring to predicates?

Not sure if this is what you’re asking, but the form `foo/2` is called a “predicate indicator” (SWI, YAP) or “predicate spec” (SICStus, Ciao). `foo(_,_)` is usually just called a “head” or “goal”. Somewhere I’ve also read “skeletal goal” for the case where all arguments of the term are `_` and not some other value.

(pi\_head/2 stands for “predicate indicator/head”)

And yeah, this is always a fun pitfall. The best “solution” I know is to assume that everything expects the head term form (`foo(_,_)`) unless you know otherwise - because if you try to pass a head term where a predicate spec is expected, you get an error, so you notice when you did it wrong. The other way around (passing a predicate spec where a head term is expected) you silently get wrong results, as you’ve found out 🙂

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 9, 2021, 5:59pm UTC](https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150/4 "2021-07-09T17:59:58Z")

</div>

> [@dgelessus](#):
>
> if you try to pass a head term where a predicate spec is expected, you get an error

Maybe we need a different form of current\_predicate/2 … this is what confused me:

```prolog
?- current_predicate(protobufs:P), predicate_property(protobufs:P, file(File)).
P = protobuf_tag_type/4,
File = '/home/peter/src/swipl-devel/build/home/library/yall.pl' ;

```

whereas I should have written:

```prolog
?- current_predicate(protobufs:P0), pi_head(P0,P), predicate_property(protobufs:P, file(File)).
P0 = protobuf_tag_type/4,
P = protobuf_tag_type(_5538, _5540, _5542, _5544),
File = '/home/peter/src/swipl-devel/build/home/library/protobufs.pl' 

```

I suppose a good type-checker would have caught this. 😈

---

<div class="post-metadata">

**Author:** ![dgelessus](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dgelessus/32/3106_2.png) [@dgelessus](https://swi-prolog.discourse.group/u/dgelessus)\
**Post date:** [July 9, 2021, 6:07pm UTC](https://swi-prolog.discourse.group/t/library-yall-appears-to-be-confusing-predicate-property-2-clause-3/4150/5 "2021-07-09T18:07:45Z")

</div>

> [@peter.ludemann](#):
>
> Maybe we need a different form of [current\_predicate/2](https://www.swi-prolog.org/pldoc/doc_for?object=current_predicate/2) …

current\_predicate/2 is actually the different form you’re looking for 🙂 For even more confusion, current\_predicate/1 (which you use in your example code) uses predicate specs, but the 2-argument version uses head terms:

```prolog
?- current_predicate(lists:PI).
PI = selectchk/3 ;
PI = append/3 ;
% ...
?- current_predicate(_, lists:Head).
Head = selectchk(_23944, _23946, _23948) ;
Head = append(_24686, _24688, _24690) ;
%...

```

> [@peter.ludemann](#):
>
> I suppose a good type-checker would have caught this.

It might not, because `protobuf_tag_type/4` is technically a valid head, even if it’s a very unusual one… A linter should definitely warn about it though.
