This commit is contained in:
Tibo De Peuter 2025-05-07 22:26:02 +02:00
parent 752c278cb0
commit 8bda3c5af4
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
15 changed files with 361 additions and 114 deletions

View file

@ -48,70 +48,93 @@ open class Preprocessor {
}
protected open fun preprocess(term: Term, nested: Boolean = false): Term {
val prepped = when (term) {
Atom("true") -> True
Structure(Atom("true"), emptyList()) -> True
Atom("false") -> False
Structure(Atom("false"), emptyList()) -> False
Atom("fail") -> Fail
Structure(Atom("fail"), emptyList()) -> Fail
Atom("!") -> Cut()
Structure(Atom("!"), emptyList()) -> Cut()
Atom("inf") -> Integer(Int.MAX_VALUE)
Atom("nl") -> Nl
Variable("_") -> AnonymousVariable.create()
is Structure -> {
// TODO Remove hardcoding by storing the functors as constants in operators?
val prepped = when {
term == Variable("_") -> AnonymousVariable.create()
term is Atom || term is Structure -> {
// Preprocess the arguments first to recognize builtins
val args = term.arguments.map { preprocess(it, nested = true) }
val args = if (term is Structure) {
term.arguments.map { preprocess(it, nested = true) }
} else emptyList()
when {
// TODO Remove hardcoding by storing the functors as constants in operators?
term.functor == FunctorInfo.of(":-/2") -> Rule( args[0] as Head, args[1] as Body )
// Logic
term.functor == FunctorInfo.of("=/2") -> Unify(args[0], args[1])
term.functor == FunctorInfo.of("\\=/2") -> NotUnify(args[0], args[1])
term.functor == FunctorInfo.of(",/2") -> Conjunction(args[0] as LogicOperand, args[1] as LogicOperand)
term.functor == FunctorInfo.of(";/2") -> Disjunction(args[0] as LogicOperand, args[1] as LogicOperand)
term.functor == FunctorInfo.of("\\+/1") -> Not(args[0] as Goal)
term.functor == FunctorInfo.of("\\==/2") -> NotEquivalent(args[0], args[1])
term.functor == FunctorInfo.of("==/2") -> Equivalent(args[0], args[1])
term.functor == FunctorInfo.of("=\\=/2") && args.all { it is Expression } -> EvaluatesToDifferent(args[0] as Expression, args[1] as Expression)
term.functor == FunctorInfo.of("=:=/2") && args.all { it is Expression } -> EvaluatesTo(args[0] as Expression, args[1] as Expression)
term.functor == FunctorInfo.of("is/2") && args.all { it is Expression } -> Is(args[0] as Expression, args[1] as Expression)
when (term.functor) {
// Analysis
Functor.of("functor/3") -> FunctorOp(args[0], args[1], args[2])
Functor.of("arg/3") -> Arg(args[0], args[1], args[2])
Functor.of("clause/2") -> ClauseOp(args[0] as Head, args[1] as Body)
// Arithmetic
Functor.of("inf/0") -> Integer(Int.MAX_VALUE)
Functor.of("=\\=/2") -> if (args.all { it is Expression }) {
EvaluatesToDifferent(args[0] as Expression, args[1] as Expression)
} else term
term.functor == FunctorInfo.of("-/1") && args.all { it is Expression } -> Negate(args[0] as Expression)
term.functor == FunctorInfo.of("-/2") && args.all { it is Expression } -> Subtract(args[0] as Expression, args[1] as Expression)
term.functor == FunctorInfo.of("+/1") && args.all { it is Expression } -> Positive(args[0] as Expression)
term.functor == FunctorInfo.of("+/2") && args.all { it is Expression } -> Add(args[0] as Expression, args[1] as Expression)
term.functor == FunctorInfo.of("*/2") && args.all { it is Expression } -> Multiply(args[0] as Expression, args[1] as Expression)
term.functor == FunctorInfo.of("//2") && args.all { it is Expression } -> Divide(args[0] as Expression, args[1] as Expression)
term.functor == FunctorInfo.of("between/3") && args.all { it is Expression } -> Between(args[0] as Expression, args[1] as Expression, args[2] as Expression)
term.functor == FunctorInfo.of("succ/2") && args.all { it is Expression } -> Successor(args[0] as Expression, args[1] as Expression)
Functor.of("=:=/2") -> if (args.all { it is Expression }) {
EvaluatesTo(args[0] as Expression, args[1] as Expression)
} else term
Functor.of("is/2") -> if (args.all { it is Expression }) {
Is(args[0] as Expression, args[1] as Expression)
} else term
Functor.of("-/1") -> if (args.all { it is Expression }) Negate(args[0] as Expression) else term
Functor.of("+/1") -> if (args.all { it is Expression }) Positive(args[0] as Expression) else term
Functor.of("+/2") -> if (args.all { it is Expression }) {
Add(args[0] as Expression, args[1] as Expression)
} else term
Functor.of("-/2") -> if (args.all { it is Expression }) {
Subtract(args[0] as Expression, args[1] as Expression)
} else term
Functor.of("*/2") -> if (args.all { it is Expression }) {
Multiply(args[0] as Expression, args[1] as Expression)
} else term
Functor.of("//2") -> if (args.all { it is Expression }) {
Divide(args[0] as Expression, args[1] as Expression)
} else term
Functor.of("between/3") -> if (args.all { it is Expression }) {
Between(args[0] as Expression, args[1] as Expression, args[2] as Expression)
} else term
Functor.of("succ/2") -> if (args.all { it is Expression }) {
Successor(args[0] as Expression, args[1] as Expression)
} else term
// Control
Functor.of("fail/0") -> Fail
Functor.of("false/0") -> False
Functor.of("true/0") -> True
Functor.of("!/0") -> Cut()
Functor.of(",/2") -> Conjunction(args[0] as LogicOperand, args[1] as LogicOperand)
Functor.of(";/2") -> Disjunction(args[0] as LogicOperand, args[1] as LogicOperand)
Functor.of("|/2") -> Bar(args[0] as LogicOperand, args[1] as LogicOperand)
Functor.of("\\+/1") -> Not(args[0] as Goal)
// Database
term.functor == FunctorInfo.of("dynamic/1") -> Dynamic(FunctorInfo.of((args[0] as Atom).name))
term.functor == FunctorInfo.of("retract/1") -> Retract(args[0])
term.functor == FunctorInfo.of("retractall/1") -> RetractAll(args[0])
term.functor == FunctorInfo.of("assert/1") -> {
Functor.of("dynamic/1") -> Dynamic(Functor.of((args[0] as Atom).name))
Functor.of("retract/1") -> Retract(args[0])
Functor.of("retractall/1") -> RetractAll(args[0])
Functor.of("assert/1") -> {
if (args[0] is Rule) {
Assert(args[0] as Rule)
} else {
Assert(Fact(args[0] as Head))
}
}
term.functor == FunctorInfo.of("asserta/1") -> {
Functor.of("asserta/1") -> {
if (args[0] is Rule) {
AssertA(args[0] as Rule)
} else {
AssertA(Fact(args[0] as Head))
}
}
term.functor == FunctorInfo.of("assertz/1") -> {
Functor.of("assertz/1") -> {
if (args[0] is Rule) {
AssertZ(args[0] as Rule)
} else {
@ -119,14 +142,25 @@ open class Preprocessor {
}
}
// IO
Functor.of("write/1") -> Write(args[0])
Functor.of("nl/0") -> Nl
Functor.of("read/1") -> Read(args[0])
// Other
term.functor == FunctorInfo.of("write/1") -> Write(args[0])
term.functor == FunctorInfo.of("read/1") -> Read(args[0])
term.functor == FunctorInfo.of("initialization/1") -> Initialization(args[0] as Goal)
term.functor == FunctorInfo.of("forall/2") -> ForAll(args[0] as LogicOperand, args[1] as Goal)
Functor.of("initialization/1") -> Initialization(args[0] as Goal)
Functor.of("forall/2") -> ForAll(args[0] as LogicOperand, args[1] as Goal)
// Unification
Functor.of("=/2") -> Unify(args[0], args[1])
Functor.of("\\=/2") -> NotUnify(args[0], args[1])
Functor.of("==/2") -> Equivalent(args[0], args[1])
Functor.of("\\==/2") -> NotEquivalent(args[0], args[1])
Functor.of(":-/2") -> Rule(args[0] as Head, args[1] as Body)
else -> {
term.arguments = args
if (term is Structure) term.arguments = args
term
}
}