git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@53 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
		
			
				
	
	
		
			351 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			351 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
:- object(difflist,
 | 
						|
	implements(listp),
 | 
						|
	extends(compound)).
 | 
						|
 | 
						|
 | 
						|
	:- info([
 | 
						|
		version is 1.0,
 | 
						|
		authors is 'Paulo Moura',
 | 
						|
		date is 2000/7/24,
 | 
						|
		comment is 'Difference list predicates.']).
 | 
						|
 | 
						|
 | 
						|
	:- public(as_list/2).
 | 
						|
 | 
						|
	:- mode(as_list(+list, -list), one).
 | 
						|
 | 
						|
	:- info(as_list/2,
 | 
						|
		[comment is 'Converts a difference list to a normal list.',
 | 
						|
		 argnames is ['Diffist', 'List']]).
 | 
						|
 | 
						|
 | 
						|
	append(List1-Back1, Back1-Back2, List1-Back2) :-
 | 
						|
		nonvar(List1),
 | 
						|
		nonvar(Back1),
 | 
						|
		!.
 | 
						|
 | 
						|
	append(Prefix, Suffix, List) :-
 | 
						|
		length(List, Length),
 | 
						|
		prefix(Prefix, List),
 | 
						|
		length(Prefix, PLength),
 | 
						|
		SLength is Length - PLength,
 | 
						|
		length(Suffix, SLength),
 | 
						|
		suffix(Suffix, List).
 | 
						|
 | 
						|
 | 
						|
	as_list(List-Back, Out) :-
 | 
						|
		List == Back ->
 | 
						|
			Out = []
 | 
						|
			;
 | 
						|
			Out = [Head| Tail],
 | 
						|
			List = [Head| Rest],
 | 
						|
			as_list(Rest-Back, Tail).
 | 
						|
 | 
						|
 | 
						|
	delete(List-Back, Element, Remaining) :-
 | 
						|
		List == Back ->
 | 
						|
			unify_with_occurs_check(Remaining, Back-Back)
 | 
						|
			;
 | 
						|
			List \== Back,
 | 
						|
			List = [Head| Tail],
 | 
						|
			(Head == Element ->
 | 
						|
				delete(Tail-Back, Element, Remaining)
 | 
						|
				;
 | 
						|
				Remaining = [Head| Tail2],
 | 
						|
				delete(Tail-Back, Element, Tail2-Back)).
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	delete_matches(List-Back, Element, Remaining) :-
 | 
						|
		List == Back ->
 | 
						|
			unify_with_occurs_check(Remaining, Back-Back)
 | 
						|
			;
 | 
						|
			List \== Back,
 | 
						|
			List = [Head| Tail],
 | 
						|
			(\+ \+ Head = Element ->
 | 
						|
				delete_matches(Tail-Back, Element, Remaining)
 | 
						|
				;
 | 
						|
				Remaining = [Head| Tail2],
 | 
						|
				delete_matches(Tail-Back, Element, Tail2-Back)).
 | 
						|
 | 
						|
 | 
						|
	empty(List-Back) :-
 | 
						|
		List == Back.
 | 
						|
 | 
						|
 | 
						|
	flatten(List-Back, Flatted-Back) :-
 | 
						|
		flatten(List-Back, Back-Back, Flatted-Back).
 | 
						|
 | 
						|
 | 
						|
	flatten(Var, Tail-Back, [Var| Tail]-Back) :-
 | 
						|
		var(Var),
 | 
						|
		!.
 | 
						|
 | 
						|
	flatten(List-Back, Flatted, Flatted) :-
 | 
						|
		List == Back,
 | 
						|
		!.
 | 
						|
 | 
						|
	flatten(List-Back, Acc, Flatted) :-
 | 
						|
		!,
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		flatten(Tail-Back, Acc, Acc2),
 | 
						|
		flatten(Head, Acc2, Flatted).
 | 
						|
 | 
						|
	flatten(Head, Tail-Back, [Head| Tail]-Back).
 | 
						|
 | 
						|
 | 
						|
	keysort(Difflist, Sorted) :-
 | 
						|
		as_list(Difflist, List),
 | 
						|
		{keysort(List, List2)},
 | 
						|
		list::as_difflist(List2, Sorted).		
 | 
						|
 | 
						|
 | 
						|
	last(List-Back, Last) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		last(Tail-Back, Head, Last).
 | 
						|
 | 
						|
 | 
						|
	last(List, Last, Last) :-
 | 
						|
		unify_with_occurs_check(List, Back-Back).
 | 
						|
 | 
						|
	last(List-Back, _, Last) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		last(Tail-Back, Head, Last).
 | 
						|
 | 
						|
 | 
						|
	length(List, Length) :-
 | 
						|
		integer(Length) ->
 | 
						|
			Length >= 0,
 | 
						|
			make_list(Length, List)
 | 
						|
			;
 | 
						|
			length(List, 0, Length).
 | 
						|
 | 
						|
 | 
						|
	length(List, Length, Length) :-
 | 
						|
		unify_with_occurs_check(List, Back-Back).
 | 
						|
 | 
						|
	length(List-Back, Acc, Length) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [_| Tail],
 | 
						|
		Acc2 is Acc + 1,
 | 
						|
		length(Tail-Back, Acc2, Length).
 | 
						|
 | 
						|
 | 
						|
	make_list(0, List):-
 | 
						|
		!,
 | 
						|
		unify_with_occurs_check(List, Back-Back).
 | 
						|
 | 
						|
	make_list(N, List-Back):-
 | 
						|
		List \== Back,
 | 
						|
		List = [_| Tail],
 | 
						|
		M is N-1,
 | 
						|
		make_list(M, Tail-Back).
 | 
						|
 | 
						|
 | 
						|
	max(List-Back, Max) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		max(Tail-Back, Head, Max).
 | 
						|
 | 
						|
 | 
						|
	max(List-Back, Max, Max) :-
 | 
						|
		List == Back, !.
 | 
						|
 | 
						|
	max(List-Back, Aux, Max) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		(Aux @< Head ->
 | 
						|
			max(Tail-Back, Head, Max)
 | 
						|
			;
 | 
						|
			max(Tail-Back, Aux, Max)).
 | 
						|
 | 
						|
 | 
						|
	member(Element, List-Back) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Element|_].
 | 
						|
 | 
						|
	member(Element, List-Back) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [_| Tail],
 | 
						|
		member(Element, Tail-Back).
 | 
						|
 | 
						|
 | 
						|
	memberchk(Element, List) :-
 | 
						|
		once(member(Element, List)).
 | 
						|
 | 
						|
 | 
						|
	nth(Position, List, Element) :-
 | 
						|
		nth(Element, List, 1, Position).
 | 
						|
 | 
						|
 | 
						|
	nth(Element, List-Back, Position, Position) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Element| _].
 | 
						|
 | 
						|
	nth(Element, List-Back, Count, Position) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [_| Tail],
 | 
						|
		Count2 is Count + 1,
 | 
						|
		nth(Element, Tail-Back, Count2, Position).
 | 
						|
 | 
						|
 | 
						|
	min(List-Back, Min) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		min(Tail-Back, Head, Min).
 | 
						|
 | 
						|
 | 
						|
	min(List-Back, Min, Min) :-
 | 
						|
		List == Back, !.
 | 
						|
 | 
						|
	min(List-Back, Aux, Min) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		(Head @< Aux ->
 | 
						|
			min(Tail-Back, Head, Min)
 | 
						|
			;
 | 
						|
			min(Tail-Back, Aux, Min)).
 | 
						|
 | 
						|
 | 
						|
	new(List) :-
 | 
						|
		unify_with_occurs_check(List, Back-Back).
 | 
						|
 | 
						|
 | 
						|
	permutation(List, Permutation) :-
 | 
						|
		same_length(List, Permutation),
 | 
						|
		permutation2(List, Permutation).
 | 
						|
 | 
						|
 | 
						|
	permutation2(List1-Back1, List2-Back2) :-
 | 
						|
		List1 == Back1,
 | 
						|
		List2 == Back2.
 | 
						|
 | 
						|
	permutation2(List1-Back1, List2-Back2) :-
 | 
						|
		List2 \== Back2,
 | 
						|
		List2 = [Head2| Tail2],
 | 
						|
		select(Head2, List1-Back1, Tail1-Back1),
 | 
						|
		permutation2(Tail1-Back1, Tail2-Back2).
 | 
						|
 | 
						|
 | 
						|
	prefix(List, _) :-
 | 
						|
		unify_with_occurs_check(List, Back-Back).
 | 
						|
 | 
						|
	prefix(List-Back, List2-Back2) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		List2 \== Back2,
 | 
						|
		List2 = [Head| Tail2],
 | 
						|
		prefix(Tail-Back, Tail2-Back2).
 | 
						|
 | 
						|
 | 
						|
	reverse(List-Back, Reversed-Back) :-
 | 
						|
		same_length(List-Back, Reversed-Back),
 | 
						|
		reverse(List-Back, Back-Back, Reversed-Back).
 | 
						|
 | 
						|
 | 
						|
	reverse(List-Back, Reversed, Reversed) :-
 | 
						|
		List == Back.
 | 
						|
 | 
						|
	reverse(List-Back, Acc-Back, Reversed) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		reverse(Tail-Back, [Head| Acc]-Back, Reversed).
 | 
						|
 | 
						|
 | 
						|
	same_length(List1, List2) :-
 | 
						|
		unify_with_occurs_check(List1, Back1-Back1),
 | 
						|
		unify_with_occurs_check(List2, Back2-Back2).
 | 
						|
 | 
						|
	same_length(List1-Back1, List2-Back2) :-
 | 
						|
		List1 \== Back1,
 | 
						|
		List1 = [_| Tail1],
 | 
						|
		List2 \== Back2,
 | 
						|
		List2 = [_| Tail2],
 | 
						|
		same_length(Tail1-Back1, Tail2-Back2).
 | 
						|
 | 
						|
 | 
						|
	select(Head, List-Back, Tail-Back) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail].
 | 
						|
 | 
						|
	select(Head, List-Back, List2-Back) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Other| Tail],
 | 
						|
		List2 \== Back,
 | 
						|
		List2 = [Other| Tail2],
 | 
						|
		select(Head, Tail-Back, Tail2-Back).
 | 
						|
 | 
						|
 | 
						|
	sort(Difflist, Sorted) :-
 | 
						|
		as_list(Difflist, List),
 | 
						|
		{sort(List, List2)},
 | 
						|
		list::as_difflist(List2, Sorted).		
 | 
						|
 | 
						|
 | 
						|
	sublist(Sublist, List) :-
 | 
						|
		unify_with_occurs_check(Sublist, List).
 | 
						|
 | 
						|
	sublist(Sublist-Back, List-Back):-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		sublist(Tail-Back, Head, Sublist-Back).
 | 
						|
 | 
						|
 | 
						|
	sublist(List, _, Sublist) :-
 | 
						|
		unify_with_occurs_check(List, Sublist).
 | 
						|
 | 
						|
	sublist(List-Back, _, Sublist-Back):-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		sublist(Tail-Back, Head, Sublist-Back).
 | 
						|
 | 
						|
	sublist(List-Back, Element, [Element| Sublist]-Back):-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		sublist(Tail-Back, Head, Sublist-Back).
 | 
						|
 | 
						|
 | 
						|
	subtract(List-Back, _, Result) :-
 | 
						|
		unify_with_occurs_check(Result, Back-Back),
 | 
						|
		List == Back, !.
 | 
						|
 | 
						|
	subtract(List-Back, Ys, List2-Back) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [Head| Tail],
 | 
						|
		(member(Head, Ys) ->
 | 
						|
			subtract(Tail-Back, Ys, List2-Back)
 | 
						|
			;
 | 
						|
			List2 = [Head| Tail2],
 | 
						|
			subtract(Tail-Back, Ys, Tail2-Back)).
 | 
						|
 | 
						|
 | 
						|
	suffix(Suffix, List) :-
 | 
						|
		unify_with_occurs_check(Suffix, List).
 | 
						|
 | 
						|
	suffix(Suffix-Back, List-Back) :-
 | 
						|
		List \== Back,
 | 
						|
		List = [_| Tail],
 | 
						|
		suffix(Suffix-Back, Tail-Back).
 | 
						|
 | 
						|
 | 
						|
	valid(List) :-
 | 
						|
		nonvar(List),
 | 
						|
		valid2(List).
 | 
						|
 | 
						|
 | 
						|
	valid2(List-Back) :-
 | 
						|
		List == Back,
 | 
						|
		!.
 | 
						|
 | 
						|
	valid2(List-Back) :-
 | 
						|
		nonvar(List),
 | 
						|
		List = [_| Tail],
 | 
						|
		valid2(Tail-Back).
 | 
						|
 | 
						|
 | 
						|
:- end_object.
 |