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; }
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); }
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(); } }
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); }
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); }
/// <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); }
/// <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; } }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
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 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; }
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; }
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; }
/// <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; }
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); }