269 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
| /*  Part of SWI-Prolog
 | |
| 
 | |
|     Author:        Tom Schrijvers, Bart Demoen, Jan Wielemaker
 | |
|     E-mail:        Tom.Schrijvers@cs.kuleuven.be
 | |
|     WWW:           http://www.swi-prolog.org
 | |
|     Copyright (C): 2004-2008, K.U. Leuven
 | |
| 
 | |
|     This program is free software; you can redistribute it and/or
 | |
|     modify it under the terms of the GNU General Public License
 | |
|     as published by the Free Software Foundation; either version 2
 | |
|     of the License, or (at your option) any later version.
 | |
| 
 | |
|     This program is distributed in the hope that it will be useful,
 | |
|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|     GNU General Public License for more details.
 | |
| 
 | |
|     You should have received a copy of the GNU General Public
 | |
|     License along with this library; if not, write to the Free Software
 | |
|     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 
 | |
|     As a special exception, if you link this library with other files,
 | |
|     compiled with a Free Software compiler, to produce an executable, this
 | |
|     library does not by itself cause the resulting executable to be covered
 | |
|     by the GNU General Public License. This exception does not however
 | |
|     invalidate any other reasons why the executable file might be covered by
 | |
|     the GNU General Public License.
 | |
| */
 | |
| 
 | |
| 
 | |
| :- module(hprolog,
 | |
| 	  [ substitute_eq/4,		% +OldVal, +OldList, +NewVal, -NewList
 | |
| 	    memberchk_eq/2,		% +Val, +List
 | |
| 	    intersect_eq/3,		% +List1, +List2, -Intersection
 | |
| 	    list_difference_eq/3,	% +List, -Subtract, -Rest
 | |
| 	    take/3,			% +N, +List, -FirstElements
 | |
| 	    drop/3,			% +N, +List, -LastElements
 | |
| 	    split_at/4,			% +N, +List, -FirstElements, -LastElements
 | |
| 	    max_go_list/2,		% +List, -Max
 | |
| 	    or_list/2,			% +ListOfInts, -BitwiseOr
 | |
| 	    sublist/2,			% ?Sublist, +List
 | |
| 	    bounded_sublist/3,		% ?Sublist, +List, +Bound
 | |
| 	    chr_delete/3,
 | |
| 	    init_store/2,
 | |
| 	    get_store/2,
 | |
| 	    update_store/2,
 | |
| 	    make_get_store_goal/3,
 | |
| 	    make_update_store_goal/3,
 | |
| 	    make_init_store_goal/3,
 | |
| 
 | |
| 	    empty_ds/1,
 | |
| 	    ds_to_list/2,
 | |
| 	    get_ds/3,
 | |
| 	    put_ds/4
 | |
| %	    lookup_ht1/4
 | |
| 	  ]).
 | |
| 
 | |
| :- reexport('../lists',[sublist/2]).
 | |
| 
 | |
| %:- use_module(library(lists)).
 | |
| :- use_module(library(assoc)).
 | |
| 
 | |
| /** <module> hProlog compatibility library
 | |
| 
 | |
| This library has been developed mainly for porting the CHR package.
 | |
| 
 | |
| @author Tom Schrijvers
 | |
| @author Bart Demoen
 | |
| @author Jan Wielemaker
 | |
| @tbd	Ultimately, this must disappear.  Generally useful predicates
 | |
| 	must be moved to their appropriate library.  Others must be moved
 | |
| 	into the CHR utilities.
 | |
| */
 | |
| 
 | |
| empty_ds(DS) :- empty_assoc(DS).
 | |
| ds_to_list(DS,LIST) :- assoc_to_list(DS,LIST).
 | |
| get_ds(A,B,C) :- get_assoc(A,B,C).
 | |
| put_ds(A,B,C,D) :- put_assoc(A,B,C,D).
 | |
| 
 | |
| 
 | |
| init_store(Name,Value) :- nb_setval(Name,Value).
 | |
| 
 | |
| get_store(Name,Value) :- nb_getval(Name,Value).
 | |
