diff --git a/src/prolog/builtins/io.kt b/src/prolog/builtins/io.kt new file mode 100644 index 0000000..aba1835 --- /dev/null +++ b/src/prolog/builtins/io.kt @@ -0,0 +1,19 @@ +package prolog.builtins + +import prolog.Answers +import prolog.Substitutions +import prolog.ast.logic.Satisfiable +import prolog.ast.terms.Atom +import prolog.ast.terms.Operator +import prolog.ast.terms.Term +import prolog.logic.applySubstitution + +class Write(private val term: Term) : Operator(Atom("write"), null, term), Satisfiable { + override fun satisfy(subs: Substitutions): Answers { + val t = applySubstitution(term, subs) + + println(t.toString()) + + return sequenceOf(Result.success(emptyMap())) + } +} \ No newline at end of file diff --git a/tests/prolog/builtins/IoOperatorsTests.kt b/tests/prolog/builtins/IoOperatorsTests.kt new file mode 100644 index 0000000..f51c313 --- /dev/null +++ b/tests/prolog/builtins/IoOperatorsTests.kt @@ -0,0 +1,85 @@ +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 org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource +import prolog.ast.arithmetic.Float +import prolog.ast.terms.Atom +import prolog.ast.terms.CompoundTerm +import java.io.ByteArrayOutputStream +import java.io.PrintStream +import prolog.ast.arithmetic.Integer +import prolog.ast.terms.Variable + +class IoOperatorsTests { + private var outStream = ByteArrayOutputStream() + + @BeforeEach + fun setup() { + outStream = ByteArrayOutputStream() + System.setOut(PrintStream(outStream)) + } + + @Test + fun dummyTest() { + val message = "Hello, World!" + print(message) + assertEquals(message, outStream.toString(), "Output should match the message") + } + + @ParameterizedTest + @ValueSource(strings = [ + "a", + "hello", + "a very special christmas", + "1 2 3 piano" + ]) + fun `write atoms`(name: String) { + val write = Write(Atom(name)) + + val result = write.satisfy(emptyMap()).toList() + + assertEquals(1, result.size, "Should return one result") + assertTrue(result[0].isSuccess, "Result should be successful") + assertEquals(name, outStream.toString().trim(), "Output should match the atom") + } + + @Test + fun `write structure`() { + val write = Write(CompoundTerm(Atom("person"), listOf(Atom("john"), Atom("doe")))) + + val result = write.satisfy(emptyMap()).toList() + + assertEquals(1, result.size, "Should return one result") + assertTrue(result[0].isSuccess, "Result should be successful") + assertEquals("person(john, doe)", outStream.toString().trim(), "Output should match the structure") + } + + @Test + fun `write arithmetic`() { + val a = Integer(1) + val b = Variable("B") + val c = Float(2.0f) + val d = Variable("D") + + val mul = Multiply(c, d) + val sub = Subtract(b, mul) + val expr = EvaluatesTo(a, sub) + + val expected1 = "1 =:= B - (2.0 * D)" + val expected2 = "=:=(1, -(B, *(2.0, D)))" + + val write = Write(expr) + + val result = write.satisfy(emptyMap()).toList() + + assertEquals(1, result.size, "Should return one result") + assertTrue(result[0].isSuccess, "Result should be successful") + + val output = outStream.toString().trim() + assertTrue(output == expected1 || output == expected2, "Output should match the arithmetic expression") + } +} \ No newline at end of file