171 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			171 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | 
 | ||
|  | :- object(random, | ||
|  | 	implements(randomp)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	:- info([ | ||
|  | 		version is 1.0, | ||
|  | 		authors is 'Paulo Moura', | ||
|  | 		date is 2000/7/24, | ||
|  | 		comment is 'Random number generator predicates.']). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	:- initialization(reset_seed). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	:- private(seed_/3). | ||
|  | 	:- dynamic(seed_/3). | ||
|  | 
 | ||
|  | 	:- mode(seed_(+integer, +integer, +integer), one). | ||
|  | 
 | ||
|  | 	:- info(seed_/3, [ | ||
|  | 		comment is 'Stores the current random generator seed values.', | ||
|  | 		argnames is ['S0', 'S1', 'S2']]). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	random(Random) :- | ||
|  | 		retract(seed_(A0, A1, A2)), | ||
|  | 		random(A0, A1, A2, B0, B1, B2, Random), | ||
|  | 		asserta(seed_(B0, B1, B2)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	random(A0, A1, A2, B0, B1, B2, Random) :- | ||
|  | 		B0 is (A0*171) mod 30269, | ||
|  | 		B1 is (A1*172) mod 30307, | ||
|  | 		B2 is (A2*170) mod 30323, | ||
|  | 		Float is A0/30269 + A1/30307 + A2/30323, | ||
|  | 		Random is Float - truncate(Float). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	random(Lower, Upper, Random) :- | ||
|  | 		integer(Lower), | ||
|  | 		integer(Upper), | ||
|  | 		Upper >= Lower, | ||
|  | 		!, | ||
|  | 		random(Float), | ||
|  | 		Random is truncate((Float*(Upper-Lower)+Lower)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	random(Lower, Upper, Random) :- | ||
|  | 		float(Lower), | ||
|  | 		float(Upper), | ||
|  | 		Upper >= Lower, | ||
|  | 		random(Float), | ||
|  | 		Random is Float*(Upper-Lower)+Lower. | ||
|  | 
 | ||
|  | 
 | ||
|  | 	randseq(Length, Lower, Upper, Sequence) :- | ||
|  | 		integer(Length), | ||
|  | 		Length >= 0, | ||
|  | 		integer(Lower), | ||
|  | 		integer(Upper), | ||
|  | 		Upper >= Lower, | ||
|  | 		!, | ||
|  | 		retract(seed_(A0, A1, A2)), | ||
|  | 		randseq(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], List), | ||
|  | 		asserta(seed_(B0, B1, B2)), | ||
|  | 		map_truncate(List, Sequence). | ||
|  | 
 | ||
|  | 	randseq(Length, Lower, Upper, Sequence) :- | ||
|  | 		integer(Length), | ||
|  | 		Length >= 0, | ||
|  | 		float(Lower), | ||
|  | 		float(Upper), | ||
|  | 		Upper >= Lower, | ||
|  | 		retract(seed_(A0, A1, A2)), | ||
|  | 		randseq(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], Sequence), | ||
|  | 		asserta(seed_(B0, B1, B2)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	randseq(0, _, _, Seed, Seed, List, List) :- | ||
|  | 		!. | ||
|  | 
 | ||
|  | 	randseq(N, Lower, Upper, (A0, A1, A2), (C0, C1, C2), Acc, List) :- | ||
|  | 		N2 is N - 1, | ||
|  | 		random(A0, A1, A2, B0, B1, B2, R), | ||
|  | 		Random is R*(Upper-Lower)+Lower, | ||
|  | 		randseq(N2, Lower, Upper, (B0, B1, B2), (C0, C1, C2), [Random| Acc], List). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	map_truncate([], []). | ||
|  | 
 | ||
|  | 	map_truncate([Float| Floats], [Integer| Integers]) :- | ||
|  | 		Integer is truncate(Float), | ||
|  | 		map_truncate(Floats, Integers). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	randset(Length, Lower, Upper, Set) :- | ||
|  | 		integer(Length), | ||
|  | 		Length >= 0, | ||
|  | 		integer(Lower), | ||
|  | 		integer(Upper), | ||
|  | 		Upper >= Lower, | ||
|  | 		Length =< Upper - Lower, | ||
|  | 		!, | ||
|  | 		retract(seed_(A0, A1, A2)), | ||
|  | 		randset(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], Set), | ||
|  | 		asserta(seed_(B0, B1, B2)). | ||
|  | 
 | ||
|  | 	randset(Length, Lower, Upper, Set) :- | ||
|  | 		integer(Length), | ||
|  | 		Length >= 0, | ||
|  | 		float(Lower), | ||
|  | 		float(Upper), | ||
|  | 		Upper >= Lower, | ||
|  | 		retract(seed_(A0, A1, A2)), | ||
|  | 		randset(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], Set), | ||
|  | 		asserta(seed_(B0, B1, B2)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	randset(0, _, _, Seed, Seed, List, List) :- | ||
|  | 		!. | ||
|  | 
 | ||
|  | 	randset(N, Lower, Upper, (A0, A1, A2), (C0, C1, C2), Acc, List) :- | ||
|  | 		N2 is N - 1, | ||
|  | 		random(A0, A1, A2, B0, B1, B2, Float), | ||
|  | 		Float2 is Float*(Upper-Lower)+Lower, | ||
|  | 		(integer(Lower) -> | ||
|  | 			Random is truncate(Float2) | ||
|  | 			; | ||
|  | 			Random is Float2), | ||
|  | 		(not_member(Acc, Random) -> | ||
|  | 			add_ordered(Acc, Random, Acc2), | ||
|  | 			randset(N2, Lower, Upper, (B0, B1, B2), (C0, C1, C2), Acc2, List) | ||
|  | 			; | ||
|  | 			randset(N, Lower, Upper, (B0, B1, B2), (C0, C1, C2), Acc, List)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	not_member([], _). | ||
|  | 
 | ||
|  | 	not_member([H| T], R) :- | ||
|  | 		H =\= R, | ||
|  | 		not_member(T, R). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	add_ordered([], R, [R]). | ||
|  | 
 | ||
|  | 	add_ordered([H| T], R, L) :- | ||
|  | 		H > R -> | ||
|  | 			L = [R, H| T] | ||
|  | 			; | ||
|  | 			L = [H| T2], | ||
|  | 			add_ordered(T, R, T2). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	reset_seed :- | ||
|  | 		retractall(seed_(_, _, _)), | ||
|  | 		asserta(seed_(3172, 9814, 20125)). | ||
|  | 
 | ||
|  | 
 | ||
|  | 	set_seed(Seed) :- | ||
|  | 		integer(Seed), | ||
|  | 		Seed > 0, | ||
|  | 		retractall(seed_(_, _, _)), | ||
|  | 		S0 is Seed mod 30269, | ||
|  | 		S1 is Seed mod 30307, | ||
|  | 		S2 is Seed mod 30323, | ||
|  | 		asserta(seed_(S0, S1, S2)). | ||
|  | 
 | ||
|  | 
 | ||
|  | :- end_object. |