All pastes #509176 Raw Edit

Nickman

public text v1 · immutable
·published 2007-05-25 10:09 UTC
rendered paste body
/*
	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).