package dfatool.operations;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;


public class SetOperations {

	
	public static <T> Set<T> union(Set<T> s1, Set<T> s2){
		Set<T> s = new HashSet<T>(s1);
		s.addAll(s2);
		return s; 
	}
	
	public static <T> Set<T> inter(Set<T> s1, Set<T> s2){
		Set<T> setW = new HashSet<T>(s1);
		for(T v : s1){
			if(!s2.contains(v)) setW.remove(v);
		}
		return setW;
	}
	
	public static <T> boolean isMember(T v, Set<T> s){
		return s.contains(v);
	}
	
	public static <T> Set<T> diff(Set<T> s1, Set<T> s2){
		Set<T> setW = new HashSet<T>(s1);
		for(T v : s1){
			if(isMember(v, s2)) setW.remove(v);
		}
		return setW;
	}
	
	public static <T> Set<List<T>> caculateCartesianProduct(List<Set<T>> listOfSets){
		Set<List<T>> s = new HashSet<List<T>>();
		getTuples(s, new ArrayList<T>(), listOfSets);
		return s;
	}
	
	private static <T> void getTuples(Set<List<T>> s, List<T> t, List<Set<T>> l){
		if(l.size() == 0){
			s.add(t); 
			return;
		}
		List<Set<T>> l2 = new LinkedList<Set<T>>(l);
		l2.remove(0);
		for(T e : l.get(0)){
			List<T> tt = new ArrayList<T>(t);
			tt.add(e);
			getTuples(s, tt , l2);
		}
	}
	

}
