Compare commits
4 commits
83f65bd683
...
b294467587
Author | SHA1 | Date | |
---|---|---|---|
b294467587 | |||
61178cbeac | |||
d50ec0f715 | |||
50b4d192f3 |
14 changed files with 290 additions and 42 deletions
19
examples/basics/password.pl
Normal file
19
examples/basics/password.pl
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
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).
|
2
examples/basics/repeat.pl
Normal file
2
examples/basics/repeat.pl
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
repeat.
|
||||||
|
repeat :- repeat.
|
|
@ -14,9 +14,9 @@ my_sum :-
|
||||||
write('The sum is: '),
|
write('The sum is: '),
|
||||||
write(Sum), nl.
|
write(Sum), nl.
|
||||||
|
|
||||||
main :-
|
summer_main :-
|
||||||
Start = 1, End = 9,
|
Start = 1, End = 9,
|
||||||
summer(Start, End, Sum),
|
summer(Start, End, Sum),
|
||||||
write('The sum of '), write(Start), write(' to '), write(End), write(' is: '), write(Sum), nl.
|
write('The sum of '), write(Start), write(' to '), write(End), write(' is: '), write(Sum), nl.
|
||||||
|
|
||||||
:- initialization(main).
|
:- initialization(summer_main).
|
||||||
|
|
164
examples/demo.pl
Normal file
164
examples/demo.pl
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
:- 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).
|
|
@ -1,15 +0,0 @@
|
||||||
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).
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ printer :-
|
||||||
shift(Name),
|
shift(Name),
|
||||||
write(Name), write(", ").
|
write(Name), write(", ").
|
||||||
|
|
||||||
main :-
|
ceremony_main :-
|
||||||
writeln("/Ceremony starts/"),
|
writeln("/Ceremony starts/"),
|
||||||
reset(printer, Name, Cont),
|
reset(printer, Name, Cont),
|
||||||
\+ \+ ( Name = "John", call(Cont) ),
|
\+ \+ ( Name = "John", call(Cont) ),
|
||||||
|
@ -12,4 +12,4 @@ main :-
|
||||||
writeln("and my parents!"),
|
writeln("and my parents!"),
|
||||||
writeln("/Ceremony ends/").
|
writeln("/Ceremony ends/").
|
||||||
|
|
||||||
:- initialization(main).
|
:- initialization(ceremony_main).
|
||||||
|
|
|
@ -12,11 +12,11 @@ test_ :-
|
||||||
X is 1 + (2 * Y),
|
X is 1 + (2 * Y),
|
||||||
write("In test X = "), write(X), writeln("; done").
|
write("In test X = "), write(X), writeln("; done").
|
||||||
|
|
||||||
main :-
|
continuations_main :-
|
||||||
test(Cont, Term),
|
test(Cont, Term),
|
||||||
\+ \+ ( writeln("Calling Cont(2)"),
|
\+ \+ ( writeln("Calling Cont(2)"),
|
||||||
Term = 2, call(Cont)),
|
Term = 2, call(Cont)),
|
||||||
\+ \+ ( writeln("Calling Cont(4)"),
|
\+ \+ ( writeln("Calling Cont(4)"),
|
||||||
Term = 4, call(Cont)).
|
Term = 4, call(Cont)).
|
||||||
|
|
||||||
:- initialization(main).
|
:- initialization(continuations_main).
|
||||||
|
|
15
examples/meta/ground.pl
Normal file
15
examples/meta/ground.pl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
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).
|
27
examples/meta/interpreter.pl
Normal file
27
examples/meta/interpreter.pl
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
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 :/').
|
|
@ -40,9 +40,9 @@ example3 :-
|
||||||
mib(f, e, Result2, Result3),
|
mib(f, e, Result2, Result3),
|
||||||
write(Result3), nl.
|
write(Result3), nl.
|
||||||
|
|
||||||
main :-
|
mib_main :-
|
||||||
example1,
|
example1,
|
||||||
example2,
|
example2,
|
||||||
example3.
|
example3.
|
||||||
|
|
||||||
:- initialization(main).
|
:- initialization(mib_main).
|
||||||
|
|
14
examples/meta/my_list.pl
Normal file
14
examples/meta/my_list.pl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
% 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.
|
|
@ -159,27 +159,31 @@ class ClauseOp(private val head: Head, private val body: Body) :
|
||||||
|
|
||||||
open class Univ(private val term: Term, private val list: Term) : Operator("=..", term, list) {
|
open class Univ(private val term: Term, private val list: Term) : Operator("=..", term, list) {
|
||||||
override fun satisfy(subs: Substitutions): Answers {
|
override fun satisfy(subs: Substitutions): Answers {
|
||||||
return when {
|
if (variable(term, subs)) {
|
||||||
nonvariable(term, subs) && nonvariable(list, subs) -> {
|
require(nonvariable(list, subs)) { "Arguments are not sufficiently instantiated" }
|
||||||
val t = applySubstitution(term, subs)
|
val l = applySubstitution(list, subs) as List
|
||||||
val l = applySubstitution(list, subs) as List
|
require(nonvariable(l.head, subs)) { "Arguments are not sufficiently instantiated" }
|
||||||
unifyLazy(t, listToTerm(l), subs)
|
|
||||||
}
|
|
||||||
|
|
||||||
variable(term, subs) && nonvariable(list, subs) -> {
|
val t = listToTerm(l)
|
||||||
val l = applySubstitution(list, subs) as List
|
return unifyLazy(term, t, subs)
|
||||||
val t = listToTerm(l)
|
|
||||||
unifyLazy(term, t, 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")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nonvariable(list, subs)) {
|
||||||
|
val l = applySubstitution(list, subs) as List
|
||||||
|
|
||||||
|
if (nonvariable(l.head, subs)) {
|
||||||
|
val t = applySubstitution(term, subs)
|
||||||
|
return unifyLazy(t, listToTerm(l), subs)
|
||||||
|
}
|
||||||
|
|
||||||
|
val t = applySubstitution(term, subs)
|
||||||
|
val expectedL = termToList(t)
|
||||||
|
return unifyLazy(expectedL, l, subs)
|
||||||
|
}
|
||||||
|
|
||||||
|
val t = applySubstitution(term, subs)
|
||||||
|
val l = termToList(t)
|
||||||
|
return unifyLazy(l, list, subs)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun listToTerm(list: List): Term {
|
protected open fun listToTerm(list: List): Term {
|
||||||
|
|
|
@ -20,6 +20,7 @@ class Repl {
|
||||||
printAnswers(query())
|
printAnswers(query())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Logger.error("Error parsing REPL: ${e.message}")
|
Logger.error("Error parsing REPL: ${e.message}")
|
||||||
|
Logger.debug(e.stackTraceToString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -568,6 +568,23 @@ class AnalysisOperatorsTests {
|
||||||
assertEquals(0, result.size, "Expected 0 results")
|
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
|
@Test
|
||||||
fun `univ with two vars should throw`() {
|
fun `univ with two vars should throw`() {
|
||||||
val univ = Univ(Variable("X"), Variable("Y"))
|
val univ = Univ(Variable("X"), Variable("Y"))
|
||||||
|
|
Reference in a new issue