This commit is contained in:
Tibo De Peuter 2025-05-07 20:22:14 +02:00
parent dff53b4e68
commit 65c4d925d3
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
15 changed files with 270 additions and 83 deletions

View file

@ -0,0 +1,65 @@
package prolog.builtins
import prolog.Answers
import prolog.Substitutions
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.AnonymousVariable
import prolog.ast.terms.Atom
import prolog.ast.terms.Head
import prolog.ast.terms.Structure
import prolog.ast.terms.Term
import prolog.ast.terms.Variable
import prolog.logic.applySubstitution
import prolog.logic.atomic
import prolog.logic.nonvariable
import prolog.logic.unifyLazy
import prolog.logic.variable
class Functor(private val term: Term, private val functorName: Term, private val functorArity: Term) :
Structure(Atom("functor"), listOf(term, functorName, functorArity)) {
override fun satisfy(subs: Substitutions): Answers {
if (nonvariable(term, subs)) {
val t = applySubstitution(term, subs) as Head
return Conjunction(
Unify(t.functor.arity, functorArity),
Unify(t.functor.name, functorName)
).satisfy(subs)
}
if (variable(term, subs)) {
require(atomic(functorName, subs) && atomic(functorArity, subs)) {
"Arguments are not sufficiently instantiated"
}
val name = applySubstitution(functorName, subs) as Atom
val arity = applySubstitution(functorArity, subs) as Integer
val result = if (arity.value == 0) {
functorName
} else {
val argList = mutableListOf<Term>()
for (i in 1..arity.value) {
argList.add(AnonymousVariable.create())
}
Structure(name, argList)
}
if (nonvariable(term, subs)) {
return unifyLazy(term, result, subs)
}
return sequenceOf(Result.success(mapOf(term to result)))
}
throw IllegalStateException()
}
override fun applySubstitution(subs: Substitutions): Functor = Functor(
term.applySubstitution(subs),
functorName.applySubstitution(subs),
functorArity.applySubstitution(subs)
)
override fun toString(): String = "functor($term, $functorName, $functorArity)"
}