/* Nick De Frangh 20051401 Sessie 6 : Prolog */ /* Oefening 1: Suppose we have the following database: */ p(1). p(2) :- !. p(3). /* Write all of Prolog's answers to the following queries: ?- p(X). X = 1; X = 2; No. ?- p(X),p(Y). X = 1, Y = 1 ; X = 1, Y = 2 ; X = 2, Y = 1 ; X = 2, Y = 2 ; No. ?- p(X),!,p(Y). X = 1, Y = 1 ; X = 1, Y = 2 ; No. */ /* Oefening 2 : First, explain what the following program does: class(Number,positive) :- Number > 0. class(0,zero). class(Number, negative) :- Number < 0. Het zegt of een bepaald getal positiefm negatief of nul is. Second, improve it by adding green cuts. */ class(0,zero). class(Number, X) :- Number > 0, !, X = positive. class(_, negative). /* Oefening 3 : Without using cut, write a predicate split/3 that splits a list of integers into two lists: one containing the positive ones (and zero), the other containing the negative ones. For example: split([3,4,-5,-1,0,4,-9],P,N) should return: P = [3,4,0,4] N = [-5,-1,-9]. Then improve this program, without changing its meaning, with the help of cut. Eerste versie : split([], [], []). split([H|T], [H|X], Y) :- H >= 0, split(T, X, Y). split([H|T], X, [H|Y]) :- H < 0, split(T, X, Y). Cut versie: */ split([], [], []). split([H|T], [H|X], Y) :- H >= 0, !, split(T, X, Y). split([H|T], X, [H|Y]) :- split(T, X, Y). /* Oefening 4: Define a predicate nu/2 ("not unifiable") which takes two terms as arguments and succeeds if the two terms do not unify. For example: nu(foo,foo). no nu (foo,blob). yes nu(foo,X). no You should define this predicate in three different ways: - write it with the help of = and \+ nu(X, Y) :- \+ X = Y. - write it with the help of =, but don't use \+. nu(X, Y) :- X = Y, !, fail. nu(_, _). - write it using a cut-fail combination. Don't use = and don't use \+. nu(X, X) :- !, fail. nu(_,_). */ nu(X, X) :- !, fail. nu(_,_). /* Oefening 5 : Implement a sudoku-solver (9x9). Try to make as much use as possible of recursion, i.e. don't just take the straightforward option where every position is assigned a different variable, and all constraints are based on enumerating these variables... Hint: Represent a board as a list of rows, which are lists of numbers. */ /* [[_, _, _, _, _, _, _, _, _], [_, _, _, _, _, _, _, _, _], [_, _, _, _, _, _, _, _, _], [_, _, _, _, _, _, _, _, _], ...] */ element(X) :- L = [1, 2, 3, 4, 5, 6, 7, 8, 9], member(X, L). solve_sudoku(G,S) :- build_sudoku(G, S), check_sudoku(S), pretty_sudo_print(S). build_sudoku([],[]). build_sudoku([OH|OT], [H|T]) :- build_row(OH, H), check_row(H), build_sudoku(OT, T). build_row([], []). build_row([OH|OT], [H|T]) :- element(OH), H is OH, build_row(OT, T). %Controleer heel de sudoku (rijen moeten niet gecontroleerd worden, deze worden al in het opstellen gecontroleerd check_sudoku(A) :- check_all_columns(A), !, check_all_blocks(A). %Controleer of alle blokken correct zijn check_all_blocks([]). check_all_blocks([A,B,C|Rest]) :- check_three_blocks([A, B, C]), !, check_all_blocks(Rest). check_three_blocks([[],[],[]]). check_three_blocks([[A,B,C|R1],[D,E,F|R2],[G,H,I|R3]]) :- check_one_block([A, B, C, D, E, F, G, H, I]), !, check_three_blocks([R1, R2, R3]). %kan eventueel weg check_one_block(A) :- all_different(A). %Controleer of alle kolommen correct zijn check_all_columns([[],[],[],[],[],[],[],[],[]]). check_all_columns([[H1|T1],[H2|T2],[H3|T3],[H4|T4],[H5|T5],[H6|T6],[H7|T7],[H8|T8],[H9|T9]]) :- check_column([H1,H2,H3,H4,H5,H6,H7,H8,H9]), !, check_all_columns([T1,T2,T3,T4,T5,T6,T7,T8,T9]). %kan eventueel weg check_column(C) :- all_different(C). %Controleer of alle rijen correct zijn check_all_rows([]). check_all_rows([H|T]) :- check_row(H), !, check_all_rows(T). %kan eventueel weg check_row(R) :- all_different(R). %Ga na of alle ellementen in de gegeven lijst verschillend zijn of niet. all_different([]). all_different([H|T]) :- \+ member(H, T), !, all_different(T). % Dit heb ik gevonden op het internet % wordt enkel gebruikt voor output % pretty printing \0/ pretty_sudo_print([]). pretty_sudo_print([A,B,C|T]) :- nl,printsudorow(A), printsudorow(B), printsudorow(C), pretty_sudo_print(T). printsudorow([]) :- nl. printsudorow([A,B,C|T]) :- writerepv(A),tab(1), writerepv(B),tab(1), writerepv(C),tab(3), printsudorow(T). writerepv(X) :- var(X),!,write(' '). writerepv(X) :- write(X).