public Clause Add(CodeSentence codeSentence) { if (codeSentence == null) { throw new ArgumentNullException("codeSentence"); } if (codeSentence.Head == null) { throw new ArgumentException("Query cannot be added to program.", "codeSentence"); } var functor = Functor.Create(codeSentence.Head.Functor); if (functor == Functor.PragmaFunctor) { ProcessPragma(codeSentence); return(null); } // Find procedure associated with codeSentence. Create a new procedure if necessary. // Procedure procedure; if (!Procedures.TryGetProcedure(functor, out procedure)) { procedure = Procedures.Add(functor); } // Create clause for codeSentence. // var clause = procedure.Clauses.Add(codeSentence); return(clause); }
internal Clause Add(CodeSentence codeSentence) { if (codeSentence == null) { throw new ArgumentNullException("codeSentence"); } if (codeSentence.Head == null) { throw new ArgumentException("Query cannot be added to program.", "codeSentence"); } if (Functor.Create(codeSentence.Head.Functor) != Procedure.Functor) { throw new ArgumentException("Clause not member of procedure.", "codeSentence"); } if (Contains(codeSentence)) { throw new ArgumentException("Item already exists.", "codeSentence"); } Clause clause = new Clause(this, codeSentence); Items.Add(clause); Procedure.InvalidateInstructionStream(); Procedure.InvalidatePosition(); Procedure.Container.Program.Touch(); return(clause); }
void Put(CodeCompoundTerm codeCompoundTerm, WamInstructionRegister targetRegister, LibraryList libraries) { var childrenRegisters = new WamInstructionRegister[codeCompoundTerm.Children.Count]; // Build substructures. // for (var idx = 0; idx < codeCompoundTerm.Children.Count; ++idx) { var child = codeCompoundTerm.Children[idx]; if (child.IsCodeList) { child = ConvertCodeList(child.AsCodeList); } if (child.IsCodeCompoundTerm) { childrenRegisters[idx] = GetNextTemporaryRegister(); Put(child, childrenRegisters[idx], libraries); } } var functor = Functor.Create(codeCompoundTerm.Functor); InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.PutStructure, functor, targetRegister)); for (var idx = 0; idx < codeCompoundTerm.Children.Count; ++idx) { var child = codeCompoundTerm.Children[idx]; if (child.IsCodeList) { child = ConvertCodeList(child.AsCodeList); } if (child.IsCodeVariable) { var variableName = child.AsCodeVariable.Name; var variableRegister = GetRegisterAssignment(variableName); if (variableRegister.IsUnused) { variableRegister = GetNextPermanentRegister(variableName); InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetUnboundVariable, variableRegister)); } else { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetBoundVariable, variableRegister)); } } else if (child.IsCodeCompoundTerm) { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetBoundVariable, childrenRegisters[idx])); } else if (child.IsCodeValue) { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.SetValue, WamValue.Create(child.AsCodeValue))); } else { throw new InvalidOperationException("Unsupported codeTerm type."); } } }
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); }
private void Call(CodeFunctor codeFunctor, LibraryList libraries) { Functor functor = Functor.Create(codeFunctor); if (functor == Functor.CutFunctor) { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.Cut)); } else if (libraries.Contains(functor)) { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.LibraryCall, functor)); } else { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.Call, functor)); } }
public bool Contains(CodeSentence codeSentence) { if (codeSentence == null) { throw new ArgumentNullException("codeSentence"); } if (codeSentence.Head == null) { throw new ArgumentException("Program cannot contain query.", "codeSentence"); } var functor = Functor.Create(codeSentence.Head.Functor); Procedure procedure; if (Procedures.TryGetProcedure(functor, out procedure)) { if (procedure.Clauses.Contains(codeSentence)) { return(true); } } return(false); }
private void Execute(CodeFunctor codeFunctor) { Functor functor = Functor.Create(codeFunctor); InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.Execute, functor)); }
private void Get(CodeCompoundTerm codeCompoundTerm, WamInstructionRegister sourceRegister) { WamInstructionRegister[] childrenRegisters = new WamInstructionRegister[codeCompoundTerm.Children.Count]; InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.GetStructure, sourceRegister, Functor.Create(codeCompoundTerm.Functor))); for (int idx = 0; idx < codeCompoundTerm.Children.Count; ++idx) { CodeTerm child = codeCompoundTerm.Children[idx]; if (child.IsCodeList) { child = ConvertCodeList(child.AsCodeList); } if (child.IsCodeVariable) { string variableName = child.AsCodeVariable.Name; WamInstructionRegister variableRegister = GetRegisterAssignment(variableName); if (variableRegister.IsUnused) { variableRegister = GetNextPermanentRegister(variableName); InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyUnboundVariable, variableRegister)); } else { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyBoundVariable, variableRegister)); } } else if (child.IsCodeCompoundTerm) { childrenRegisters[idx] = GetNextTemporaryRegister(); InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyUnboundVariable, childrenRegisters[idx])); } else if (child.IsCodeValue) { InstructionStreamBuilder.Write(new WamInstruction(WamInstructionOpCodes.UnifyValue, WamValue.Create(child.AsCodeValue))); } else { throw new InvalidOperationException("Unsupported codeTerm type."); } } // Build substructures. // for (int idx = 0; idx < codeCompoundTerm.Children.Count; ++idx) { CodeTerm child = codeCompoundTerm.Children[idx]; if (child.IsCodeList) { child = ConvertCodeList(child.AsCodeList); } if (child.IsCodeCompoundTerm) { Get(child, childrenRegisters[idx]); } } }
public WamInstructionStream Compile(CodeSentence codeSentence, Functor functor, int index, bool isLast, LibraryList libraries, bool optimize) { Initialize(); // When true, indicates we are compiling code for a procedure clause. When false, indicates we // are compiling for an ad hoc query. // bool isClause = (functor != null); if (isClause) { WamInstructionStreamClauseAttribute clauseAttribute = new WamInstructionStreamClauseAttribute( m_instructionStreamBuilder.NextIndex, functor, index); m_instructionStreamBuilder.AddAttribute(clauseAttribute); } if (isClause) { if (isLast) { if (index == 0) { // Procedure only has one clause in it. No retry logic required. } else { TrustMe(); } } else { if (index == 0) { TryMeElse(functor, index + 1); } else { RetryMeElse(functor, index + 1); } } } Allocate(); if (codeSentence.Head != null) { for (int idx = 0; idx < codeSentence.Head.Children.Count; ++idx) { Get(codeSentence.Head.Children[idx], GetArgumentRegister(idx)); } } if (codeSentence.Body.Count > 0) { for (int idxProcedure = 0; idxProcedure < codeSentence.Body.Count; ++idxProcedure) { CodeCompoundTerm codeCompoundTerm = codeSentence.Body[idxProcedure]; for (int idxArgument = 0; idxArgument < codeCompoundTerm.Children.Count; ++idxArgument) { Put(codeCompoundTerm.Children[idxArgument], GetArgumentRegister(idxArgument), libraries); } bool isLastCall = (idxProcedure == codeSentence.Body.Count - 1); if (isClause) { if (isLastCall) { if (optimize && !libraries.Contains(Functor.Create(codeCompoundTerm.Functor)) && codeCompoundTerm.Functor != CodeFunctor.CutFunctor) { Deallocate(); Execute(codeCompoundTerm.Functor); } else { Call(codeCompoundTerm.Functor, libraries); Deallocate(); Proceed(); } } else { Call(codeCompoundTerm.Functor, libraries); } } else // isQuery { Call(codeCompoundTerm.Functor, libraries); if (isLastCall) { Success(); } } } } else // fact { if (isClause) { Deallocate(); Proceed(); } else // isQuery { // No action required. } } return(InstructionStreamBuilder.ToInstructionStream()); }