Checkpoint
This commit is contained in:
parent
43b364044e
commit
9db1c66781
34 changed files with 746 additions and 194 deletions
|
@ -1,7 +1,10 @@
|
|||
package prolog.logic
|
||||
|
||||
import prolog.Substitutions
|
||||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.terms.Term
|
||||
import prolog.ast.terms.Variable
|
||||
|
||||
/**
|
||||
* True when Term is a term with functor Name/Arity. If Term is a variable it is unified with a new term whose
|
||||
|
@ -20,3 +23,53 @@ fun functor(term: Term, name: Atom, arity: Int): Boolean {
|
|||
// TODO Implement
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Unify the free variables in Term with a term $VAR(N), where N is the number of the variable.
|
||||
* Counting starts at Start.
|
||||
* End is unified with the number that should be given to the next variable.
|
||||
*
|
||||
* Source: [SWI-Prolog Predicate numbervars/3](https://www.swi-prolog.org/pldoc/man?predicate=numbervars/3)
|
||||
*
|
||||
* @return Pair of the next number and only the new substitutions of variables to $VAR(N)
|
||||
*/
|
||||
fun numbervars(
|
||||
term: Term,
|
||||
start: Int = 0,
|
||||
subs: Substitutions = emptyMap(),
|
||||
sessionSubs: Substitutions = emptyMap()
|
||||
): Pair<Int, Substitutions> {
|
||||
when {
|
||||
variable(term, subs) -> {
|
||||
// All instances of the same variable are unified with the same term
|
||||
if (term in sessionSubs) {
|
||||
return Pair(start, emptyMap())
|
||||
}
|
||||
|
||||
val from = term as Variable
|
||||
var suggestedName = "${from.name}($start)"
|
||||
// If the suggested name is already in use, find a new one
|
||||
while ((subs + sessionSubs).filter { (it.key as Variable).name == suggestedName }.isNotEmpty()) {
|
||||
val randomInfix = ((0..9) + ('a'..'z') + ('A'..'Z')).random()
|
||||
suggestedName = "${from.name}_${randomInfix}_($start)"
|
||||
}
|
||||
return Pair(start + 1, mapOf(from to Variable(suggestedName)))
|
||||
}
|
||||
|
||||
compound(term, subs) -> {
|
||||
val from = term as Structure
|
||||
var n = start
|
||||
val s: MutableMap<Term, Term> = sessionSubs.toMutableMap()
|
||||
from.arguments.forEach { arg ->
|
||||
val (newN, newSubs) = numbervars(arg, n, subs, s)
|
||||
n = newN
|
||||
s += newSubs
|
||||
}
|
||||
return Pair(n, s)
|
||||
}
|
||||
|
||||
else -> {
|
||||
return Pair(start, emptyMap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ fun applySubstitution(expr: Expression, subs: Substitutions): Expression = when
|
|||
}
|
||||
|
||||
// Check if a variable occurs in a term
|
||||
private fun occurs(variable: Variable, term: Term, subs: Substitutions): Boolean = when {
|
||||
fun occurs(variable: Variable, term: Term, subs: Substitutions): Boolean = when {
|
||||
variable(term, subs) -> term == variable
|
||||
atomic(term, subs) -> false
|
||||
compound(term, subs) -> {
|
||||
|
@ -53,18 +53,18 @@ fun unifyLazy(term1: Term, term2: Term, subs: Substitutions): Answers = sequence
|
|||
val t2 = applySubstitution(term2, subs)
|
||||
|
||||
when {
|
||||
equivalent(t1, t2, subs) -> yield(Result.success(subs))
|
||||
equivalent(t1, t2, subs) -> yield(Result.success(emptyMap()))
|
||||
variable(t1, subs) -> {
|
||||
val variable = t1 as Variable
|
||||
if (!occurs(variable, t2, subs)) {
|
||||
yield(Result.success(subs + (variable to t2)))
|
||||
yield(Result.success(mapOf(term1 to t2)))
|
||||
}
|
||||
}
|
||||
|
||||
variable(t2, subs) -> {
|
||||
val variable = t2 as Variable
|
||||
if (!occurs(variable, t1, subs)) {
|
||||
yield(Result.success(subs + (variable to t1)))
|
||||
yield(Result.success(mapOf(term2 to t1)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue