private string GeneratePredicateHelper(BDD pred)
{
string res;
//generate a predicate depending on how complex the condition is
if (!predicate_cache.TryGetValue(pred, out res))
{
if (pred.IsLeaf)
{
if (pred.IsEmpty)
res = "false";
else if (pred.IsFull)
res = "true";
else
throw new AutomataException(AutomataExceptionKind.UnexpectedMTBDDTerminal);
}
else
{
//if there is a single node in the BDD then
//just inline the corresponding bit mask operation
if (pred.One.IsLeaf && pred.Zero.IsLeaf)
res = string.Format("c & 0x{0:X} {1} 0", 1 << pred.Ordinal, (pred.One.IsFull ? "!=" : "=="));
else
{
var ranges = pred.ToRanges();
if (ranges.Length <= 3)
{
res = RangesToCode(ranges);
}
else
{
//generate a method for checking this condition
StringBuilder helper_method = new StringBuilder();
//create a new method for this predicate
int methid = helper_predicates.Count;
helper_method.Append(String.Format(@"
static bool P{0}(int c)
{{
return ", methid));
helper_method.Append(RangesToCode(ranges));
helper_method.Append(@";
}");
helper_predicates.Add(helper_method.ToString());
res = string.Format("P{0}(c)", methid);
}
}
}
predicate_cache[pred] = res;
}
return res;
}