Builtin predicates - Clause handling

Predicates in this group are used to add and remove clauses from the predicate database dynamically. There are two types of databases in the Plang system: global and local.

The global database is shared between all parts of the Plang system and contains the following:

As an example, we consider a theorem prover for propositional logic. The prover needs simplification rules to convert complex logical expressions into simpler ones. Rather than fix the set of rules at compile time, the theorem prover allows the user to add new rules at runtime. To support this, we declare the simplify/2 predicate as dynamic and add the predefined rules as follows:

 :- dynamic(simplify/2).
 add_rules()
 {
     assertz(simplify(in A && A, A));
     assertz(simplify(in B || true, true));
     ...
 }

To use the rules to simplify a logical expression, the application calls the simplify/2 predicate in the usual fashion:

 simplify(Expr, Simplified);

When the user supplies a new rule, the application can call asserta/1 or assertz/1 to add the new rule to the start or end of the existing dynamic clause list. Rules that are no longer needed can be removed with retract/1.

In practice, theorem provers rarely implement a single theory of logic. We want our prover to be extensible from propositional logic to first order logic, higher order logic, and so on. Each logical theory will need its own simplification rules. We could define separate global predicates for each theory: prop_simplify/2, fo_simplify/2, etc. An alternative is to use local databases.

The application creates local databases with new_database/1 to store additional predicates that are generated at runtime. Each local database defines a separate scope - the same predicate name can have different purposes in different local databases.

Returning to our example, we will create a generic class to hold information about a logical theory. The constructor creates a new local database to hold the rules that make up the theory:

 class theory
 {
     var rules;
     new() { new_database(Self.rules); }
 }

We can then create our theory object for propositional logic as follows:

 new theory(Prop);
 assertz(simplify(in A && A, A), Prop.rules);
 assertz(simplify(in B || true, true), Prop.rules);
 ...

To use the simplification rules, we need to call the local predicate with call/2:

 call(simplify(Expr, Simplified), Prop.rules);

The local predicate is executed in a context where the current database is set to Prop.rules. If the local predicate calls other predicates, they will first be looked up in the local database, and then the global database.

abolish/1, abolish/2, abolish_database/1, asserta/1, asserta/2, assertz/1, assertz/2, clause/2, clause/3, new_database/1, retract/1, retract/2


abolish/1 - removes a user-defined predicate from the predicate database.

Usage
abolish(Pred)
Description
Removes all clauses from the predicate database that are associated with the predicate indicator Pred and succeeds. The indicator should have the form Name / Arity. If the predicate does not exist, then succeeds.
Removing a predicate that is in the process of being executed leads to undefined behavior.
Errors
Examples
 abolish(userdef/3)       succeeds
 abolish(Pred)            instantiation_error
 abolish(Name/3)          instantiation_error
 abolish(userdef/Arity)   instantiation_error
 abolish(1.5)             type_error(predicate_indicator, 1.5)
 abolish(userdef/a)       type_error(integer, a)
 abolish(1/a)             type_error(integer, a)
 abolish(1/3)             type_error(atom, 1)
 abolish(userdef/-3)      domain_error(not_less_than_zero, -3)
 abolish(abolish/1)       permission_error(modify, static_procedure, abolish/1)
Compatibility
Standard Prolog
See Also
abolish/2, asserta/1, retract/1

abolish/2 - removes a user-defined predicate from a local predicate database.

Usage
abolish(Pred, Database)
Description
Removes all clauses from the specified local predicate Database that are associated with the predicate indicator Pred and succeeds. The indicator should have the form Name / Arity. If the predicate does not exist, then succeeds.
Removing a predicate that is in the process of being executed leads to undefined behavior.
Errors
Examples
 new_database(DB);
 assertz(userdef(a, b, c), DB);
 abolish(userdef/3, DB);
See Also
abolish/1, abolish_database/1, asserta/2, new_database/1, retract/2

abolish_database/1 - removes all predicates from a local predicate database.

Usage
abolish_database(Database)
Description
Removes all predicates from the specified local predicate Database and succeeds.
Removing predicates that are in the process of being executed leads to undefined behavior.
Errors
Examples
 new_database(DB);
 assertz(userdef(a, b, c), DB);
 assertz(simplify(in A && A, A), DB);
 abolish_database(DB);
See Also
abolish/2, asserta/2, new_database/1, retract/2

asserta/1, assertz/1 - adds a clause to the start/end of a user-defined predicate in the predicate database.

