113 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			113 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | abolish_table_info :- at(compress/2). | ||
|  | 
 | ||
|  | time :- statistics(runtime,_), benchmark, fail; | ||
|  |         statistics(runtime,[_,T]), write(T). | ||
|  | 
 | ||
|  | benchmark :- data(Data), compress(Data, _C). | ||
|  | 
 | ||
|  | test :- | ||
|  |     data(Data), reinit, | ||
|  |     cputime(T0), | ||
|  |     compress(Data, C), write(C), write(' '), | ||
|  |     cputime(T1), T is T1-T0, write(T), write(' msecs'), nl, fail. | ||
|  | test. | ||
|  | 
 | ||
|  | %% data([a,a,b,a,a,b]). | ||
|  | %% data([a,a,b,a,a,b,a,a,b]). | ||
|  | %% data([a,a,a,a,a,a,a,a,a,a,a,a]). | ||
|  | %% data([a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a]). | ||
|  | %% data([a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a]). | ||
|  | %% data(D) :- bigdata(D). | ||
|  | %% data(D2) :- bigdata(D), append(D,D,D2). | ||
|  | data(D4) :- bigdata(D), append(D,D,D2), append(D2,D2,D4). | ||
|  | %% data(D8) :- bigdata(D), append(D,D,D2), append(D2,D2,D4), append(D4,D4,D8). | ||
|  | %% data(D16) :- bigdata(D), append(D,D,D2), append(D2,D2,D4), append(D4,D4,D8), append(D8,D8,D16). | ||
|  | 
 | ||
|  | bigdata([x,c,a,a,b,a,a,b,a,a,b,c,c,a,d,a,d,c,a,a,b,a,a,b,a,a,b,c,c,a,d,a,d,y]). | ||
|  | 
 | ||
|  | %% ==================== VERSION USING ASSERT FOR TABLES ====================== | ||
|  | %% reinit :- | ||
|  | %%	retractall(memo_compress(_, _)), | ||
|  | %%	assert(memo_compress([C1], [C1])), | ||
|  | %%	assert(memo_compress([C1,C2], [C1,C2])). | ||
|  | %% | ||
|  | %% compress(Initial, Compressed) :- | ||
|  | %%	( memo_compress(Initial, Compressed) -> true | ||
|  | %%	  mlength(Initial, LenInitial), | ||
|  | %%	  CurrentBest = Initial, | ||
|  | %%	  LenCurrentBest = LenInitial, | ||
|  | %%	  compress4(Initial, CurrentBest, LenCurrentBest, Compressed) | ||
|  | %%	  assert(memo_compress(Initial, Compressed)) | ||
|  | %%	). | ||
|  | %% =========================================================================== | ||
|  | 
 | ||
|  | reinit :- abolish_all_tables. | ||
|  | 
 | ||
|  | :- table compress/2. | ||
|  | 
 | ||
|  | compress(Initial, Compressed) :- | ||
|  | 	mlength(Initial, LenInitial), | ||
|  | 	CurrentBest = Initial, | ||
|  | 	LenCurrentBest = LenInitial, | ||
|  | 	compress4(Initial, CurrentBest, LenCurrentBest, Compressed). | ||
|  | 
 | ||
|  | compress4(Initial, CurrentBest, LenCurrentBest, Compressed) :- | ||
|  | 	( compress_with_bound(Initial, LenCurrentBest, NewBest) -> | ||
|  | 	        mlength(NewBest, NewLenBest), | ||
|  | 		compress4(Initial, NewBest, NewLenBest, Compressed) | ||
|  | 	; Compressed = CurrentBest | ||
|  | 	). | ||
|  | 
 | ||
|  | compress_with_bound(Initial, LenBound, Better) :- | ||
|  | 	repetition_compress(Initial, LenBound, Better). | ||
|  | compress_with_bound(Initial, LenBound, Better) :- | ||
|  | 	two_price_compress(Initial, LenBound, Better). | ||
|  | 
 | ||
|  | repetition_compress(Initial, LenBound, Better) :- | ||
|  | 	chopup(Initial, Piece, Repeated), | ||
|  | 	( Piece = [C] -> | ||
|  | 		Better = [C,Repeated] | ||
|  | 	; compress(Piece, CompressedPiece), | ||
|  | 	  append(['('|CompressedPiece], [')',Repeated], Better) | ||
|  | 	), | ||
|  | 	mlength(Better, LenBetter), | ||
|  | 	LenBetter < LenBound. | ||
|  | 
 | ||
|  | two_price_compress(Initial, LenBound, Better) :- | ||
|  | 	append(Piece1, Piece2, Initial), | ||
|  | 	Piece1 \== [], | ||
|  | 	Piece2 \== [], | ||
|  | 	compress(Piece1, Compressed1), | ||
|  | 	mlength(Compressed1, LenCompressed1), | ||
|  | 	LenCompressed1 < LenBound, | ||
|  | 	compress(Piece2, Compressed2), | ||
|  | 	mlength(Compressed2, LenCompressed2), | ||
|  | 	LenCompressed1 + LenCompressed2 < LenBound, | ||
|  | 	append(Compressed1, Compressed2, Better). | ||
|  | 
 | ||
|  | chopup(List, Part, Repeated) :- | ||
|  | 	append(Part, Rest, List), | ||
|  | 	Part \== [], | ||
|  | 	Rest \== [], | ||
|  | 	count_parts(Rest, Part, 1, Repeated). | ||
|  | 
 | ||
|  | count_parts(Rest, Part, I, O) :- | ||
|  | 	( Rest == [] -> I = O | ||
|  | 	; append(Part, Rest1, Rest), | ||
|  | 	  I1 is I+1, | ||
|  | 	  count_parts(Rest1, Part, I1, O) | ||
|  | 	). | ||
|  | 
 | ||
|  | %%---------------------------------------------------------------------------- | ||
|  | %% Utilities below | ||
|  | %%---------------------------------------------------------------------------- | ||
|  | 
 | ||
|  | append([],L,L). | ||
|  | append([H|L1],L2,[H|L3]) :- append(L1,L2,L3). | ||
|  | 
 | ||
|  | mlength(L,N) :- mlength(L,0,N). | ||
|  | 
 | ||
|  | mlength([],N,N). | ||
|  | mlength([_|R],N0,N) :- N1 is N0+1, mlength(R,N1,N). | ||
|  | 
 |