User defined predicate properties

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:

?- knowledge_property(author_of_predicate_knowledge,formula(e=mc**2,_),Value).
Value=author('Albert Einstein', [iri(''),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.

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 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


then adding a primary key it would become


The associated property fact would be

knowledge_property(key(101,author)-author('Albert Einstein', [iri(''),type(human),...])).

The next logical step is then to use persistency.


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.

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.

1 Like