diff --git a/examples/basics/password.pl b/examples/basics/password.pl deleted file mode 100644 index 7322247..0000000 --- a/examples/basics/password.pl +++ /dev/null @@ -1,19 +0,0 @@ -login :- - getdata(_, _), - writeln('Welcome!'). -login :- - repeat, - writeln('Sorry, you are not permitted.'), - getdata(_, _), - writeln('Welcome'). - -getdata(Name, Password) :- - write('Username: '), - read(Name), - write('Password: '), - read(Password), - user(Name, Password). - -user(john, john1). -user(jimmy, jimmy1). -user(mary, mary1). diff --git a/examples/basics/repeat.pl b/examples/basics/repeat.pl deleted file mode 100644 index 35efa9b..0000000 --- a/examples/basics/repeat.pl +++ /dev/null @@ -1,2 +0,0 @@ -repeat. -repeat :- repeat. \ No newline at end of file diff --git a/examples/basics/summer.pl b/examples/basics/summer.pl index f0ad7a3..ba759d9 100644 --- a/examples/basics/summer.pl +++ b/examples/basics/summer.pl @@ -14,9 +14,9 @@ my_sum :- write('The sum is: '), write(Sum), nl. -summer_main :- +main :- Start = 1, End = 9, summer(Start, End, Sum), write('The sum of '), write(Start), write(' to '), write(End), write(' is: '), write(Sum), nl. -:- initialization(summer_main). +:- initialization(main). diff --git a/examples/demo.pl b/examples/demo.pl deleted file mode 100644 index ed94765..0000000 --- a/examples/demo.pl +++ /dev/null @@ -1,164 +0,0 @@ -:- initialization(demo). - -% % % % % % % % % % -% DEMO MENU LOGIC % -% % % % % % % % % % - -demo :- - clear, - header, - menu. - -menu :- - nl, - options, - write('DEMO: Enter your choice: '), - read(Choice), - choice(Choice). - -header :- - writeln('* * * * * * * * * * * * * * * * * * * * * * * * *'), - writeln('* GHENT PROLOG DEMO *'), - writeln('* * * * * * * * * * * * * * * * * * * * * * * * *'). - -options :- - writeln('-------------------------------------------------'), - writeln('INPUT DESCRIPTION CATEGORY SOURCE'), - writeln('-------------------------------------------------'), - writeln('(1) A password prompt basics password.pl'), - writeln('(2) Add i in [a..b] maths summer.pl'), - writeln('(3) A translator meta mib_voorbeelden.pl'), - writeln('(4) A tale of a ceremony cont. ceremony.pl'), - writeln('(5) Maths with Shift/Reset cont. continuations.pl'), -% writeln('(6) Alternative lists meta my_list.pl'), - nl, - writeln('(interpreter) to enter the interpreter'), - writeln('(exit) to exit the demo'), - nl. - -choice(1) :- !, run_login_example, menu. -choice(2) :- !, run_summer_example, menu. -choice(3) :- !, run_mib_voorbeelden_example, continue, menu. -choice(4) :- !, run_ceremony_example, continue, menu. -choice(5) :- !, run_continuations_example, continue, menu. -%choice(6) :- !, run_my_list_example, continue, menu. -choice(interpreter) :- !, run_interpreter, continue, menu. -choice(exit) :- !, writeln('Exiting...'). -choice(_) :- write('DEMO: Invalid choice, please try again: '), read(Choice), choice(Choice). - -% % % % % % % % % % -% DEMO REPOSITORY % -% % % % % % % % % % - -run_login_example :- - say('Loading login example...'), - consult('examples/basics/repeat.pl'), - consult('examples/basics/password.pl'), - say('Showing login/0'), - say('You might try logging in with tibo/noaccess and john/john1.'), - login, login_example_loop, !, - say('Login example finished.'). - -login_example_loop :- - yes_or_no('Do you want to try again?', (login, login_example_loop), true). - -run_summer_example :- - say('Loading summer example...'), - consult('examples/basics/summer.pl'), - say('Showing my_sum/1'), - say('You might try summing 1 to 9.'), - my_sum, summer_example_loop, !, - say('Summer example finished.'). - -summer_example_loop :- - yes_or_no('Do you want to try again?', (my_sum, summer_example_loop), true). - -run_mib_voorbeelden_example :- - say('Loading mib_voorbeelden example...'), - consult('examples/meta/mib_voorbeelden.pl'), clear, - say('Showing example1/0'), example1, next(( - say('Showing example2/0'), example2, next(( - say('Showing example3/0'), example3)))), - say('mib_voorbeelden example finished.'). - -run_ceremony_example :- - say('Loading ceremony example...'), - consult('examples/meta/ceremony.pl'), clear, - say('Showing ceremony_main/0'), - ceremony_main, - say('Ceremony example finished.'). - -run_continuations_example :- - say('Loading continuations example...'), - consult('examples/meta/continuations.pl'), clear, - say('Showing continuations_main/0'), - continuations_main, - say('Continuations example finished.'). - -run_my_list_example :- - say('Loading my_list example...'), - consult('examples/meta/my_list.pl'), - say('Showing my_member/2'), - showcase(my_member(X, a(b(c))), 'X', X), - continue, - say('Showing my_length/2'), - showcase(my_length(a(b(c)), Length), 'Length', Length), - say('my_list example finished.'). - -run_interpreter :- - say('Loading interpreter...'), - consult('examples/meta/ground.pl'), - consult('examples/meta/interpreter.pl'), - say('Showing interpreter/0'), - say('Have fun!'), - interpreter, - say('Interpreter finished.'). - -% % % % % % % % % % % -% HELPER PREDICATES % -% % % % % % % % % % % - -yes_or_no(Question, IfYes, IfNo) :- - write(Question), write(' (y/n): '), - read(Answer), - ( ( was_yes(Answer), !, call(IfYes)) ; ( was_no(Answer), !, call(IfNo))). - -was_yes(y). -was_yes('Y'). -was_yes(yes). -was_yes('Yes'). -was_yes('YES'). - -was_no(n). -was_no('N'). -was_no(no). -was_no('No'). -was_no('NO'). - -say(Message) :- - write('DEMO: '), - writeln(Message). - -showcase(Goal, VarName, Var) :- - say(Goal), - call(Goal), - say(solution(VarName, Var)). - -showcase(Goal) :- - Goal =.. List, - say(List), - call(Goal). - -next(Next) :- yes_or_no('See next?', call(Next), true). - -continue :- - write('Write anything to continue... '), - read(_). - -clear :- clear(30). - -clear(0) :- !. -clear(N) :- - nl, - M is N - 1, - clear(M). diff --git a/examples/meta/calculator.pl b/examples/meta/calculator.pl new file mode 100644 index 0000000..3ac4216 --- /dev/null +++ b/examples/meta/calculator.pl @@ -0,0 +1,15 @@ +accumulator :- + Sum = 0, + shift(Number), + NewSum is Sum + Number, + write("Result is: "), writeln(NewSum). + +main :- + reset(accumulator, Number, Cont), + between(1, 5, Number), + forall() + call(Cont), + writeln("End of calculation"). + +:- initialization(main). + diff --git a/examples/meta/ceremony.pl b/examples/meta/ceremony.pl index 2e5138d..e378367 100644 --- a/examples/meta/ceremony.pl +++ b/examples/meta/ceremony.pl @@ -4,7 +4,7 @@ printer :- shift(Name), write(Name), write(", "). -ceremony_main :- +main :- writeln("/Ceremony starts/"), reset(printer, Name, Cont), \+ \+ ( Name = "John", call(Cont) ), @@ -12,4 +12,4 @@ ceremony_main :- writeln("and my parents!"), writeln("/Ceremony ends/"). -:- initialization(ceremony_main). +:- initialization(main). diff --git a/examples/meta/continuations.pl b/examples/meta/continuations.pl index 8742fb5..8661361 100644 --- a/examples/meta/continuations.pl +++ b/examples/meta/continuations.pl @@ -12,11 +12,11 @@ test_ :- X is 1 + (2 * Y), write("In test X = "), write(X), writeln("; done"). -continuations_main :- +main :- test(Cont, Term), \+ \+ ( writeln("Calling Cont(2)"), Term = 2, call(Cont)), \+ \+ ( writeln("Calling Cont(4)"), Term = 4, call(Cont)). -:- initialization(continuations_main). +:- initialization(main). diff --git a/examples/meta/ground.pl b/examples/meta/ground.pl deleted file mode 100644 index d7af4d7..0000000 --- a/examples/meta/ground.pl +++ /dev/null @@ -1,15 +0,0 @@ -ground(T) :- - nonvar(T), atomic(T), - !. -ground(T) :- - nonvar(T), compound(T), - functor(T, _, N), - ground(T, N). - -ground(T, N) :- - N \== 0, - arg(N, T, A), - ground(A), - M is N - 1, - ground(T, M). -ground(T, 0). diff --git a/examples/meta/interpreter.pl b/examples/meta/interpreter.pl deleted file mode 100644 index 30f74d3..0000000 --- a/examples/meta/interpreter.pl +++ /dev/null @@ -1,27 +0,0 @@ -interpreter :- - interpreter_prompt, - read(Goal), - interpreter(Goal). - -interpreter_prompt :- write('Next Command ?-- '). - -interpreter(exit) :- !. -interpreter(Goal) :- - ground(Goal), !, - solve_ground(Goal), - interpreter. -interpreter(Goal) :- - solve(Goal), - interpreter. - -solve_ground(Goal) :- - call(Goal), - !, - writeln('True :)'). -solve_ground(_) :- writeln('False :('). - -solve(Goal) :- - call(Goal), - writeln(Goal), - fail. -solve(_) :- writeln('No more solutions :/'). diff --git a/examples/meta/mib_voorbeelden.pl b/examples/meta/mib_voorbeelden.pl index e3cd52b..47003d5 100644 --- a/examples/meta/mib_voorbeelden.pl +++ b/examples/meta/mib_voorbeelden.pl @@ -40,9 +40,9 @@ example3 :- mib(f, e, Result2, Result3), write(Result3), nl. -mib_main :- +main :- example1, example2, example3. -:- initialization(mib_main). +:- initialization(main). diff --git a/examples/meta/my_list.pl b/examples/meta/my_list.pl deleted file mode 100644 index 0f6b1de..0000000 --- a/examples/meta/my_list.pl +++ /dev/null @@ -1,14 +0,0 @@ -% my_member(Element, List) - checks if Element is in List -my_member(Element, Element) :- atomic(Element). -my_member(Element, Compound) :- - compound(Compound), - Compound =.. [Head, Tail], - (Element = Head ; my_member(Element, Tail)). - -% my_length(List, Length) - finds the my_length of a list -my_length(Atom, 1) :- atomic(Atom). -my_length(Compound, N) :- - compound(Compound), - Compound =.. [_, Tail], - my_length(Tail, M), - N is M + 1. diff --git a/src/prolog/builtins/analysisOperators.kt b/src/prolog/builtins/analysisOperators.kt index 75b7711..7f83ab0 100644 --- a/src/prolog/builtins/analysisOperators.kt +++ b/src/prolog/builtins/analysisOperators.kt @@ -159,31 +159,27 @@ class ClauseOp(private val head: Head, private val body: Body) : open class Univ(private val term: Term, private val list: Term) : Operator("=..", term, list) { override fun satisfy(subs: Substitutions): Answers { - if (variable(term, subs)) { - require(nonvariable(list, subs)) { "Arguments are not sufficiently instantiated" } - val l = applySubstitution(list, subs) as List - require(nonvariable(l.head, subs)) { "Arguments are not sufficiently instantiated" } - - val t = listToTerm(l) - return unifyLazy(term, t, subs) - } - - if (nonvariable(list, subs)) { - val l = applySubstitution(list, subs) as List - - if (nonvariable(l.head, subs)) { + return when { + nonvariable(term, subs) && nonvariable(list, subs) -> { val t = applySubstitution(term, subs) - return unifyLazy(t, listToTerm(l), subs) + val l = applySubstitution(list, subs) as List + unifyLazy(t, listToTerm(l), subs) } - val t = applySubstitution(term, subs) - val expectedL = termToList(t) - return unifyLazy(expectedL, l, subs) - } + variable(term, subs) && nonvariable(list, subs) -> { + val l = applySubstitution(list, subs) as List + val t = listToTerm(l) + unifyLazy(term, t, subs) + } - val t = applySubstitution(term, subs) - val l = termToList(t) - return unifyLazy(l, list, subs) + nonvariable(term, subs) && variable(list, subs) -> { + val t = applySubstitution(term, subs) + val l = termToList(t) + unifyLazy(l, list, subs) + } + + else -> throw Exception("Arguments are not sufficiently instantiated") + } } protected open fun listToTerm(list: List): Term { diff --git a/src/repl/Repl.kt b/src/repl/Repl.kt index 70b95db..688cea4 100644 --- a/src/repl/Repl.kt +++ b/src/repl/Repl.kt @@ -20,7 +20,6 @@ class Repl { printAnswers(query()) } catch (e: Exception) { Logger.error("Error parsing REPL: ${e.message}") - Logger.debug(e.stackTraceToString()) } } } diff --git a/tests/prolog/builtins/AnalysisOperatorsTests.kt b/tests/prolog/builtins/AnalysisOperatorsTests.kt index 1f4981a..a6866c3 100644 --- a/tests/prolog/builtins/AnalysisOperatorsTests.kt +++ b/tests/prolog/builtins/AnalysisOperatorsTests.kt @@ -568,23 +568,6 @@ class AnalysisOperatorsTests { assertEquals(0, result.size, "Expected 0 results") } - @Test - fun `univ extra debugging`() { - val univ = Univ( - Structure("baz", Variable("Foo")), - Cons(Variable("Baz"), Cons(Structure("foo", Integer(1)), Empty)) - ) - - val result = univ.satisfy(emptyMap()).toList() - - assertEquals(1, result.size, "Expected 1 result") - assertTrue(result[0].isSuccess, "Expected success") - val subs = result[0].getOrNull()!! - assertEquals(2, subs.size, "Expected 2 substitutions") - assertEquals(Atom("baz"), subs[Variable("Baz")], "Expected Baz to be baz") - assertEquals(Structure("foo", Integer(1)), subs[Variable("Foo")], "Expected Foo to be foo(1)") - } - @Test fun `univ with two vars should throw`() { val univ = Univ(Variable("X"), Variable("Y"))