/*
* #%~
* VDM Code Generator Runtime
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* 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 3 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 program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.codegen.runtime;
public class SetUtil
{
public static VDMSet set()
{
return new VDMSet();
}
@SuppressWarnings("unchecked")
public static VDMSet set(Object... elements)
{
if (elements == null)
{
throw new IllegalArgumentException("Cannot instantiate set from null");
}
VDMSet set = set();
for (Object element : elements)
{
set.add(element);
}
return set;
}
public static boolean inSet(Object elem, Object set)
{
validateSet(set, "'in set'");
VDMSet vdmSet = (VDMSet) set;
return vdmSet.contains(elem);
}
@SuppressWarnings("unchecked")
public static boolean subset(Object left, Object right)
{
validateSets(left, right, "subset");
VDMSet leftSet = (VDMSet) left;
VDMSet rightSet = (VDMSet) right;
return rightSet.containsAll(leftSet);
}
@SuppressWarnings("unchecked")
public static VDMSet union(Object left, Object right)
{
validateSets(left, right, "set union");
VDMSet leftSet = (VDMSet) left;
VDMSet rightSet = (VDMSet) right;
VDMSet result = new VDMSet();
result.addAll(leftSet);
result.addAll(rightSet);
return result;
}
@SuppressWarnings("unchecked")
public static VDMSet dunion(Object setOfSets)
{
final String DUNION = "distributed union";
validateSet(setOfSets, DUNION);
VDMSet vdmSetOfSets = (VDMSet) setOfSets;
VDMSet result = set();
for (Object set : vdmSetOfSets)
{
validateSet(set, DUNION);
VDMSet vdmSet = (VDMSet) set;
result.addAll(vdmSet);
}
return result;
}
@SuppressWarnings("unchecked")
public static VDMSet dinter(Object setOfSets)
{
final String DINTER = "distributed intersection";
validateSet(setOfSets, DINTER);
VDMSet vdmSetOfSets = (VDMSet) setOfSets;
VDMSet result = dunion(vdmSetOfSets);
for (Object set : vdmSetOfSets)
{
validateSet(set, DINTER);
VDMSet vdmSet = (VDMSet) set;
result.retainAll(vdmSet);
}
return result;
}
@SuppressWarnings("unchecked")
public static VDMSet diff(Object left, Object right)
{
validateSets(left, right, "set difference");
VDMSet setLeft = (VDMSet) left;
VDMSet setRight = (VDMSet) right;
VDMSet result = new VDMSet();
result.addAll(setLeft);
result.removeAll(setRight);
return result;
}
@SuppressWarnings("unchecked")
public static boolean psubset(Object left, Object right)
{
validateSets(left, right, "proper subset");
VDMSet setLeft = (VDMSet) left;
VDMSet setRight = (VDMSet) right;
return setLeft.size() < setRight.size()
&& setRight.containsAll(setLeft);
}
@SuppressWarnings("unchecked")
public static VDMSet intersect(Object left, Object right)
{
validateSets(left, right, "set intersection");
VDMSet setLeft = (VDMSet) left;
VDMSet setRight = (VDMSet) right;
VDMSet result = new VDMSet();
result.addAll(setLeft);
result.retainAll(setRight);
return result;
}
@SuppressWarnings("unchecked")
public static VDMSet powerset(Object originalSet)
{
validateSet(originalSet, "power set");
VDMSet vdmOriginalSet = (VDMSet) originalSet;
VDMSet sets = SetUtil.set();
if (vdmOriginalSet.isEmpty())
{
sets.add(SetUtil.set());
return sets;
}
VDMSeq seq = SeqUtil.seq();
seq.addAll(vdmOriginalSet);
Object firstElement = seq.get(0);
VDMSet rest = SetUtil.set();
rest.addAll(seq.subList(1, seq.size()));
VDMSet powerSets = powerset(rest);
Object[] powerSetsArray = powerSets.toArray();
for (int i = 0; i < powerSets.size(); i++)
{
Object obj = powerSetsArray[i];
if (!(obj instanceof VDMSet))
{
throw new IllegalArgumentException("Powerset operation is only applicable to sets. Got: "
+ obj);
}
VDMSet set = (VDMSet) obj;
VDMSet newSet = SetUtil.set();
newSet.add(firstElement);
newSet.addAll(set);
sets.add(newSet);
sets.add(set);
}
return sets;
}
@SuppressWarnings("unchecked")
public static VDMSet range(Object first, Object last)
{
Utils.validateNumbers(first, last, "set range");
Number firstNumber = (Number) first;
Number lastNumber = (Number) last;
long from = (long) Math.ceil(firstNumber.doubleValue());
long to = (long) Math.floor(lastNumber.doubleValue());
VDMSet result = new VDMSet();
for (long i = from; i <= to; i++)
{
result.add(i);
}
return result;
}
static void validateSet(Object arg, String operator)
{
if (!(arg instanceof VDMSet))
{
throw new IllegalArgumentException(operator
+ " is only supported for " + VDMSet.class.getName()
+ ". Got " + arg);
}
}
private static void validateSets(Object left, Object right, String operator)
{
if (!(left instanceof VDMSet) || !(right instanceof VDMSet))
{
throw new IllegalArgumentException(operator
+ " is only supported for " + VDMSet.class.getName()
+ ". Got " + left + " and " + right);
}
}
}