package org.overture.codegen.vdm2jml.runtime;
import java.util.Collection;
import java.util.HashSet;
import org.overture.codegen.runtime.SeqUtil;
import org.overture.codegen.runtime.Tuple;
import org.overture.codegen.runtime.VDMMap;
import org.overture.codegen.runtime.VDMSeq;
import org.overture.codegen.runtime.VDMSet;
/**
* Runtime library used by the Java Modeling Language (JML) generator, which translates VDM-SL models into JML annotated
* Java. The JML annotations generated by the VDM-SL to Java/JML generator uses the methods in this class.
*
* @author pvj
*/
public class V2J
{
/* @ pure @ */
/* @ helper @ */
public static boolean isMap(Object subject)
{
return subject instanceof VDMMap;
}
/* @ pure @ */
/* @ helper @ */
public static boolean isInjMap(Object subject)
{
if (subject instanceof VDMMap)
{
VDMMap map = (VDMMap) subject;
@SuppressWarnings("unchecked")
HashSet<Object> values = new HashSet<>(map.values());
return map.keySet().size() == values.size();
} else
{
return false;
}
}
/* @ pure @ */
/* @ helper @ */
public static boolean isSet(Object subject)
{
return subject instanceof VDMSet;
}
/* @ pure @ */
/* @ helper @ */
public static boolean isSeq(Object subject)
{
return subject instanceof VDMSeq;
}
/* @ pure @ */
/* @ helper @ */
public static boolean isSeq1(Object subject)
{
if (subject instanceof VDMSeq)
{
VDMSeq seq = (VDMSeq) subject;
return !seq.isEmpty();
} else
{
return false;
}
}
/* @ pure @ */
/* @ helper @ */
public static boolean isTup(Object subject, int size)
{
if (subject instanceof Tuple)
{
Tuple t = (Tuple) subject;
return t.size() == size;
} else
{
return false;
}
}
/* @ pure @ */
/* @ helper @ */
public static Object field(Object subject, int fieldNo)
{
if (subject instanceof Tuple)
{
Tuple tuple = (Tuple) subject;
return tuple.get(fieldNo);
} else
{
throw new IllegalArgumentException("Method is only supported for "
+ Tuple.class);
}
}
/* @ pure @ */
/* @ helper @ */
public static Object get(Object col, int index)
{
if (col instanceof VDMSeq)
{
VDMSeq seq = (VDMSeq) col;
return seq.get(index);
} else if (col instanceof VDMSet)
{
VDMSeq seq = set2seq(col);
return seq.get(index);
}
throw new IllegalArgumentException("Method is only supported for "
+ VDMSeq.class + " and " + VDMSet.class);
}
/* @ pure @ */
/* @ helper @ */
@SuppressWarnings("unchecked")
public static Object getDom(Object subject, int index)
{
if (subject instanceof VDMMap)
{
VDMMap map = (VDMMap) subject;
// http://stackoverflow.com/questions/2923856/is-the-order-guaranteed-for-the-return-of-keys-and-values-from-a-linkedhashmap-o
VDMSeq seq = SeqUtil.seq();
seq.addAll(map.keySet());
return seq.get(index);
}
throw new IllegalArgumentException("Method is only supported for "
+ VDMMap.class);
}
/* @ pure @ */
/* @ helper @ */
@SuppressWarnings("unchecked")
public static Object getRng(Object subject, int index)
{
if (subject instanceof VDMMap)
{
VDMMap map = (VDMMap) subject;
VDMSeq seq = SeqUtil.seq();
seq.addAll(map.values());
return seq.get(index);
}
throw new IllegalArgumentException("Method is only supported for "
+ VDMMap.class);
}
/* @ pure @ */
/* @ helper @ */
public static int size(Object vdmCol)
{
// Covers sequences and sets
if (vdmCol instanceof Collection)
{
Collection<?> setSeq = (Collection<?>) vdmCol;
return setSeq.size();
}
// Covers maps
if (vdmCol instanceof VDMMap)
{
VDMMap map = (VDMMap) vdmCol;
return map.size();
}
throw new IllegalArgumentException("Method is only supported for "
+ Collection.class + " and " + VDMMap.class);
}
/* @ pure @ */
/* @ helper @ */
@SuppressWarnings("unchecked")
public static VDMSeq set2seq(Object set)
{
if (set instanceof VDMSet)
{
VDMSeq seq = SeqUtil.seq();
seq.addAll((VDMSet) set);
return seq;
}
throw new IllegalArgumentException("Method is only supported for "
+ VDMSet.class);
}
}