示例#1
0
        public bool SetVariable(ILiteral variable)
        {
            // Mark the variable as used
            _usedVariables.Add(_indexForVariable[variable]);

            // Create a new reference
            IReferenceLiteral newReference;

            // Add to the current structure
            if (_lastArgument != null)
            {
                // The last argument is the reference
                newReference  = _lastArgument;
                _lastArgument = _lastArgument.NextArgument;
            }
            else
            {
                newReference = new SimpleReference();
            }

            // Store in the variable
            _addressForName[variable].SetTo(newReference);

            return(true);
        }
 public ByteCodeEnvironment(int numVariables, int numArguments, ByteCodeEnvironment continuationEnvironment)
 {
     Variables = new SimpleReference[numVariables];
     NumberOfArguments = numArguments;
     for (var x=0; x<numVariables; ++x)
     {
         Variables[x] = new SimpleReference();
     }
     ContinuationEnvironment = continuationEnvironment;
     ContinuationPointer = -1;
 }
示例#3
0
        public bool GetStructure(ILiteral termName, int termLength, ILiteral variable)
        {
            // This variable becomes used
            _usedVariables.Add(_indexForVariable[variable]);

            // Get the dereferenced address of the variable
            var heapValue = _addressForName[variable].Dereference();

            // Action depends on what's at that address
            if (heapValue.IsVariable())
            {
                // Variable is an unbound ref cell: bind it to a new value that we create
                ArgumentReference firstArgument = null;

                for (int argNum = 0; argNum < termLength; ++argNum)
                {
                    var newArgument = new ArgumentReference(null, firstArgument);
                    firstArgument = newArgument;
                }

                var newStructure = new SimpleReference(termName, firstArgument);
                _lastArgument = firstArgument;
                _structurePtr = firstArgument;

                Bind(heapValue, newStructure);
                _writeMode = true;
            }
            else if (!heapValue.IsReference())
            {
                if (Equals(heapValue.Term, termName))
                {
                    // Set the structure pointer, and use read mode
                    _structurePtr = heapValue.Reference;
                    _writeMode    = false;
                }
                else
                {
                    // Structure doesn't match; fail
                    return(false);
                }
            }
            else
            {
                // Fail
                return(false);
            }

            return(true);
        }
示例#4
0
        public ByteCodeExecutor(ByteCodePoint[] program, ILiteral[] literals, int maxVariableIndex)
        {
            if (program == null) throw new ArgumentNullException(nameof(program));

            _program        = program;
            _literals       = literals;
            _programCounter = 0;
            _environment    = new ByteCodeEnvironment(0, 0, null);
            _registers      = new SimpleReference[maxVariableIndex];

            for (var registerIndex = 0; registerIndex<_registers.Length; ++registerIndex)
            {
                _registers[registerIndex] = new SimpleReference();
            }
        }
示例#5
0
        public bool PutVariable(ILiteral variable1, ILiteral variable2)
        {
            _usedVariables.Add(_indexForVariable[variable1]);
            _usedVariables.Add(_indexForVariable[variable2]);

            var newValue = new SimpleReference();

            // Store in the variables
            _addressForName[variable1].SetTo(newValue);
            _addressForName[variable2].SetTo(newValue);

            // Store to the current structure
            if (_lastArgument != null)
            {
                _lastArgument.SetTo(newValue);
                _lastArgument = _lastArgument.NextArgument;
            }

            return(true);
        }
示例#6
0
        public bool PutStructure(ILiteral termName, int termLength, ILiteral variable)
        {
            // Mark this variable as used
            _usedVariables.Add(_indexForVariable[variable]);

            // Create the structure
            ArgumentReference firstArgument = null;

            for (int argNum = 0; argNum < termLength; ++argNum)
            {
                var newArgument = new ArgumentReference(null, firstArgument);
                firstArgument = newArgument;
            }

            var structure = new SimpleReference(termName, firstArgument);

            _lastArgument = firstArgument;

            // Store in the variable
            _addressForName[variable].SetTo(structure);

            return(true);
        }
示例#7
0
        /// <summary>
        /// Cretes a new reference and stores it in the current structure and a particular variable
        /// </summary>
        private void SetVariable(int variable)
        {
            // Create a new reference
            IReferenceLiteral newReference;

            // Add to the current structure
            if (_lastArgument != null)
            {
                // The last argument is the reference
                newReference = _lastArgument;
                _lastArgument = _lastArgument.NextArgument;
            }
            else
            {
                newReference = new SimpleReference();
            }

            // Store in the variable
            _registers[variable].SetTo(newReference);
        }
示例#8
0
        /// <summary>
        /// Stores a new reference in two variables and the current structure
        /// </summary>
        private void PutVariable(int variable, int argument)
        {
            var newValue = new SimpleReference();

            // Store in the variables
            _registers[variable].SetTo(newValue);
            _registers[argument].SetTo(newValue);

            // Store to the current structure
            if (_lastArgument != null)
            {
                _lastArgument.SetTo(newValue);
                _lastArgument = _lastArgument.NextArgument;
            }
        }
