package prolog import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import prolog.builtins.Conjunction import prolog.builtins.Disjunction import prolog.components.Program import prolog.components.expressions.Fact import prolog.components.expressions.Rule import prolog.components.terms.Atom import prolog.components.terms.Structure class EvaluationTest { @BeforeEach fun setUp() { Program.clear() } @Test fun successful_single_fact_query() { val fact = Fact(Atom("a")) Program.load(listOf(fact)) assertTrue(Program.query(Atom("a"))) } @Test fun failing_single_fact_query() { val fact = Fact(Atom("a")) Program.load(listOf(fact)) val result = Program.query(Atom("b")) assertFalse(result) } @Test fun multiple_fact_query() { val fact1 = Fact(Atom("a")) val fact2 = Fact(Atom("b")) Program.load(listOf(fact1, fact2)) assertTrue(Program.query(Atom("a"))) assertTrue(Program.query(Atom("b"))) assertFalse(Program.query(Atom("c"))) } @Test fun single_compound_query() { val structure = Structure(Atom("f"), listOf(Atom("a"), Atom("b"))) Program.load(listOf(Fact(structure))) assertTrue(Program.query(Structure(Atom("f"), listOf(Atom("a"), Atom("b"))))) } @Test fun multiple_compound_query() { val structure1 = Structure(Atom("f"), listOf(Atom("a"), Atom("b"))) val structure2 = Structure(Atom("g"), listOf(Atom("c"), Atom("d"))) Program.load(listOf(Fact(structure1), Fact(structure2))) assertTrue(Program.query(Structure(Atom("f"), listOf(Atom("a"), Atom("b"))))) assertTrue(Program.query(Structure(Atom("g"), listOf(Atom("c"), Atom("d"))))) assertFalse(Program.query(Structure(Atom("h"), listOf(Atom("e"))))) } /** * John and Jane are Jimmy's parents. */ @Test fun parents_prolog_way() { val father = Fact(Structure(Atom("father"), listOf(Atom("john"), Atom("jimmy")))) val mother = Fact(Structure(Atom("mother"), listOf(Atom("jane"), Atom("jimmy")))) val parent1 = Rule( Structure(Atom("parent"), listOf(Atom("X"), Atom("Y"))), /* :- */ Structure(Atom("father"), listOf(Atom("X"), Atom("Y"))) ) val parent2 = Rule( Structure(Atom("parent"), listOf(Atom("X"), Atom("Y"))), /* :- */ Structure(Atom("mother"), listOf(Atom("X"), Atom("Y"))) ) Program.load(listOf(father, mother, parent1, parent2)) assertTrue(Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jimmy"))))) assertTrue(Program.query(Structure(Atom("parent"), listOf(Atom("jane"), Atom("jimmy"))))) } /** * John and Jane are Jimmy's parents. */ @Test fun parents_disjunction_way() { val father = Fact(Structure(Atom("father"), listOf(Atom("john"), Atom("jimmy")))) val mother = Fact(Structure(Atom("mother"), listOf(Atom("jane"), Atom("jimmy")))) val parent = Rule( Structure(Atom("parent"), listOf(Atom("X"), Atom("Y"))), /* :- */ Disjunction( Structure(Atom("father"), listOf(Atom("X"), Atom("Y"))), /* ; */ Structure(Atom("mother"), listOf(Atom("X"), Atom("Y"))) )) Program.load(listOf(father, mother, parent)) assertTrue(Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jimmy"))))) assertTrue(Program.query(Structure(Atom("parent"), listOf(Atom("jane"), Atom("jimmy"))))) assertFalse(Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jane"))))) assertFalse(Program.query(Structure(Atom("father"), listOf(Atom("john"), Atom("jane"))))) } /** * John is Jimmy's father. * Jane is Jimmy's mother. */ @Test fun father_or_mother() { val male = Fact(Structure(Atom("male"), listOf(Atom("john")))) val female = Fact(Structure(Atom("female"), listOf(Atom("jane")))) val parent1 = Fact(Structure(Atom("parent"), listOf(Atom("john"), Atom("jimmy")))) val parent2 = Fact(Structure(Atom("parent"), listOf(Atom("jane"), Atom("jimmy")))) val isFather = Rule( Structure(Atom("isFather"), listOf(Atom("X"), Atom("Y"))), Conjunction( Structure(Atom("parent"), listOf(Atom("X"), Atom("Y"))), Structure(Atom("male"), listOf(Atom("X"))) ) ) val isMother = Rule( Structure(Atom("isMother"), listOf(Atom("X"), Atom("Y"))), Conjunction( Structure(Atom("parent"), listOf(Atom("X"), Atom("Y"))), Structure(Atom("female"), listOf(Atom("X"))) ) ) Program.load(listOf(male, female, parent1, parent2, isFather, isMother)) val result1 = Program.query(Structure(Atom("isFather"), listOf(Atom("john"), Atom("jimmy")))) assertTrue(result1) val result2 = Program.query(Structure(Atom("isMother"), listOf(Atom("jane"), Atom("jimmy")))) assertTrue(result2) val result3 = Program.query(Structure(Atom("isFather"), listOf(Atom("jane"), Atom("jimmy")))) assertFalse(result3) val result4 = Program.query(Structure(Atom("isMother"), listOf(Atom("john"), Atom("jimmy")))) assertFalse(result4) val result5 = Program.query(Structure(Atom("parent"), listOf(Atom("trudy"), Atom("jimmy")))) assertFalse(result5) } }