示例#1
0
        ExecutionResults OnGetStructure(WamInstruction instruction)
        {
            var sourceReference    = GetRegister(instruction.SourceRegister).Dereference();
            var sourceVariable     = sourceReference as WamVariable;
            var sourceCompoundTerm = sourceReference as WamCompoundTerm;

            // Ensure target is either a variable or compound term.
            //
            Debug.Assert(sourceVariable != null || sourceCompoundTerm != null);

            if (sourceVariable != null)
            {
                var compoundTerm = WamCompoundTerm.Create(instruction.Functor);
                Bind(sourceVariable, compoundTerm);

                CurrentStructure      = compoundTerm;
                CurrentStructureIndex = -1;
                CurrentUnifyMode      = UnifyModes.Write;
            }
            else // targetCompoundTerm != null
            {
                if (sourceCompoundTerm.Functor != instruction.Functor)
                {
                    return(ExecutionResults.Backtrack);
                }

                CurrentStructure      = sourceCompoundTerm;
                CurrentStructureIndex = -1;
                CurrentUnifyMode      = UnifyModes.Read;
            }
            InstructionPointer = InstructionPointer.GetNext();
            return(ExecutionResults.None);
        }
示例#2
0
        public static WamReferenceTarget Create(IEnumerable <WamReferenceTarget> items)
        {
            WamCompoundTerm result = null;

            // Iterate through collection and add each item to the list.
            //
            WamCompoundTerm currentListItem = null;

            foreach (var item in items)
            {
                if (currentListItem == null)
                {
                    result          = WamCompoundTerm.Create(Functor.ListFunctor);
                    currentListItem = result;
                }
                else
                {
                    currentListItem.Children[1] = WamCompoundTerm.Create(Functor.ListFunctor);
                    currentListItem             = (WamCompoundTerm)(currentListItem.Children[1]);
                }
                currentListItem.Children[0] = item;
            }
            if (currentListItem != null)
            {
                currentListItem.Children[1] = WamCompoundTerm.Create(Functor.NilFunctor);
            }

            // If there were no items, create a nil list.
            //
            return(result ?? WamCompoundTerm.Create(Functor.NilFunctor));
        }
        public static void Eval(WamMachine machine, WamReferenceTarget[] arguments)
        {
            Debug.Assert(arguments.Length == 1);

            WamReferenceTarget expression = arguments[0].Dereference();

            WamCompoundTerm compoundTerm = expression as WamCompoundTerm;

            if (compoundTerm == null)
            {
                return;
            }

            WamInstructionStreamBuilder builder = new WamInstructionStreamBuilder();

            builder.Write(new WamInstruction(WamInstructionOpCodes.Allocate));
            for (int idx = 0; idx < compoundTerm.Functor.Arity; ++idx)
            {
                builder.Write(new WamInstruction(
                                  WamInstructionOpCodes.PutValue,
                                  compoundTerm.Children[idx],
                                  new WamInstructionRegister(WamInstructionRegisterTypes.Argument, (byte)idx)));
            }
            builder.Write(new WamInstruction(WamInstructionOpCodes.Call, compoundTerm.Functor));
            builder.Write(new WamInstruction(WamInstructionOpCodes.Deallocate));
            builder.Write(new WamInstruction(WamInstructionOpCodes.Proceed));

            machine.SetInstructionStream(builder.ToInstructionStream());
        }
示例#4
0
        WamCompoundTerm CreateCompoundTerm(Functor functor)
        {
            var value = WamCompoundTerm.Create(functor);

            CurrentStructure      = value;
            CurrentStructureIndex = -1;
            return(value);
        }
 public override WamReferenceTarget Clone()
 {
     var result = new WamCompoundTerm(Functor);
     for (var index = 0; index < Functor.Arity; ++index)
     {
         result.Children[index] = Children[index].Clone();
     }
     return result;
 }
示例#6
0
        public override WamReferenceTarget Clone()
        {
            var result = new WamCompoundTerm(Functor);

            for (var index = 0; index < Functor.Arity; ++index)
            {
                result.Children[index] = Children[index].Clone();
            }
            return(result);
        }