| 
 | |
| update_store(Name,Value) :- b_setval(Name,Value).
 | |
| 
 | |
| make_init_store_goal(Name,Value,Goal) :- Goal = nb_setval(Name,Value).
 | |
| 
 | |
| make_get_store_goal(Name,Value,Goal) :- Goal = nb_getval(Name,Value).
 | |
| 
 | |
| make_update_store_goal(Name,Value,Goal) :- Goal = b_setval(Name,Value).
 | |
| 
 | |
| 
 | |
| 		 /*******************************
 | |
| 		 *      MORE LIST OPERATIONS	*
 | |
| 		 *******************************/
 | |
| 
 | |
| %%	substitute_eq(+OldVal, +OldList, +NewVal, -NewList)
 | |
| %
 | |
| %	Substitute OldVal by NewVal in OldList and unify the result
 | |
| %	with NewList.
 | |
| 
 | |
| substitute_eq(_, [], _, []) :- ! .
 | |
| substitute_eq(X, [U|Us], Y, [V|Vs]) :-
 | |
|         (   X == U
 | |
| 	->  V = Y,
 | |
|             substitute_eq(X, Us, Y, Vs)
 | |
|         ;   V = U,
 | |
|             substitute_eq(X, Us, Y, Vs)
 | |
|         ).
 | |
| 
 | |
| %%	memberchk_eq(+Val, +List)
 | |
| %
 | |
| %	Deterministic check of membership using == rather than
 | |
| %	unification.
 | |
| 
 | |
| memberchk_eq(X, [Y|Ys]) :-
 | |
|    (   X == Y
 | |
|    ->  true
 | |
|    ;   memberchk_eq(X, Ys)
 | |
|    ).
 | |
| 
 | |
| % :- load_foreign_library(chr_support).
 | |
| 
 | |
| %%	list_difference_eq(+List, -Subtract, -Rest)
 | |
| %
 | |
| %	Delete all elements of Subtract from List and unify the result
 | |
| %	with Rest.  Element comparision is done using ==/2.
 | |
| 
 | |
| list_difference_eq([],_,[]).
 | |
| list_difference_eq([X|Xs],Ys,L) :-
 | |
| 	(   memberchk_eq(X,Ys)
 | |
| 	->  list_difference_eq(Xs,Ys,L)
 | |
| 	;   L = [X|T],
 | |
| 	    list_difference_eq(Xs,Ys,T)
 | |
| 	).
 | |
| 
 | |
| %%	intersect_eq(+List1, +List2, -Intersection)
 | |
| %
 | |
| %	Determine the intersection of two lists without unifying values.
 | |
| 
 | |
| intersect_eq([], _, []).
 | |
| intersect_eq([X|Xs], Ys, L) :-
 | |
| 	(   memberchk_eq(X, Ys)
 | |
| 	->  L = [X|T],
 | |
| 	    intersect_eq(Xs, Ys, T)
 | |
| 	;   intersect_eq(Xs, Ys, L)
 | |
| 	).
 | |
| 
 | |
| 
 | |
| %%	take(+N, +List, -FirstElements)
 | |
| %
 | |
| %	Take the first  N  elements  from   List  and  unify  this  with
 | |
| %	FirstElements. The definition is based   on the GNU-Prolog lists
 | |
| %	library. Implementation by Jan Wielemaker.
 | |
| 
 | |
| take(0, _, []) :- !.
 | |
| take(N, [H|TA], [H|TB]) :-
 | |
| 	N > 0,
 | |
| 	N2 is N - 1,
 | |
| 	take(N2, TA, TB).
 | |
| 
 | |
| %%	drop(+N, +List, -ListMinFirstN) is semidet.
 | |
| %
 | |
| %	Drop the first N elements from List and unify the remainder with
 | |
| %	LastElements.
 | |
| 
 | |
| drop(0,LastElements,LastElements) :- !.
 | |
| drop(N,[_|Tail],LastElements) :-
 | |
| 	N > 0,
 | |
| 	N1 is N  - 1,
 | |