示例#9
0
        /// <summary>
        /// Generates a new empty structure of a particular length on the heap and stores a reference
        /// to it in a variable
        /// </summary>
        private void PutStructure(int termLiteral, int variable, int termLength)
        {
            var termName = _literals[termLiteral];

            // Create the structure
            ArgumentReference firstArgument = null;

            for (int argNum = 0; argNum < termLength; ++argNum)
            {
                var newArgument = new ArgumentReference(null, firstArgument);
                firstArgument = newArgument;
            }

            var structure = new SimpleReference(termName, firstArgument);

            _lastArgument = firstArgument;

            // Store in the variable
            _registers[variable].SetTo(structure);
        }
示例#10
0
        /// <summary>
        /// Either begins unifying against an existing structure (if the variable is bound) or
        /// begins writing a new structure to an unbound variable.
        /// </summary>
        private bool GetStructure(int literal, int variable, int termLength)
        {
            var termName = _literals[literal];

            // Get the dereferenced address of the variable
            var heapValue = _registers[variable].Dereference();

            // Action depends on what's at that address
            if (heapValue.IsVariable())
            {
                // Variable is an unbound ref cell: bind it to a new value that we create
                ArgumentReference firstArgument = null;

                for (int argNum = 0; argNum < termLength; ++argNum)
                {
                    var newArgument = new ArgumentReference(null, firstArgument);
                    firstArgument = newArgument;
                }

                var newStructure = new SimpleReference(termName, firstArgument);
                _lastArgument = firstArgument;
                _structurePtr = firstArgument;

                Bind(heapValue, newStructure);
                _writeMode = true;
            }
            else if (!heapValue.IsReference())
            {
                if (Equals(heapValue.Term, termName))
                {
                    // Set the structure pointer, and use read mode
                    _structurePtr = heapValue.Reference;
                    _writeMode = false;
                }
                else
                {
                    // Structure doesn't match; fail
                    return false;
                }
            }
            else
            {
                // Fail
                return false;
            }

            return true;
        }
示例#11
0
        /// <summary>
        /// Deallocates the last allocated block, restoring the permanent variables from the preceding environment
        /// </summary>
        private void Deallocate()
        {
            var oldEnvironment = _environment.ContinuationEnvironment;
            if (oldEnvironment == null) return;

            // Restore any permanent variables from the new environment
            for (var varIndex = 0; varIndex < oldEnvironment.Variables.Length; ++varIndex)
            {
                _registers[varIndex] = oldEnvironment.Variables[varIndex];
            }

            // Reallocate any temporary variables that have newly appeared
            for (var varIndex = oldEnvironment.Variables.Length; varIndex < _environment.Variables.Length; ++varIndex)
            {
                _registers[varIndex] = new SimpleReference();
            }

            // Finally, restore the environment
            _environment = oldEnvironment;
        }
示例#12
0
        /// <summary>
        /// Allocates space for a number of permanent and argument variables.
        /// </summary>
        /// <remarks>
        /// Permanent variables are stored in the environment and are numbered from 0.
        /// Arguments occur after the temporary variables and have their values preserved
        /// from the previous state by this call.
        /// </remarks>
        private void Allocate(int numPermanent, int numArguments)
        {
            // Allocate a new environment
            var newEnvironment = new ByteCodeEnvironment(numPermanent, numArguments, _environment);
            newEnvironment.ContinuationEnvironment = _environment;

            // Make sure that we don't overwrite arguments in the previous environment by replacing them with new temporary variables
            if (numPermanent + numArguments < _environment.Variables.Length)
            {
                for (int oldPermanent = numPermanent + numArguments; oldPermanent < _environment.Variables.Length; ++oldPermanent)
                {
                    _registers[oldPermanent] = new SimpleReference();
                }
            }

            // Move arguments to their new position
            int oldArgStart = _environment.Variables.Length;

            if (oldArgStart > numPermanent)
            {
                // Moving arguments 'down', leaving a hole
                for (int argument = 0; argument < numArguments; ++argument)
                {
                    _registers[argument + numPermanent] = _registers[argument + oldArgStart];
                    _registers[argument + oldArgStart] = new SimpleReference();
                }
            }
            else if (oldArgStart < numPermanent)
            {
                // Moving arguments 'up', old locations will be overwritten by new permanent variables
                for (int argument = numArguments-1; argument >=0; --argument)
                {
                    _registers[argument + numPermanent] = _registers[argument + oldArgStart];
                }
            }

            // Copy in the new permanent variables
            for (int permanent = 0; permanent < numPermanent; ++permanent)
            {
                _registers[permanent] = newEnvironment.Variables[permanent];
            }

            _environment = newEnvironment;
        }
