163 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			163 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								/*  $Id: pairs.pl,v 1.1 2008-02-12 17:03:52 vsc Exp $
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Part of SWI-Prolog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Author:        Jan Wielemaker
							 | 
						||
| 
								 | 
							
								    E-mail:        wielemak@science.uva.nl
							 | 
						||
| 
								 | 
							
								    WWW:           http://www.swi-prolog.org
							 | 
						||
| 
								 | 
							
								    Copyright (C): 1985-2006, University of Amsterdam
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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(pairs,
							 | 
						||
| 
								 | 
							
									  [ pairs_keys_values/3,
							 | 
						||
| 
								 | 
							
									    pairs_values/2,
							 | 
						||
| 
								 | 
							
									    pairs_keys/2,
							 | 
						||
| 
								 | 
							
									    group_pairs_by_key/2,
							 | 
						||
| 
								 | 
							
									    transpose_pairs/2,
							 | 
						||
| 
								 | 
							
									    map_list_to_pairs/3
							 | 
						||
| 
								 | 
							
									  ]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** <module> Operations on key-value lists
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This module implements common operations on  Key-Value lists, also known
							 | 
						||
| 
								 | 
							
								as  _Pairs_.  Pairs  have  great  practical  value,  especially  due  to
							 | 
						||
| 
								 | 
							
								keysort/2 and the library assoc.pl.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This library is based  on  disussion   in  the  SWI-Prolog  mailinglist,
							 | 
						||
| 
								 | 
							
								including specifications from Quintus and a  library proposal by Richard
							 | 
						||
| 
								 | 
							
								O'Keefe.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@see	keysort/2, library(assoc)
							 | 
						||
| 
								 | 
							
								@author Jan Wielemaker
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	pairs_keys_values(?Pairs, ?Keys, ?Values) is det.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	True if Keys holds the keys of Pairs and Values the values.
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	Deterministic if any argument is instantiated to a finite list
							 | 
						||
| 
								 | 
							
								%	and the others are either free or finite lists.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pairs_keys_values(Pairs, Keys, Values) :-
							 | 
						||
| 
								 | 
							
									(   nonvar(Pairs) ->
							 | 
						||
| 
								 | 
							
									    pairs_keys_values_(Pairs, Keys, Values)
							 | 
						||
| 
								 | 
							
									;   nonvar(Keys) ->
							 | 
						||
| 
								 | 
							
									    keys_values_pairs(Keys, Values, Pairs)
							 | 
						||
| 
								 | 
							
									;   values_keys_pairs(Values, Keys, Pairs)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pairs_keys_values_([], [], []).
							 | 
						||
| 
								 | 
							
								pairs_keys_values_([K-V|Pairs], [K|Keys], [V|Values]) :-
							 | 
						||
| 
								 | 
							
									pairs_keys_values_(Pairs, Keys, Values).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								keys_values_pairs([], [], []).
							 | 
						||
| 
								 | 
							
								keys_values_pairs([K|Ks], [V|Vs], [K-V|Pairs]) :-
							 | 
						||
| 
								 | 
							
									keys_values_pairs(Ks, Vs, Pairs).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								values_keys_pairs([], [], []).
							 | 
						||
| 
								 | 
							
								values_keys_pairs([V|Vs], [K|Ks], [K-V|Pairs]) :-
							 | 
						||
| 
								 | 
							
									values_keys_pairs(Vs, Ks, Pairs).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	pairs_values(+Pairs, -Values) is det.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Remove the keys  from  a  list   of  Key-Value  pairs.  Same  as
							 | 
						||
| 
								 | 
							
								%	pairs_keys_values(Pairs, _, Values)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pairs_values([], []).
							 | 
						||
| 
								 | 
							
								pairs_values([_-V|T0], [V|T]) :-
							 | 
						||
| 
								 | 
							
									pairs_values(T0, T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	pairs_keys(+Pairs, -Keys) is det.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Remove the values  from  a  list   of  Key-Value  pairs.  Same  as
							 | 
						||
| 
								 | 
							
								%	pairs_keys_values(Pairs, Keys, _)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								pairs_keys([], []).
							 | 
						||
| 
								 | 
							
								pairs_keys([K-_|T0], [K|T]) :-
							 | 
						||
| 
								 | 
							
									pairs_keys(T0, T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	group_pairs_by_key(+Pairs, -Joined:list(Key-Values)) is det.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Group values with the same key.  For example:
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	==
							 | 
						||
| 
								 | 
							
								%	?- group_pairs_by_key([a-2, a-1, b-4], X).
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	X = [a-[2,1], b-[4]]
							 | 
						||
| 
								 | 
							
								%	==
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	@param	Pairs	Key-Value list, sorted to the standard order
							 | 
						||
| 
								 | 
							
								%			of terms (as keysort/2 does)
							 | 
						||
| 
								 | 
							
								%	@param  Joined	List of Key-Group, where Group is the
							 | 
						||
| 
								 | 
							
								%			list of Values associated with Key. 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								group_pairs_by_key([], []).
							 | 
						||
| 
								 | 
							
								group_pairs_by_key([M-N|T0], [M-[N|TN]|T]) :-
							 | 
						||
| 
								 | 
							
									same_key(M, T0, TN, T1),
							 | 
						||
| 
								 | 
							
									group_pairs_by_key(T1, T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								same_key(M, [M-N|T0], [N|TN], T) :- !,
							 | 
						||
| 
								 | 
							
									same_key(M, T0, TN, T).
							 | 
						||
| 
								 | 
							
								same_key(_, L, [], L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	transpose_pairs(+Pairs, -Transposed) is det.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Swap Key-Value to Value-Key and sort the result on Value
							 | 
						||
| 
								 | 
							
								%	(the new key) using keysort/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								transpose_pairs(Pairs, Transposed) :-
							 | 
						||
| 
								 | 
							
									flip_pairs(Pairs, Flipped),
							 | 
						||
| 
								 | 
							
									keysort(Flipped, Transposed).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								flip_pairs([], []).
							 | 
						||
| 
								 | 
							
								flip_pairs([Key-Val|Pairs], [Val-Key|Flipped]) :-
							 | 
						||
| 
								 | 
							
									flip_pairs(Pairs, Flipped).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%	map_list_to_pairs(:Function, +List, -Keyed)
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%	Create a key-value list by mapping each element of List.
							 | 
						||
| 
								 | 
							
								%	For example, if we have a list of lists we can create a
							 | 
						||
| 
								 | 
							
								%	list of Length-List using
							 | 
						||
| 
								 | 
							
								%	
							 | 
						||
| 
								 | 
							
								%	==
							 | 
						||
| 
								 | 
							
								%		map_list_to_pairs(length, ListOfLists, Pairs),
							 | 
						||
| 
								 | 
							
								%	==
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- module_transparent
							 | 
						||
| 
								 | 
							
									map_list_to_pairs/3,
							 | 
						||
| 
								 | 
							
									map_list_to_pairs2/3.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								map_list_to_pairs(Function, List, Pairs) :-
							 | 
						||
| 
								 | 
							
									map_list_to_pairs2(List, Function, Pairs).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								map_list_to_pairs2([], _, []).
							 | 
						||
| 
								 | 
							
								map_list_to_pairs2([H|T0], Pred, [K-H|T]) :-
							 | 
						||
| 
								 | 
							
									call(Pred, H, K),
							 | 
						||
| 
								 | 
							
									map_list_to_pairs2(T0, Pred, T).
							 | 
						||
| 
								 | 
							
								
							 |