# User defined predicate properties

**URL:** <https://swi-prolog.discourse.group/t/user-defined-predicate-properties/4537>\
**Category:** Predicate\
**Created:** [October 9, 2021, 8:47pm UTC](https://swi-prolog.discourse.group/t/user-defined-predicate-properties/4537 "2021-10-09T20:47:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [October 9, 2021, 8:47pm UTC](https://swi-prolog.discourse.group/t/user-defined-predicate-properties/4537/1 "2021-10-09T20:47:13Z")

</div>

Is there a way to set a user-defined predicate property?

My use case is having a large (and changing) human knowledge base that is expressed using prolog predicates. I would like to be able to attach ‘properties’ to the predicates (and maybe even specific clauses) so that I can query something like this:

```prolog
?- knowledge_property(author_of_predicate_knowledge,formula(e=mc**2,_),Value).
Value=author('Albert Einstein', [iri('https://en.wikipedia.org/wiki/Albert_Einstein'),type(human),...]).

```

I can think of two ways to do this (there are probably many more):

1. Use term\_expansion, and declare predicates with some predefined syntax. The term\_expansion would take care of storing clause/predicate properties.

2. Use something modeled after :- begin\_test/end\_test; something like :- begin\_properties(…), :- end\_properties(…), especially for cases where the propertie(s) are the same for a group of predicates.

However I wanted to see if there is already a built-in way that I can use to set properties and then call predicate\_property/2 to get the user-defined property.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [October 9, 2021, 9:21pm UTC](https://swi-prolog.discourse.group/t/user-defined-predicate-properties/4537/2 "2021-10-09T21:21:41Z")

</div>

If you think in terms of an SQL database then just add a primary key to each predicate. Then if the data was in an SQL database you would add another table using the primary key as a foreign key.

A nice way to implement such a table in Prolog is to use [assoc list](https://eu.swi-prolog.org/pldoc/man?section=assoc) and create a key of the primary key and the property name, then the associated value is the value for the property.

So if the starting fact is

```prolog
knowledge(formula(e=mc**2)).

```

then adding a primary key it would become

```prolog
knowledge(101,formula(e=mc**2,_))

```

The associated property fact would be

```prolog
knowledge_property(key(101,author)-author('Albert Einstein', [iri('https://en.wikipedia.org/wiki/Albert_Einstein'),type(human),...])).

```

The next logical step is then to use [persistency](https://www.swi-prolog.org/pldoc/man?section=persistency).

HTH

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [October 10, 2021, 12:55am UTC](https://swi-prolog.discourse.group/t/user-defined-predicate-properties/4537/3 "2021-10-10T00:55:46Z")

</div>

Thanks EricGT, that is a useful model to keep in mind. Common also in the prolog world.

I my case it doesn’t really work because I can not impose that kind of structure on the predicate (i.e wrapping it in knowledge/2).

Granted, I could use term\_expansion to implement something similar to what you mentioned, and that would be covered by option#1 that I mentioned in my original post.

What I was really wondering is if I can reuse predicate\_property/2 somehow.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 10, 2021, 7:19am UTC](https://swi-prolog.discourse.group/t/user-defined-predicate-properties/4537/4 "2021-10-10T07:19:15Z")

</div>

I think both your proposals make sense. You may also analyze your loaded program and derive properties. Next, you create a binary predicate relating a head term to the property and you are done. E.g.

```
 my_prop(m:p(_), iri(...)).

```

I don’t see much added value in allowing something like set\_predicate\_property/2 to add properties for the system predicate\_property/2.
