Fast/concurrent update of facts

Author(s): Daniel Cabeza, Manuel Carro.

Prolog implementations traditionally implement the concept of dynamic predicates: predicates which can be inspected or modified at run-time, adding or deleting individual clauses. The power of this feature comes at a cost: as new clause bodies can be arbitrarily added to the program, new predicate calls can arise which are not 'visible' at compile-time, thus complicating global analysis and optimization of the code. But it is the case that most of the time what the programmer wants is simply to store data, with the purpose of sharing it between search branches, predicates, or even execution threads. In Ciao the concept of data predicate serves this purpose: a data predicate is a predicate composed exclusively by facts, which can be inspected, and dynamically added or deleted, at run-time. Using data predicates instead of normal dynamic predicates brings benefits in terms of speed, but above all makes the code much easier to analyze automatically and thus allows better optimization.

Also, a special kind of data predicates exists, concurrent predicates, which can be used to communicate/synchronize among different execution threads (see Low-level concurrency/multithreading primitives).

Data predicates must be declared through a data/1 declaration. Concurrent data predicates must be declared through a concurrent/1 declaration.


Usage and interface

Documentation on exports

PREDICATE
asserta_fact(Fact)

Fact is added to the corresponding data predicate. The fact becomes the first clause of the predicate concerned.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: asserta_fact(fact).

PREDICATE
asserta_fact(Fact,Ref)

Same as asserta_fact/1, instantiating Ref to a unique identifier of the asserted fact.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
    (term_typing:var/1)Ref is a free variable.
  • The following properties should hold upon exit:
    (data_facts:reference/1)Ref is a reference of a dynamic or data clause.
Meta-predicate with arguments: asserta_fact(fact,?).

PREDICATE
assertz_fact(Fact)

Fact is added to the corresponding data predicate. The fact becomes the last clause of the predicate concerned.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: assertz_fact(fact).

PREDICATE
assertz_fact(Fact,Ref)

Same as assertz_fact/1, instantiating Ref to a unique identifier of the asserted fact.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
    (term_typing:var/1)Ref is a free variable.
  • The following properties should hold upon exit:
    (data_facts:reference/1)Ref is a reference of a dynamic or data clause.
Meta-predicate with arguments: assertz_fact(fact,?).

PREDICATE
current_fact(Fact)

Gives on backtracking all the facts defined as data or concurrent which unify with Fact. It is faster than calling the predicate explicitly, which do invoke the meta-interpreter. If the Fact has been defined as concurrent and has not been closed, current_fact/1 will wait (instead of failing) for more clauses to appear after the last clause of Fact is returned.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: current_fact(fact).

PREDICATE
current_fact(Fact,Ref)

Fact is a fact of a data predicate and Ref is its reference identifying it uniquely.

Usage 1:

Gives on backtracking all the facts defined as data which unify with Fact, instantiating Ref to a unique identifier for each fact.

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
    (term_typing:var/1)Ref is a free variable.
  • The following properties should hold upon exit:
    (data_facts:reference/1)Ref is a reference of a dynamic or data clause.

Usage 2:

Given Ref, unifies Fact with the fact identified by it.

  • Call and exit should be compatible with:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold at call time:
    (data_facts:reference/1)Ref is a reference of a dynamic or data clause.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: current_fact(fact,?).

PREDICATE
retract_fact(Fact)

Unifies Fact with the first matching fact of a data predicate, and then erases it. On backtracking successively unifies with and erases new matching facts. If Fact is declared as concurrent and is non-closed, retract_fact/1 will wait for more clauses or for the closing of the predicate after the last matching clause has been removed.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: retract_fact(fact).

PREDICATE
retractall_fact(Fact)

Erase all the facts of a data predicate unifying with Fact. Even if all facts are removed, the predicate continues to exist.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: retractall_fact(fact).

PREDICATE
current_fact_nb(Fact)

Behaves as current_fact/1 but a fact is never waited on even if it is concurrent and non-closed.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: current_fact_nb(fact).

PREDICATE
retract_fact_nb(Fact)

Behaves as retract_fact/1, but never waits on a fact, even if it has been declared as concurrent and is non-closed.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: retract_fact_nb(fact).

PREDICATE
close_predicate(Pred)

Changes the behavior of the predicate Pred if it has been declared as a concurrent predicate: calls to this predicate will fail (instead of wait) if no more clauses of Pred are available.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Pred is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Pred is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: close_predicate(fact).

PREDICATE
open_predicate(Pred)

Reverts the behavior of concurrent predicate Pred to waiting instead of failing if no more clauses of Pred are available.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Pred is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Pred is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: open_predicate(fact).

PREDICATE
set_fact(Fact)

Sets Fact as the unique fact of the corresponding data predicate.

Usage:

  • The following properties should hold at call time:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
  • The following properties should hold upon exit:
    (basic_props:callable/1)Fact is a term which represents a goal, i.e., an atom or a structure.
Meta-predicate with arguments: set_fact(fact).

PREDICATE
erase(Ref)

Deletes the clause referenced by Ref.

Usage:

  • The following properties should hold at call time:
    (data_facts:reference/1)Ref is a reference of a dynamic or data clause.
  • The following properties should hold upon exit:
    (data_facts:reference/1)Ref is a reference of a dynamic or data clause.
  • The following properties should hold globally:
    (basic_props:native/1)This predicate is understood natively by CiaoPP.

REGTYPE

(True) Usage:reference(R)

R is a reference of a dynamic or data clause.

    Documentation on internals

    DECLARATION

    (True) Usage::- data Predicates.

    Defines each predicate in Predicates as a data predicate. If a predicate is defined data in a file, it must be defined data in every file containing clauses for that predicate. The directive should precede all clauses of the affected predicates. This directive is defined as a prefix operator in the compiler.

    • The following properties hold at call time:
      (basic_props:sequence_or_list/2)Predicates is a sequence or list of prednames.

    DECLARATION

    (True) Usage::- concurrent Predicates.

    Defines each predicate in Predicates as a concurrent predicate. If a predicate is defined concurrent in a file, it must be defined concurrent in every file containing clauses for that predicate. The directive should precede all clauses of the affected predicates. This directive is defined as a prefix operator in the compiler.

    • The following properties hold at call time:
      (basic_props:sequence_or_list/2)Predicates is a sequence or list of prednames.

    Known bugs and planned improvements

    • Run-time checks have been reported not to work with this code. That means that either the assertions here, or the code that implements the run-time checks are erroneous.