This guide shows how to locate all usage sites of a Prolog predicate before refactoring using the find_predicate_references tool.

Find All References to a Predicate

Use find_predicate_references to locate every rule body, direct fact, assumption, and cross-memory reference involving a target predicate.

Basic Usage

bash
# Step 1: Populate the knowledge base
remember_fact fact='task_status(f024, in_progress)'
remember_fact fact='task_status(f025, done)'
define_rule head='active_work(X)' body='task_status(X, in_progress)'
define_rule head='completed(X)' body='task_status(X, done)'

# Step 2: Find all references to task_status
find_predicate_references functor='task_status'
# Returns references from both rules, the direct facts count, and any assumptions

The tool requires the functor argument. Optional arguments are arity, memory, and include_cross_memory_refs.

Search by Functor and Arity

When you specify both functor and arity, the tool only matches predicates with that exact arity.

Exact Arity Match

bash
# Find only task_status/2 references (not task_status/1 if it exists)
find_predicate_references functor='task_status' arity=2

# Find all arities of task_status
find_predicate_references functor='task_status'

Multiple Arities Example

bash
# Define predicates with the same functor but different arities
remember_fact fact='status(f024)'           # status/1
remember_fact fact='status(f024, done)'     # status/2

# Search for status/1 only
find_predicate_references functor='status' arity=1
# Returns: direct_facts_count: 1 (only the status/1 fact)

# Search for all status predicates
find_predicate_references functor='status'
# Returns: direct_facts_count: 2 (both status/1 and status/2 facts)

Understand the Response

The response includes multiple sections:

SectionContentUse Case
rulesAll rules whose body mentions the predicateIdentify rules that depend on the predicate
direct_facts_countCount of matching factsSee how many ground facts exist
facts_referenced_in_assumptionsTMS assumptions referencing the predicateKnow which hypotheses reference it
cross_memory_refsModule-qualified references from other memory segmentsDetect external dependencies

Example Response

bash
find_predicate_references functor='task_status' arity=2

# Returns (formatted):
# {
#   "target": "task_status/2",
#   "memory": "default",
#   "rules": [
#     {"head": "active_work(X)", "body": "task_status(X, in_progress)", "memory": "default"},
#     {"head": "completed(X)", "body": "task_status(X, done)", "memory": "default"}
#   ],
#   "direct_facts_count": 2,
#   "facts_referenced_in_assumptions": [],
#   "cross_memory_refs": []
# }

Workflow: Safe Refactoring

Before renaming a predicate or changing its arity, always consult find_predicate_references to identify all places that need updating:

bash
# 1. Discover all references
find_predicate_references functor='old_name' arity=2

# 2. Review the rules and facts returned
# (in the response: check all entries in "rules" and direct_facts_count)

# 3. Rename the predicate atomically with rename_predicate
#    rename_predicate old_functor='old_name' new_functor='new_name' arity=2
#    See: docs/user-guide/predicate-rename.md
# (or manually retract old facts/rules and assert new ones)

# 4. Verify the refactor is complete
find_predicate_references functor='old_name' arity=2
# Should now return: direct_facts_count: 0, empty rules, no assumptions

Search Assumptions

If the knowledge base uses TMS (Truth Maintenance System) assumptions, the response includes a facts_referenced_in_assumptions section that shows which assumptions justify facts mentioning the predicate.

Example with Assumptions

bash
# Assert a fact under an assumption
assume_fact assumption='sprint_planning' fact='task_status(f024, in_progress)'

# Find all references including assumptions
find_predicate_references functor='task_status'

# The response now includes:
# "facts_referenced_in_assumptions": [
#   {"assumption": "sprint_planning", "fact": "task_status(f024, in_progress)", "memory": "default"}
# ]

This is crucial for understanding which hypothetical beliefs would be invalidated if you change or remove the predicate.

Cross-Memory References

When using segmented memories (F021), the cross_memory_refs section surfaces module-qualified references like other_segment:predicate(...) from other mounted memory segments.

Example with Multiple Memories

bash
# Create two memory segments
memory create audit_log
memory mount audit_log

# In the default memory, define a rule
define_rule head='critical_tasks(X)' body='task_status(X, critical)'

# In the audit_log memory, define a rule that references the default memory
remember_fact fact='task_status(f024, critical)' memory=audit_log
define_rule head='verify_critical(X)' body='default:task_status(X, critical)' memory=audit_log

# Search all memories for references
find_predicate_references functor='task_status' memory='__all__'

# The response includes:
# "rules": [
#   {"head": "critical_tasks(X)", "body": "task_status(X, critical)", "memory": "default"}
# ],
# "cross_memory_refs": [
#   {"head": "verify_critical(X)", "body": "default:task_status(X, critical)", "memory": "audit_log", "qualifier": "default"}
# ]

Skip Cross-Memory References

By default, module-qualified references are included in the response. To search only for same-segment references:

bash
# Search without cross-memory references
find_predicate_references functor='task_status' memory='__all__' include_cross_memory_refs=false

# The response now omits the "cross_memory_refs" section

Search a Specific Memory Segment

If you only care about references within one memory segment, specify the memory parameter:

bash
# Search only the "audit" memory
find_predicate_references functor='task_status' memory='audit'

# Returns references only from the "audit" memory segment

Error Handling

Predicate Not Found

If the predicate does not exist in the knowledge base, the tool returns an empty result:

bash
find_predicate_references functor='nonexistent'

# Returns:
# {
#   "target": "nonexistent",
#   "memory": "default",
#   "rules": [],
#   "direct_facts_count": 0,
#   "facts_referenced_in_assumptions": [],
#   "cross_memory_refs": []
# }

This is not an error — it confirms the predicate has no references.

Memory Not Mounted

If you specify a memory segment that is not mounted:

json
{
  "is_error": true,
  "message": "Memory not mounted: unknown_segment"
}

Check available memories with memory list.

Invalid Functor

If the functor contains invalid characters or is not a valid Prolog atom:

json
{
  "is_error": true,
  "message": "InvalidArguments"
}

Ensure the functor is a valid Prolog identifier (letters, digits, and underscores; starts with a lowercase letter).

See Also