Continuations

This commit is contained in:
Tibo De Peuter 2025-05-09 14:02:03 +02:00
parent 88c90220fe
commit 026218ddbd
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
13 changed files with 255 additions and 15 deletions

View file

@ -27,7 +27,7 @@ class Examples {
@Test
fun debugHelper() {
loader.load("examples/basics/arithmetics.pl")
loader.load("examples/meta/continuations.pl")
}
@ParameterizedTest
@ -65,6 +65,7 @@ class Examples {
)
fun meta() = listOf(
Arguments.of("continuations.pl", "Inside test\nEntering reset\nAfter reset\nCalling Cont(2)\nIn test X = 5; done\nCalling Cont(4)\nIn test X = 9; done\n"),
Arguments.of("mib_voorbeelden.pl", "b\nf(b)\nf(g(a,a),h(c,d),i(e,f))\nf(g(a,a),h(c,c),i(e,f))\nf(g(a,a),h(c,c),i(e,e))\n")
)

View file

@ -126,10 +126,11 @@ class LogicGrammarTests {
val rule = result[0] as Rule
assertEquals(Functor.of("guest/2"), rule.head.functor, "Expected functor 'guest/2'")
assertEquals(Functor.of(",/2"), (rule.body as CompoundTerm).functor, "Expected functor ',/2'")
val l1 = (rule.body as CompoundTerm).arguments[0] as CompoundTerm
assertEquals(Functor.of(",/2"), l1.functor, "Expected functor ',/2'")
val l2 = l1.arguments[0] as CompoundTerm
assertEquals(Functor.of("invited/2"), l2.functor, "Expected functor 'invited/2'")
val l0 = (rule.body as CompoundTerm)
val l1 = l0.arguments[0] as CompoundTerm
assertEquals(Functor.of("invited/2"), l1.functor, "Expected functor 'invited/2'")
val l2 = l0.arguments[1] as CompoundTerm
assertEquals(Functor.of(",/2"), l2.functor, "Expected functor ',/2'")
}
@Test

View file

@ -0,0 +1,75 @@
package prolog.builtins
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import prolog.ast.Database.Program
import prolog.ast.arithmetic.Integer
import prolog.ast.lists.List.Cons
import prolog.ast.lists.List.Empty
import prolog.ast.logic.Rule
import prolog.ast.terms.Atom
import prolog.ast.terms.Structure
import prolog.ast.terms.Variable
import java.io.ByteArrayOutputStream
import java.io.PrintStream
class DelimitedContinuationsOperatorsTests {
@BeforeEach
fun setup() {
Program.reset()
}
@Test
fun `example member`() {
val member = Member(Variable("X"), Cons(Integer(1), Cons(Integer(2), Cons(Integer(3), Empty))))
val reset = Reset(member, Variable("Ball"), Variable("Cont"))
val result = reset.satisfy(emptyMap()).toList()
assertEquals(3, result.size, "Expected 3 results")
assertTrue(result[0].isSuccess, "Expected success for first result")
val subs0 = result[0].getOrNull()!!
assertEquals(2, subs0.size, "Expected 2 substitutions for first result")
assertEquals(Integer(1), subs0[Variable("X")])
assertEquals(Integer(0), subs0[Variable("Cont")])
assertTrue(result[1].isSuccess, "Expected success for second result")
val subs1 = result[1].getOrNull()!!
assertEquals(2, subs1.size, "Expected 2 substitutions for second result")
assertEquals(Integer(2), subs1[Variable("X")])
assertEquals(Integer(0), subs1[Variable("Cont")])
assertTrue(result[2].isSuccess, "Expected success for third result")
val subs2 = result[2].getOrNull()!!
assertEquals(2, subs2.size, "Expected 2 substitutions for third result")
assertEquals(Integer(3), subs2[Variable("X")])
assertEquals(Integer(0), subs2[Variable("Cont")])
}
@Test
fun `example with output`() {
val reset = Reset(Atom("test_"), Variable("Term"), Variable("Cont"))
val isOp = Is(Variable("X"), Add(Integer(1), Multiply(Integer(2), Variable("Y"))))
Program.load(
listOf(
Rule(
Structure(Atom("test"), listOf(Variable("Cont"), Variable("Term"))),
Conjunction(WriteLn("Inside test"), Conjunction(reset, WriteLn("After reset")))
),
Rule(
Atom("test_"),
Conjunction(WriteLn("Entering reset"), Conjunction(Shift(Variable("Y")), Conjunction(isOp, Conjunction(Write("In test X = "), Conjunction(Write(Variable("X")), WriteLn("; done"))))))
)
)
)
val notNot2 = Not(Not(Conjunction(WriteLn("calling Cont(2)"), Conjunction(Unify(Variable("Term"), Integer(2)), Call(Variable("Cont"))))))
val notNot4 = Not(Not(Conjunction(WriteLn("calling Cont(4)"), Conjunction(Unify(Variable("Term"), Integer(4)), Call(Variable("Cont"))))))
val query = Conjunction(Structure(Atom("test"), listOf(Variable("Cont"), Variable("Term"))), Conjunction(notNot2, notNot4))
val result = query.satisfy(emptyMap()).toList()
}
}