| 	drop(N1,Tail,LastElements).
 | |
| 
 | |
| %%	split_at(+N, +List, +FirstN, -Rest) is semidet.
 | |
| %
 | |
| %	Combines take/3 and drop/3.
 | |
| 
 | |
| split_at(0,L,[],L) :- !.
 | |
| split_at(N,[H|T],[H|L1],L2) :-
 | |
| 	M is N -1,
 | |
| 	split_at(M,T,L1,L2).
 | |
| 
 | |
| %%	max_go_list(+List, -Max)
 | |
| %
 | |
| %	Return the maximum of List in the standard order of terms.
 | |
| 
 | |
| max_go_list([H|T], Max) :-
 | |
| 	max_go_list(T, H, Max).
 | |
| 
 | |
| max_go_list([], Max, Max).
 | |
| max_go_list([H|T], X, Max) :-
 | |
|         (   H @=< X
 | |
| 	->  max_go_list(T, X, Max)
 | |
|         ;   max_go_list(T, H, Max)
 | |
|         ).
 | |
| 
 | |
| %%	or_list(+ListOfInts, -BitwiseOr)
 | |
| %
 | |
| %	Do a bitwise disjuction over all integer members of ListOfInts.
 | |
| 
 | |
| or_list(L, Or) :-
 | |
| 	or_list(L, 0, Or).
 | |
| 
 | |
| or_list([], Or, Or).
 | |
| or_list([H|T], Or0, Or) :-
 | |
| 	Or1 is H \/ Or0,
 | |
| 	or_list(T, Or1, Or).
 | |
| 
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| 
 | |
| %%	sublist(?Sub, +List) is nondet.
 | |
| %
 | |
| %	True if all elements of Sub appear in List in the same order.
 | |
| 
 | |
| %sublist(L, L).
 | |
| %sublist(Sub, [H|T]) :-
 | |
| %	'$sublist1'(T, H, Sub).
 | |
| 
 | |
| %'$sublist1'(Sub, _, Sub).
 | |
| %'$sublist1'([H|T], _, Sub) :-
 | |
| %	'$sublist1'(T, H, Sub).
 | |
| %'$sublist1'([H|T], X, [X|Sub]) :-
 | |
| %	'$sublist1'(T, H, Sub).
 | |
| 
 | |
| %%	bounded_sublist(?Sub, +List, +Bound:integer)
 | |
| %
 | |
| %	As sublist/2, but Sub has at most  Bound elements. E.g. the call
 | |
| %	below generates all 21 sublists of length   =< 2 from the second
 | |
| %	argument.
 | |
| %	
 | |
| %	==
 | |
| %	?- bounded_sublist(List, [a,b,c,d], 2).
 | |
| %	X = [] ;
 | |
| %	X = [a] ;
 | |
| %	X = [a, b] ;
 | |
| %	X = [a] ;
 | |
| %	...
 | |
| %	==
 | |
| 
 | |
| bounded_sublist(Sublist,_,_) :-
 | |
| 	Sublist = [].
 | |
| bounded_sublist(Sublist,[H|List],Bound) :-
 | |
| 	Bound > 0,
 | |
| 	(
 | |
| 		Sublist = [H|Rest],
 | |
| 		NBound is Bound - 1,
 | |
| 		bounded_sublist(Rest,List,NBound)
 | |
| 	;
 | |
| 		bounded_sublist(Sublist,List,Bound)
 | |
| 	).
 | |
| 	
 | |
| 
 | |
| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | |
| 
 | |
| %%	chr_delete(+List, +Element, -Rest) is det.
 | |
| %
 | |
| %	Rest is a copy of List   without elements matching Element using
 | |
| %	==.
 | |
| 
 | |
| chr_delete([], _, []).
 | |
| chr_delete([H|T], X, L) :-
 | |
|         (   H==X ->
 | |
|             chr_delete(T, X, L)
 | |
|         ;   L=[H|RT],
 | |
|             chr_delete(T, X, RT)
 | |
|         ).
 | |
|     
 |