private void ExecuteForeignPredicate(AbstractMachineState state)
{
Assembly loadedAssembly = Assembly.LoadFrom(_assemblyName);
Type[] types = loadedAssembly.GetTypes();
AMForeignPredicate fp = state.GetForeignPredicate(_predicateName);
if (fp == null)
{
throw new Exception("INTERNAL ERROR: cannot find foreign predicate " + _predicateName);
}
foreach (Type type in types)
{
if (type.Name == _classType)
{
foreach (MethodInfo mi in type.GetMethods())
{
if (mi.Name == _methodName)
{
if (mi.ReturnType == typeof(bool))
{
fp.ReturnType = AMForeignPredicate.R_BOOL;
}
else
{
fp.ReturnType = AMForeignPredicate.R_VOID;
}
bool foreignMethodResult = InvokeForeignPredicate(type, mi, fp, loadedAssembly, state);
// bool, fail = !foreignMethodResult (if fail, backtrack, else P++)
// internal, (if fail, backtrack, else P++)
// void, if fail backtrack, else P++
if (fp.ReturnType == AMForeignPredicate.R_BOOL)
{
state.Fail = !foreignMethodResult;
}
else if (fp.ReturnType == AMForeignPredicate.R_VOID)
{
((AMProgram)state.Program).Next();
return;
}
if (state.Fail)
{
state.Backtrack();
}
else
{
((AMProgram)state.Program).Next();
}
}
}
}
}
}