/*
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).