示例#13
0
        public bool SetVariable(ILiteral variable)
        {
            // Mark the variable as used
            _usedVariables.Add(_indexForVariable[variable]);

            // Create a new reference
            IReferenceLiteral newReference;

            // Add to the current structure
            if (_lastArgument != null)
            {
                // The last argument is the reference
                newReference = _lastArgument;
                _lastArgument = _lastArgument.NextArgument;
            }
            else
            {
                newReference = new SimpleReference();
            }

            // Store in the variable
            _addressForName[variable].SetTo(newReference);

            return true;
        }
示例#14
0
        public bool PutVariable(ILiteral variable1, ILiteral variable2)
        {
            _usedVariables.Add(_indexForVariable[variable1]);
            _usedVariables.Add(_indexForVariable[variable2]);

            var newValue = new SimpleReference();

            // Store in the variables
            _addressForName[variable1].SetTo(newValue);
            _addressForName[variable2].SetTo(newValue);

            // Store to the current structure
            if (_lastArgument != null)
            {
                _lastArgument.SetTo(newValue);
                _lastArgument = _lastArgument.NextArgument;
            }

            return true;
        }
示例#15
0
        public bool PutStructure(ILiteral termName, int termLength, ILiteral variable)
        {
            // Mark this variable as used
            _usedVariables.Add(_indexForVariable[variable]);

            // Create the structure
            ArgumentReference firstArgument = null;

            for (int argNum = 0; argNum < termLength; ++argNum)
            {
                var newArgument = new ArgumentReference(null, firstArgument);
                firstArgument = newArgument;
            }

            var structure = new SimpleReference(termName, firstArgument);

            _lastArgument = firstArgument;

            // Store in the variable
            _addressForName[variable].SetTo(structure);

            return true;
        }
示例#16
0
        public bool GetStructure(ILiteral termName, int termLength, ILiteral variable)
        {
            // This variable becomes used
            _usedVariables.Add(_indexForVariable[variable]);

            // Get the dereferenced address of the variable
            var heapValue = _addressForName[variable].Dereference();

            // Action depends on what's at that address
            if (heapValue.IsVariable())
            {
                // Variable is an unbound ref cell: bind it to a new value that we create
                ArgumentReference firstArgument = null;

                for (int argNum = 0; argNum < termLength; ++argNum)
                {
                    var newArgument = new ArgumentReference(null, firstArgument);
                    firstArgument = newArgument;
                }

                var newStructure = new SimpleReference(termName, firstArgument);
                _lastArgument = firstArgument;
                _structurePtr = firstArgument;

                Bind(heapValue, newStructure);
                _writeMode = true;
            }
            else if (!heapValue.IsReference())
            {
                if (Equals(heapValue.Term, termName))
                {
                    // Set the structure pointer, and use read mode
                    _structurePtr = heapValue.Reference;
                    _writeMode = false;
                }
                else
                {
                    // Structure doesn't match; fail
                    return false;
                }
            }
            else
            {
                // Fail
                return false;
            }

            return true;
        }
示例#17
0
        /// <summary>
        /// Backtracks to the current choice point
        /// </summary>
        public void BacktrackToChoicePoint()
        {
            // Restore the environment permanent variables
            if (!ReferenceEquals(_choicePoint.Environment, _environment))
            {
                for (var varIndex = 0; varIndex < _choicePoint.Environment.Variables.Length; ++varIndex)
                {
                    _registers[varIndex] = _choicePoint.Environment.Variables[varIndex];
                }

                for (var varIndex = _choicePoint.Environment.Variables.Length; varIndex < _environment.Variables.Length; ++varIndex)
                {
                    _registers[varIndex] = new SimpleReference();
                }
            }

            // Restore the argument registers
            var argumentIndex = _choicePoint.Environment.Variables.Length;
            foreach (var argument in _choicePoint.Arguments)
            {
                _registers[argumentIndex].SetTo(argument);
                ++argumentIndex;
            }

            // Environment is reset to the choice point environment
            _environment = _choicePoint.Environment;

            // Reset the trail
            _choicePoint.Trail.Reset();
            _trail = _choicePoint.Trail;
        }
示例#18
0
        public async Task SolveSimplePredicate()
        {
            // Knowledge is a(x)
            var a = Literal.NewFunctor(1);
            var x = Literal.NewAtom();
            var aOfX = a.With(x);

            var knowledge = KnowledgeBase.New().Assert(Clause.Always(aOfX));

            // Generate a bytecode solver for this
            var solver = new ByteCodeSolver();
            await solver.Compile(knowledge);

            // Call it with the query a(Y)
            var refToY = new SimpleReference();

            var solve = solver.Call(a, refToY);

            var solved = solve();
            Assert.IsTrue(solved);
            Assert.AreEqual(x, refToY.Term);
        }