コード例 #1
0
ファイル: KnowledgeBase.cs プロジェクト: mantoun/MKULTRA
        IEnumerable <CutState> CallPrimitive(Symbol functor, PrologPrimitives.PrimitiveImplementation handler, object[] args, PrologContext context)
        {
            if (Trace)
            {
                context.TraceOutput("Goal: {0}", new Structure(functor, args));
            }
            foreach (var state in handler(args, context))
            {
                if (Trace)
                {
                    context.TraceOutput((state == CutState.Continue) ? "Succeed: {0}" : "Cut: {0}", new Structure(functor, args));
                }
                yield return(state);

                if (Trace)
                {
                    context.TraceOutput("Retry: {0}", new Structure(functor, args));
                }
            }
            if (Trace)
            {
                context.TraceOutput("Fail: {0}", new Structure(functor, args));
            }
            context.PopGoalStack();
        }
コード例 #2
0
        private ushort StartCallInstruction(PrologContext context, int framePointer, ref ushort pc, out ushort succeedPC,
                                            out IEnumerator <CutState> iterator)
        {
            int    iteratorRegister = code[pc++];
            ushort failPC           = GetUShort(ref pc);

            succeedPC = GetUShort(ref pc);
            iterator  = null;
            // Make the iterator.  How we do this depends on the opcode, so re-fetch it.
            switch ((Opcode)code[pc - CallTargetOffset])
            {
            case Opcode.CallWokenGoals:
            {
                if (context.GoalsHaveWoken)
                {
                    iterator = context.ProveAllWokenGoals().GetEnumerator();
                }
            }
            break;

            case Opcode.Call:
            {
                // It's a user-defined predicate call
                PredicateInfo calledPredicate = GetPredicate(ref pc);
                PushCallArgs(context, framePointer, predicate.Arity, ref pc);
                iterator = calledPredicate.StackCall(context).GetEnumerator();
            }
            break;

            case Opcode.CallPrimitive:
            {
                // It's a primitive call
                PrologPrimitives.PrimitiveImplementation implementation = GetPrimitive(ref pc);
                int arity = code[pc++];
                PushCallArgs(context, framePointer, arity, ref pc);
                iterator =
                    PrologPrimitives.StackCall(implementation, arity, context).GetEnumerator();
            }
            break;

            default:
                Debug.Assert(false, "Bad call opcode");
                break;
            }
            context.SetStack(framePointer, iteratorRegister, iterator);
            return(failPC);
        }
コード例 #3
0
        /// <summary>
        /// Prints the byte code for the rule to System.Console.
        /// </summary>
        public void Disassemble()
        {
            ushort pc = 0;

            while (pc < code.Length)
            {
                var opcode = (Opcode)code[pc++];
                Console.Write("L{0}: {1} ", pc - 1, opcode.ToString());
                switch (opcode)
                {
                case Opcode.MatchStructure:
                {
                    Symbol functor    = GetSymbol(ref pc);
                    int    arity      = code[pc++];
                    int    endofMatch = GetUShort(ref pc);
                    Console.Write("{0}/{1}, L{2}, ", functor.Name, arity, endofMatch);
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.MatchVar:
                case Opcode.MatchVarFirst:
                {
                    if (opcode == Opcode.MatchVarFirst)
                    {
                        Console.Write("{0}, ", GetSymbol(ref pc));
                    }
                    byte register = code[pc++];
                    Console.Write("{0}, ", FormatRegister(register));
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.MatchLiteral:
                {
                    Console.Write(GetLiteral(ref pc));
                    Console.Write(", ");
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.BuildStructure:
                {
                    Console.Write(GetSymbol(ref pc));
                    Console.Write("/{0}, ", code[pc++]);
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.BuildVar:
                {
                    Console.Write(GetSymbol(ref pc));
                    Console.Write(", ");
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.BuildReg:
                {
                    byte reg = code[pc++];
                    Console.Write("{0}, ", FormatRegister(reg));
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.BuildLiteral:
                {
                    Console.Write(GetLiteral(ref pc));
                    DisassembleOperand(ref pc);
                }
                break;

                case Opcode.Call:
                case Opcode.CallPrimitive:
                case Opcode.CallWokenGoals:
                {
                    Console.Write("{0}", FormatRegister(code[pc++]));
                    Console.Write(", {0}", FormatLabel(GetUShort(ref pc)));
                    Console.Write(", {0}", FormatLabel(GetUShort(ref pc)));
                    if (opcode != Opcode.CallWokenGoals)
                    {
                        int arity;
                        if (opcode == Opcode.Call)
                        {
                            PredicateInfo p = GetPredicate(ref pc);
                            Console.Write(", {0}/{1}", p.Name, p.Arity);
                            arity = p.Arity;
                        }
                        else
                        {
                            PrologPrimitives.PrimitiveImplementation impl = GetPrimitive(ref pc);
                            arity = code[pc++];
                            Console.Write(", {0}/{1}", PrologPrimitives.PrimitiveName(impl), arity);
                        }
                        while (arity-- > 0)
                        {
                            Console.Write(", ");
                            int arg = code[pc++];
                            if (arg < 0x80)
                            {
                                Console.Write("{0}", FormatRegister(arg));         // It's a register
                            }
                            else
                            {
                                // It's a literal
                                arg = ((arg & 0x7f) << 8) + code[pc++];
                                Console.Write(GlobalLiteralTable[arg]);
                            }
                        }
                    }
                }
                break;

                default:
                    throw new Exception("Unknown opcode " + opcode);
                }
                Console.WriteLine();
            }
        }