示例#7
0
        public static WamCompoundTerm Create(CodeCompoundTerm codeCompoundTerm)
        {
            var functor = Functor.Create(codeCompoundTerm.Functor);
            var result  = WamCompoundTerm.Create(functor);

            for (var index = 0; index < functor.Arity; ++index)
            {
                result.Children[index] = WamReferenceTarget.Create(codeCompoundTerm.Children[index]);
            }
            return(result);
        }
        public static bool Compound(WamMachine machine, WamReferenceTarget[] arguments)
        {
            Debug.Assert(arguments.Length == 1);

            WamReferenceTarget wamReferenceTarget = arguments[0].Dereference();

            WamCompoundTerm wamCompoundTerm = wamReferenceTarget as WamCompoundTerm;

            if (wamCompoundTerm != null)
            {
                return(wamCompoundTerm.Functor.Arity > 0);
            }

            return(false);
        }
        public static bool Atomic(WamMachine machine, WamReferenceTarget[] arguments)
        {
            Debug.Assert(arguments.Length == 1);

            WamReferenceTarget wamReferenceTarget = arguments[0].Dereference();

            WamCompoundTerm wamCompoundTerm = wamReferenceTarget as WamCompoundTerm;

            if (wamCompoundTerm != null)
            {
                return(wamCompoundTerm.Functor.Arity == 0);
            }

            return(wamReferenceTarget is WamValueInteger ||
                   wamReferenceTarget is WamValueDouble);
        }
        private static bool IsPartialList(WamReferenceTarget wamReferenceTarget)
        {
            WamCompoundTerm wamCompoundTerm = wamReferenceTarget as WamCompoundTerm;

            if (wamCompoundTerm != null)
            {
                if (wamCompoundTerm.Functor == Functor.ListFunctor)
                {
                    WamReferenceTarget tail = wamCompoundTerm.Children[1].Dereference();

                    return(tail is WamVariable ||
                           IsPartialList(tail));
                }
            }

            return(false);
        }
示例#11
0
        public static WamReferenceTarget Create(CodeTerm codeTerm)
        {
            if (codeTerm == null)
            {
                throw new ArgumentNullException("codeTerm");
            }
            var codeValue = codeTerm as CodeValue;

            if (codeValue != null)
            {
                return(WamValue.Create(codeValue));
            }
            var codeCompoundTerm = codeTerm as CodeCompoundTerm;

            if (codeCompoundTerm != null)
            {
                return(WamCompoundTerm.Create(codeCompoundTerm));
            }
            throw new ArgumentException("Invalid CodeTerm type.");
        }
        private static bool IsList(WamReferenceTarget wamReferenceTarget)
        {
            WamCompoundTerm wamCompoundTerm = wamReferenceTarget as WamCompoundTerm;

            if (wamCompoundTerm != null)
            {
                if (wamCompoundTerm.Functor == Functor.NilFunctor)
                {
                    return(true);
                }

                if (wamCompoundTerm.Functor == Functor.ListFunctor)
                {
                    WamReferenceTarget tail = wamCompoundTerm.Children[1].Dereference();

                    return(IsList(tail));
                }
            }

            return(false);
        }
示例#13
0
        public static bool FindAll(WamMachine machine, WamReferenceTarget[] arguments)
        {
            Debug.Assert(arguments.Length == 3);

            WamReferenceTarget arg0 = arguments[0].Dereference();
            WamReferenceTarget arg1 = arguments[1].Dereference();
            WamReferenceTarget arg2 = arguments[2].Dereference();

            WamVariable variable = arg0 as WamVariable;

            if (variable == null)
            {
                return(false);
            }

            WamCompoundTerm goal = arg1 as WamCompoundTerm;

            if (goal == null)
            {
                return(false);
            }

            WamVariable result = arg2 as WamVariable;

            if (result == null)
            {
                return(false);
            }

            WamInstructionStreamBuilder builder = new WamInstructionStreamBuilder();

            builder.Write(new WamInstruction(WamInstructionOpCodes.Allocate));
            for (int idx = 0; idx < goal.Functor.Arity; ++idx)
            {
                builder.Write(new WamInstruction(
                                  WamInstructionOpCodes.PutValue,
                                  goal.Children[idx],
                                  new WamInstructionRegister(WamInstructionRegisterTypes.Argument, (byte)idx)));
            }
            builder.Write(new WamInstruction(WamInstructionOpCodes.Call, goal.Functor));
            builder.Write(new WamInstruction(WamInstructionOpCodes.Success));

            machine.PushContext(builder.ToInstructionStream());

            List <WamReferenceTarget> values = new List <WamReferenceTarget>();

            try
            {
                ExecutionResults results = machine.RunToSuccess();
                while (results == ExecutionResults.Success)
                {
                    WamReferenceTarget value = variable.Clone();
                    values.Add(value);

                    results = machine.RunToSuccess();
                }
            }
            finally
            {
                machine.PopContext(true);
            }

            // Unbind the variable from the last results found by the goal.
            //
            variable.Unbind();

            // Unify the output variable with the list of values.
            //
            return(machine.Unify(result, WamReferenceTarget.Create(values)));
        }