Usage
asserta(Clause)
assertz(Clause)
Description
If the Clause has (:-)/2 as its top-level functor, then break it down into Head :- Body. If the Clause has (-->)/2 as its top-level functor, then expand the clause according to the Definite clause grammar rules and then break it down into Head :- Body. Otherwise, let Head be Clause and Body be true.
A freshly renamed version of the clause Head :- Body is added to the predicate database at the start (asserta/1) or end (assertz/1) of the predicate defined by Head.
Adding a clause to a predicate that is in the process of being executed leads to undefined behavior.
Errors
Examples
 asserta(Clause)              instantiation_error
 assertz((Head :- true))      instantiation_error
 asserta((1.5 :- true))       type_error(callable, 1.5)
 assertz((a :- true))         succeeds
 asserta((a(X) :- b(X,Y)))    succeeds
 assertz(a(X))                succeeds
 asserta((det --> "the"))     succeeds
 assertz((a :- X))            type_error(callable, X) when executed
 asserta(asserta(X))          permission_error(modify, static_procedure, asserta/1)
Compatibility
Standard Prolog, with the addition of the handling for (-->)/2.
See Also
abolish/1, asserta/2, retract/1, dynamic/1

asserta/2, assertz/2 - adds a clause to the start/end of a user-defined predicate in a local predicate database.

Usage
asserta(Clause, Database)
assertz(Clause, Database)
Description
If the Clause has (:-)/2 as its top-level functor, then break it down into Head :- Body. If the Clause has (-->)/2 as its top-level functor, then expand the clause according to the Definite clause grammar rules and then break it down into Head :- Body. Otherwise, let Head be Clause and Body be true.
A freshly renamed version of the clause Head :- Body is added to the specified local predicate Database at the start (asserta/2) or end (assertz/2) of the predicate defined by Head.
Adding a clause to a predicate that is in the process of being executed leads to undefined behavior.
Errors
Examples
 new_database(DB);
 assertz(userdef(a, b, c), DB);
See Also
abolish/2, asserta/1, new_database/1, retract/2

clause/2 - searches for clauses in the predicate database.

Usage
clause(Head, Body)
Description
Succeeds if Head :- Body unifies with a clause in the predicate database. If there are multiple clauses that unify, then backtrack through the alternatives. Fails immediately if no clauses unify.
Errors
Compatibility
Standard Prolog
See Also
asserta/1, clause/3

clause/3 - searches for clauses in a local predicate database.

Usage
clause(Head, Body, Database)
Description
Succeeds if Head :- Body unifies with a clause in the specified local predicate Database. If there are multiple clauses that unify, then backtrack through the alternatives. Fails immediately if no clauses unify.
Errors
See Also
asserta/2, new_database/1

new_database/1 - creates a new local predicate database.

Usage
new_database(Database)
Description
Creates a new local predicate database and unifies it with Database.
Errors
Examples
 new_database(DB);
See Also
abolish/2, asserta/2, clause/3, database/1, retract/2

retract/1 - removes a clause from a user-defined predicate in the predicate database.

Usage
retract(Clause)
Description
If the Clause has (:-)/2 as its top-level functor, then break it down into Head :- Body. If the Clause has (-->)/2 as its top-level functor, then expand the clause according to the Definite clause grammar rules and then break it down into Head :- Body. Otherwise, let Head be Clause and Body be true.
The retract/1 predicate finds the first clause in the predicate database that unifies with Head :- Body, removes it, and then succeeds. If Head :- Body does not unify with any clause in the database, then retract/1 fails.
Upon success, Clause is unified with the clause that was removed.
Removing a clause from a predicate that is in the process of being executed leads to undefined behavior.
Errors
Examples
 retract(Clause)              instantiation_error
 retract((Head :- true))      instantiation_error
 retract((1.5 :- true))       type_error(callable, 1.5)
 retract((a(X) :- b(X, Y))    fails
 assertz((a(X) :- b(X, Y))); retract((a(X) :- b(X, Y)))   succeeds
 retract(retract(X))          permission_error(modify, static_procedure, retract/1)
Compatibility
The retract/1 predicate in Standard Prolog removes multiple clauses that match Head :- Body upon back-tracking. In Plang, only the first clause is removed and back-tracking will cause a failure. It is possible to remove all clauses that match a specific Head :- Body as follows:
 while [X, Y] (retract((a(X) :- b(X, Y)))) {}
See Also
abolish/1, asserta/1

retract/2 - removes a clause from a user-defined predicate in a local predicate database.

Usage
retract(Clause, Database)
Description
If the Clause has (:-)/2 as its top-level functor, then break it down into Head :- Body. If the Clause has (-->)/2 as its top-level functor, then expand the clause according to the Definite clause grammar rules and then break it down into Head :- Body. Otherwise, let Head be Clause and Body be true.
The retract/2 predicate finds the first clause in the specified local predicate Database that unifies with Head :- Body, removes it, and then succeeds. If Head :- Body does not unify with any clause in Database, then retract/2 fails.
Upon success, Clause is unified with the clause that was removed.
Removing a clause from a predicate that is in the process of being executed leads to undefined behavior.
Errors
Examples
 new_database(DB);
 assertz(userdef(a, b, c), DB);
 retract(userdef(A, B, C), DB);
See Also
abolish/2, asserta/2, new_database/1, retract/1

Generated on 26 May 2011 for plang by  doxygen 1.6.1