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 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() } }