/// <summary> /// Freezes a literal /// </summary> public static ILiteral Freeze(this IReferenceLiteral literal) { var deref = literal.Dereference(); if (!IsReference(deref)) { var term = deref.Term; var arguments = new List <ILiteral>(); // Freeze the arguments for (var structurePtr = deref.Reference; structurePtr != null; structurePtr = structurePtr.NextArgument) { arguments.Add(structurePtr.Freeze()); } // Rebuild the term with these arguments return(term.RebuildWithParameters(arguments)); } else { // Represents an unbound variable // TODO: re-use the same variable for the same literal address return(new Variable()); } }
public SimpleReference(IReferenceLiteral reference) { if (reference == null) reference = this; Term = null; Reference = reference; }
public ArgumentReference(IReferenceLiteral value, ArgumentReference nextArgument) { if (value == null) value = this; Term = null; Reference = value; NextArgument = nextArgument; }
/// <summary> /// Unifies a value on the heap /// </summary> public static bool Unify(this IReferenceLiteral address1, IReferenceLiteral address2, ITrail trail) { var unifyStack = new Stack<IReferenceLiteral>(); // Push the addresses that we're going to unify unifyStack.Push(address1); unifyStack.Push(address2); // Iterate until the stack is empty while (unifyStack.Count > 0) { // Deref the values on the stack var value1 = unifyStack.Pop().Dereference(); var value2 = unifyStack.Pop().Dereference(); if (!ReferenceEquals(value1, value2)) { if (value1.IsReference()) { // Bind references trail.Record(value1); value1.SetTo(value2); } else if (value2.IsReference()) { trail.Record(value2); value2.SetTo(value1); } else { if (Equals(value1.Term, value2.Term)) { // Process the rest of the structure var structurePos1 = value1.Reference; var structurePos2 = value2.Reference; while (structurePos1 != null) { unifyStack.Push(structurePos1); unifyStack.Push(structurePos2); structurePos1 = structurePos1.NextArgument; structurePos2 = structurePos2.NextArgument; } } else { // Structures do not match: fail return false; } } } } return true; }
/// <summary> /// Unifies a value on the heap /// </summary> public static bool Unify(this IReferenceLiteral address1, IReferenceLiteral address2, ITrail trail) { var unifyStack = new Stack <IReferenceLiteral>(); // Push the addresses that we're going to unify unifyStack.Push(address1); unifyStack.Push(address2); // Iterate until the stack is empty while (unifyStack.Count > 0) { // Deref the values on the stack var value1 = unifyStack.Pop().Dereference(); var value2 = unifyStack.Pop().Dereference(); if (!ReferenceEquals(value1, value2)) { if (value1.IsReference()) { // Bind references trail.Record(value1); value1.SetTo(value2); } else if (value2.IsReference()) { trail.Record(value2); value2.SetTo(value1); } else { if (Equals(value1.Term, value2.Term)) { // Process the rest of the structure var structurePos1 = value1.Reference; var structurePos2 = value2.Reference; while (structurePos1 != null) { unifyStack.Push(structurePos1); unifyStack.Push(structurePos2); structurePos1 = structurePos1.NextArgument; structurePos2 = structurePos2.NextArgument; } } else { // Structures do not match: fail return(false); } } } } return(true); }
public SimpleReference(IReferenceLiteral reference) { if (reference == null) { reference = this; } Term = null; Reference = reference; }
/// <summary> /// Stores the value of a variable in the current structure /// </summary> private void SetValue(int variable) { var variableValue = _registers[variable]; // Store to the current structure if (_lastArgument != null) { _lastArgument.SetTo(variableValue); _lastArgument = _lastArgument.NextArgument; } }
public ArgumentReference(IReferenceLiteral value, ArgumentReference nextArgument) { if (value == null) { value = this; } Term = null; Reference = value; NextArgument = nextArgument; }
/// <summary> /// Dereferences a reference literal, finding the point at which it refers to a structure or /// is self-referential (which means it's an unbound variable) /// </summary> public static IReferenceLiteral Dereference(this IReferenceLiteral literal) { var result = literal; while (IsReference(result) && !IsVariable(result)) { result = result.Reference; } return(result); }
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> /// 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> /// 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> /// Unifies a variable /// </summary> private void UnifyVariable(int variable) { if (!_writeMode) { // Just read the value of the variable into the variable _registers[variable].SetTo(_structurePtr); } else { // Write the value of the variable _registers[variable].SetTo(_lastArgument); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; }
/// <summary> /// In write mode, writes the value of a variable to the current structure. In read mode, /// unifies the value in the current structure with the value of a variable. /// </summary> private bool UnifyValue(int variable) { if (!_writeMode) { if (!_registers[variable].Unify(_structurePtr, _trail)) { return(false); } } else { _lastArgument.SetTo(_registers[variable]); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; return(true); }
public bool UnifyValue(ILiteral variable) { if (!_writeMode) { if (!Unify(_addressForName[variable], _structurePtr)) { return(false); } } else { _lastArgument.SetTo(_addressForName[variable]); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; 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> /// 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); }
public bool UnifyVariable(ILiteral variable) { // This variable becomes used _usedVariables.Add(_indexForVariable[variable]); if (!_writeMode) { // Just read the value of the variable _addressForName[variable].SetTo(_structurePtr); } else { // Write the value of the variable _addressForName[variable].SetTo(_lastArgument); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; return(true); }
/// <summary> /// Unifies a value on the heap /// </summary> private bool Unify(IReferenceLiteral address1, IReferenceLiteral address2) { return address1.Unify(address2, _trails.Peek()); }
/// <summary> /// Unifies a value on the heap /// </summary> private bool Unify(IReferenceLiteral address1, IReferenceLiteral address2) { return(address1.Unify(address2, _trails.Peek())); }
/// <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; }
public void Record(IReferenceLiteral reference) { }
/// <summary> /// Returns true if a literal represents an unbound variable /// </summary> public static bool IsVariable(this IReferenceLiteral literal) { return(IsReference(literal) && ReferenceEquals(literal, literal.Reference)); }
public SimpleReference(ILiteral term, IReferenceLiteral referenceToFirstArgument) { Term = term; Reference = referenceToFirstArgument; }
public void Record(IReferenceLiteral reference) { _toReset.Add(reference); }
public void SetTo(IReferenceLiteral value) { Term = value.Term; Reference = value.Reference; }
/// <summary> /// Prepares to run a new program unifier using this object /// </summary> public void PrepareToRunProgram() { _usedVariables.Clear(); _structurePtr = null; }
/// <summary> /// Binds one value to anoteher /// </summary> private void Bind(IReferenceLiteral target, IReferenceLiteral value) { _trail.Record(target); target.SetTo(value); }
/// <summary> /// Returns true if a literal is a reference, false if it is a term /// </summary> public static bool IsReference(this IReferenceLiteral literal) { return(literal.Term == null); }
public bool UnifyValue(ILiteral variable) { if (!_writeMode) { if (!Unify(_addressForName[variable], _structurePtr)) { return false; } } else { _lastArgument.SetTo(_addressForName[variable]); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; return true; }
public bool UnifyVariable(ILiteral variable) { // This variable becomes used _usedVariables.Add(_indexForVariable[variable]); if (!_writeMode) { // Just read the value of the variable _addressForName[variable].SetTo(_structurePtr); } else { // Write the value of the variable _addressForName[variable].SetTo(_lastArgument); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; return true; }
/// <summary> /// Binds a value to the heap /// </summary> private void Bind(IReferenceLiteral target, IReferenceLiteral value) { target.SetTo(value); _trails.Peek().Record(target); }
/// <summary> /// In write mode, writes the value of a variable to the current structure. In read mode, /// unifies the value in the current structure with the value of a variable. /// </summary> private bool UnifyValue(int variable) { if (!_writeMode) { if (!_registers[variable].Unify(_structurePtr, _trail)) { return false; } } else { _lastArgument.SetTo(_registers[variable]); _lastArgument = _lastArgument.NextArgument; } _structurePtr = _structurePtr.NextArgument; 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; }