60 lines
1.8 KiB
Kotlin
60 lines
1.8 KiB
Kotlin
package prolog.components.expressions
|
|
|
|
import prolog.Substitution
|
|
import prolog.components.Resolvent
|
|
import prolog.components.terms.Functor
|
|
import prolog.components.terms.Goal
|
|
|
|
/**
|
|
* Collection of [Clause]s with the same [Functor].
|
|
*
|
|
* If a goal is proved, the system looks for a predicate with the same functor, then uses indexing
|
|
* to select candidate clauses and then tries these clauses one-by-one.
|
|
*/
|
|
class Predicate : Resolvent {
|
|
val functor: Functor
|
|
val clauses: MutableList<Clause>
|
|
|
|
/**
|
|
* Creates a predicate with the given functor and an empty list of clauses.
|
|
*/
|
|
constructor(functor: Functor) {
|
|
this.functor = functor
|
|
this.clauses = mutableListOf()
|
|
}
|
|
|
|
/**
|
|
* Creates a predicate with the given clauses.
|
|
*/
|
|
constructor(clauses: List<Clause>) {
|
|
this.functor = clauses.first().functor
|
|
|
|
require(clauses.all { it.functor == functor }) { "All clauses must have the same functor" }
|
|
this.clauses = clauses.toMutableList()
|
|
}
|
|
|
|
/**
|
|
* Adds a clause to the predicate.
|
|
*/
|
|
fun add(clause: Clause) {
|
|
require (clause.functor == functor) { "Clause functor does not match predicate functor" }
|
|
clauses.add(clause)
|
|
}
|
|
|
|
/**
|
|
* Adds a list of clauses to the predicate.
|
|
*/
|
|
fun addAll(clauses: List<Clause>) {
|
|
require(clauses.all { it.functor == functor }) { "All clauses must have the same functor" }
|
|
this.clauses.addAll(clauses)
|
|
}
|
|
|
|
override fun solve(goal: Goal): Sequence<Substitution> = sequence {
|
|
require(goal.functor == functor) { "Goal functor does not match predicate functor" }
|
|
for (clause in clauses) {
|
|
// Try to unify the goal with the clause
|
|
// If the unification is successful, yield the substitutions
|
|
yieldAll(clause.solve(goal))
|
|
}
|
|
}
|
|
}
|