Beispiel #1
0
		public CGExpr[] PEvalArgs(PEnv pEnv, bool hasDynamicControl) {
			CGExpr[] res = new CGExpr[es.Length];
			for (int i = 0; i < es.Length; i++) {
				res[i] = es[i].PEval(pEnv, hasDynamicControl);
			}
			return res;
		}
Beispiel #2
0
        // Partially evaluate the programList with respect to the given static inputs,
        // producing a new ProgramLines object.
        public ProgramLines PEval(Value[] args, FullCellAddr[] residualInputs)
        {
            PEnv pEnv = new PEnv();

            // Map static input cells to their constant values:
            for (int i = 0; i < args.Length; i++)
            {
                pEnv[inputCells[i]] = CGConst.Make(args[i]);
            }
            ProgramLines residual = new ProgramLines(outputCell, residualInputs);

            // PE-time environment PEnv maps each residual input cell address to the delegate argument:
            for (int i = 0; i < residualInputs.Length; i++)
            {
                FullCellAddr input = residualInputs[i];
                pEnv[input] = new CGCellRef(input, residual.addressToVariable[input]);
            }
            // Process the given function's compute cells in dependency order, output last:
            foreach (ComputeCell ccell in programList)
            {
                ComputeCell rCcell = ccell.PEval(pEnv);
                if (rCcell != null)
                {
                    residual.AddComputeCell(ccell.cellAddr, rCcell);
                }
            }
            residual = residual.PruneZeroUseCells();
            return(residual);
        }
Beispiel #3
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     // When FunctionValue is known, reduce to a CGSdfCall node.
     // Don't actually call the function (even on constant arguments); could loop.
     CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
     if (res[0] is CGValueConst)
     {
         FunctionValue fv = (res[0] as CGValueConst).Value as FunctionValue;
         if (fv != null)
         {
             CGExpr[] args = new CGExpr[fv.args.Length];
             int      j    = 1;
             for (int i = 0; i < args.Length; i++)
             {
                 if (fv.args[i] != ErrorValue.naError)
                 {
                     args[i] = CGConst.Make(fv.args[i]);
                 }
                 else
                 {
                     args[i] = res[j++];
                 }
             }
             return(new CGSdfCall(fv.sdfInfo, args));
         }
         else
         {
             return(new CGError(ErrorValue.argCountError));
         }
     }
     else
     {
         return(new CGApply(res));
     }
 }
Beispiel #4
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			// When FunctionValue is known, reduce to a CGSdfCall node.  
			// Don't actually call the function (even on constant arguments); could loop.
			CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
			if (res[0] is CGValueConst) {
				FunctionValue fv = (res[0] as CGValueConst).Value as FunctionValue;
				if (fv != null) {
					CGExpr[] args = new CGExpr[fv.args.Length];
					int j = 1;
					for (int i = 0; i < args.Length; i++) {
						if (fv.args[i] != ErrorValue.naError) {
							args[i] = CGConst.Make(fv.args[i]);
						}
						else {
							args[i] = res[j++];
						}
					}
					return new CGSdfCall(fv.sdfInfo, args);
				}
				else {
					return new CGError(ErrorValue.argCountError);
				}
			}
			else {
				return new CGApply(res);
			}
		}
Beispiel #5
0
        public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
        {
            List <CGExpr> res = new List <CGExpr>();

            for (int i = 0; i < es.Length; i++)
            {
                CGExpr ri = es[i].PEval(pEnv, hasDynamicControl || res.Count > 0);
                if (ri is CGNumberConst)
                {
                    // A TRUE operand makes the OR true; a FALSE operand can be ignored
                    if ((ri as CGNumberConst).number.value != 0.0)
                    {
                        return(new CGNumberConst(NumberValue.ONE));
                    }
                }
                else
                {
                    res.Add(ri);
                }
            }
            // The residual OR consists of the non-constant operands, if any
            if (res.Count == 0)
            {
                return(new CGNumberConst(NumberValue.ZERO));
            }
            else
            {
                return(new CGOr(res.ToArray()));
            }
        }
        public ProveResult TripleQuery(Term thisTerm, PartListImpl goalList, PEnv environment, PDB db, int level, reportDelegate reportFunction)
        {
            // bagof(Term, ConditionTerm, ReturnList)
            //  PartList goalList = (PartList)goalIn;

            Part collect0 = value((Part)thisTerm.ArgList[0], environment);
            Part subgoal  = value((Part)thisTerm.ArgList[1], environment);
            Part into     = value((Part)thisTerm.ArgList[2], environment);

            Part collect = renameVariables(collect0, level, thisTerm);
            //var newGoal = new Term(subgoal.name, renameVariables(subgoal.ArgList, level, thisTerm));
            Term newGoal = new Term(subgoal.fname, false,
                                    (PartListImpl)renameVariables(((PartListImpl)subgoal), level, thisTerm));

            newGoal.parent = thisTerm;

            //var newGoals = [];
            //newGoals[0] = newGoal;
            PartListImpl newGoals = new PartListImpl();

            newGoals.AddPart(newGoal);

            // Prove this subgoal, collecting up the environments...
            PartListImpl anslist = new PartListImpl();

            anslist.renumber = -1;
            var ret = prove(newGoals, environment, db, level + 1, BagOfCollectFunction(collect, anslist));

            // Turn anslist into a proper list and unify with 'into'

            // optional here: nil anslist -> fail?
            Part answers = Atom.FromSource(FUNCTOR_NIL);

            /*
             * print("Debug: anslist = [");
             *  for (var j = 0; j < anslist.length; j++) {
             *      anslist[j].print();
             *      print(", ");
             *  }
             * print("]\n");
             */

            for (int i = anslist.Arity; i > 0; i--)
            {
                answers = MakeList(anslist.ArgList[i - 1], answers);
            }

            //print("Debug: unifying "); into.print(); print(" with "); answers.print(); print("\n");
            var env2 = unify(into, answers, environment);

            if (env2 == null)
            {
                //print("Debug: bagof cannot unify anslist with "); into.print(); print(", failing\n");
                return(null);
            }

            // Just prove the rest of the goallist, recursively.
            return(prove(goalList, env2, db, level + 1, reportFunction));
        }
Beispiel #7
0
        public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
        {
            CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
            // The static argument positions are those that have args[i] != naError
            Value[] args = new Value[res.Length];
            bool    anyStatic = false, allStatic = true;

            for (int i = 0; i < res.Length; i++)
            {
                if (res[i] is CGConst)
                {
                    args[i]   = (res[i] as CGConst).Value;
                    anyStatic = true;
                }
                else
                {
                    args[i]   = ErrorValue.naError;                   // Generalize to dynamic
                    allStatic = false;
                }
            }
            if (!hasDynamicControl)
            {
                // This would be wrong, because the called function might contain
                // volatile functions and in that case should residualize:
                // if (allStatic)       // If all arguments static, just call the SDF
                //  return CGConst.Make(sdfInfo.Apply(args));
                // else
                if (anyStatic)                 // Specialize if there are static arguments
                {
                    return(Specialize(res, args));
                }
                // Do nothing if all arguments are dynamic
            }
            else
            {
                // If under dynamic control reduce to longest static prefix
                // where the argument values agree.
                // TODO: This is wrong -- should always specialize when the call is not
                // recursive
                ICollection <Value[]> pending = SdfManager.PendingSpecializations(sdfInfo.name);
                Value[] maxArray = null;
                int     maxCount = 0;
                foreach (Value[] vs in pending)
                {
                    int agree = AgreeCount(vs, args);
                    if (agree > maxCount)
                    {
                        maxCount = agree;
                        maxArray = vs;
                    }
                }
                if (maxCount > 0)
                {
                    SetNaInArgs(maxArray, args);
                    return(Specialize(res, args));
                }
            }
            return(new CGSdfCall(sdfInfo, res));
        }
 public PartListImpl(PartListImpl head, PEnv env)
 {
     this.tlist = new List <Part>();
     for (var i = 0; i < head.Count; i++)
     {
         tlist.Add(value(head[i], env));
     }
 }
Beispiel #9
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			// Volatile functions must be residualized
			if (functionInfo.name == "NOW" || functionInfo.name == "RAND") {
				return Residualize(PEvalArgs(pEnv, hasDynamicControl));
			}
			else {
				return base.PEval(pEnv, hasDynamicControl);
			}
		}
Beispiel #10
0
 public CGExpr[] PEvalArgs(PEnv pEnv, bool hasDynamicControl)
 {
     CGExpr[] res = new CGExpr[es.Length];
     for (int i = 0; i < es.Length; i++)
     {
         res[i] = es[i].PEval(pEnv, hasDynamicControl);
     }
     return(res);
 }
Beispiel #11
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     // Partial evaluation may encounter a cached expression in conditionals
     // etc, and should simply partially evaluate the expression inside the cache.
     // No duplication of cached expression happens in the residual program because
     // a cached expression appears only once in the regular code, and no occurrence
     // from evaluation conditions is added to the residual program; see ComputeCell.PEval.
     // New evaluation conditions are added later; see ProgramLines.CompileToDelegate.
     return(expr.PEval(pEnv, hasDynamicControl));
 }
        public ProveResult ExecuteSharp(Term thisTerm, PartListImpl goalList, PEnv environment, PDB db, int level,
                                        reportDelegate reportFunction)
        {
            Term       collect0   = value((Part)thisTerm.ArgList[1], environment).AsTerm();
            string     methodName = collect0.fname;
            var        partObj    = value((Part)thisTerm.ArgList[0], environment);
            object     result;
            TextWriter warns = new StringWriter();

            try
            {
                if (partObj.IsObject)
                {
                    if (!CanInvokeObject(partObj.Functor0, methodName, collect0.ArgList, out result, warns))
                    {
                        Warn(warns);
                        return(new ProveResult()
                        {
                            Failed = true
                        });
                    }
                }
                else
                {
                    if (!CanInvokeObjectByName(partObj.Text, methodName, collect0.ArgList, true, out result, warns))
                    {
                        Warn(warns);
                        return(new ProveResult()
                        {
                            Failed = true
                        });
                    }
                }
            }
            catch (Exception e2)
            {
                Warn(warns);
                throw e2;
                return(new ProveResult()
                {
                    Failed = true
                });
            }
            //print("Debug: unifying "); into.print(); print(" with "); answers.print(); print("\n");
            var env2 = unify(thisTerm.ArgList[2], ObjectToPart(result), environment);

            if (env2 == null)
            {
                //print("Debug: bagof cannot unify anslist with "); into.print(); print(", failing\n");
                return(null);
            }

            // Just prove the rest of the goallist, recursively.
            return(prove(goalList, env2, db, level + 1, reportFunction));
        }
Beispiel #13
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     // Volatile functions must be residualized
     if (functionInfo.name == "NOW" || functionInfo.name == "RAND")
     {
         return(Residualize(PEvalArgs(pEnv, hasDynamicControl)));
     }
     else
     {
         return(base.PEval(pEnv, hasDynamicControl));
     }
 }
Beispiel #14
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			CGExpr r0 = es[0].PEval(pEnv, hasDynamicControl);
			if (r0 is CGNumberConst) {
				if ((r0 as CGNumberConst).number.value != 0.0) {
					return es[1].PEval(pEnv, hasDynamicControl);
				}
				else {
					return es[2].PEval(pEnv, hasDynamicControl);
				}
			}
			else {
				return new CGIf(PEvalArgs(pEnv, r0, true));
			}
		}
Beispiel #15
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
			// The static argument positions are those that have args[i] != naError
			Value[] args = new Value[res.Length];
			bool anyStatic = false, allStatic = true;
			for (int i = 0; i < res.Length; i++) {
				if (res[i] is CGConst) {
					args[i] = (res[i] as CGConst).Value;
					anyStatic = true;
				}
				else {
					args[i] = ErrorValue.naError; // Generalize to dynamic
					allStatic = false;
				}
			}
			if (!hasDynamicControl) {
				// This would be wrong, because the called function might contain
				// volatile functions and in that case should residualize:
				// if (allStatic)       // If all arguments static, just call the SDF
				//  return CGConst.Make(sdfInfo.Apply(args));
				// else 
				if (anyStatic) // Specialize if there are static arguments
				{
					return Specialize(res, args);
				}
				// Do nothing if all arguments are dynamic
			}
			else {
				// If under dynamic control reduce to longest static prefix
				// where the argument values agree.
				// TODO: This is wrong -- should always specialize when the call is not 
				// recursive
				ICollection<Value[]> pending = SdfManager.PendingSpecializations(sdfInfo.name);
				Value[] maxArray = null;
				int maxCount = 0;
				foreach (Value[] vs in pending) {
					int agree = AgreeCount(vs, args);
					if (agree > maxCount) {
						maxCount = agree;
						maxArray = vs;
					}
				}
				if (maxCount > 0) {
					SetNaInArgs(maxArray, args);
					return Specialize(res, args);
				}
			}
			return new CGSdfCall(sdfInfo, res);
		}
Beispiel #16
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			CGExpr r0 = es[0].PEval(pEnv, hasDynamicControl);
			if (r0 is CGNumberConst) {
				int index = (int)((r0 as CGNumberConst).number.value);
				if (index < 1 || index >= es.Length) {
					return new CGError(ErrorValue.valueError);
				}
				else {
					return es[index].PEval(pEnv, hasDynamicControl);
				}
			}
			else {
				return new CGChoose(PEvalArgs(pEnv, r0, true /* has dynamic control */));
			}
		}
Beispiel #17
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
			// If all args are constant then evaluate else residualize:
			if (AllConstant(res)) {
				Expr[] es = new Expr[res.Length];
				for (int i = 0; i < res.Length; i++) {
					es[i] = Const.Make((res[i] as CGConst).Value);
				}
				// Use the interpretive implementation's applier on a fake sheet 
				// and fake cell coordinates, but constant argument expressions:
				return CGConst.Make(applier(null, es, -1, -1));
			}
			else {
				return Residualize(res);
			}
		}
Beispiel #18
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
     // If all args are constant then evaluate else residualize:
     if (AllConstant(res))
     {
         Expr[] es = new Expr[res.Length];
         for (int i = 0; i < res.Length; i++)
         {
             es[i] = Const.Make((res[i] as CGConst).Value);
         }
         // Use the interpretive implementation's applier on a fake sheet
         // and fake cell coordinates, but constant argument expressions:
         return(CGConst.Make(applier(null, es, -1, -1)));
     }
     else
     {
         return(Residualize(res));
     }
 }
Beispiel #19
0
        public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
        {
            CGExpr r0 = es[0].PEval(pEnv, hasDynamicControl);

            if (r0 is CGNumberConst)
            {
                if ((r0 as CGNumberConst).number.value != 0.0)
                {
                    return(es[1].PEval(pEnv, hasDynamicControl));
                }
                else
                {
                    return(es[2].PEval(pEnv, hasDynamicControl));
                }
            }
            else
            {
                return(new CGIf(PEvalArgs(pEnv, r0, true)));
            }
        }
Beispiel #20
0
        public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
        {
            CGExpr r0 = es[0].PEval(pEnv, hasDynamicControl);

            if (r0 is CGNumberConst)
            {
                int index = (int)((r0 as CGNumberConst).number.value);
                if (index < 1 || index >= es.Length)
                {
                    return(new CGError(ErrorValue.valueError));
                }
                else
                {
                    return(es[index].PEval(pEnv, hasDynamicControl));
                }
            }
            else
            {
                return(new CGChoose(PEvalArgs(pEnv, r0, true /* has dynamic control */)));
            }
        }
Beispiel #21
0
        // Returns residual ComputeCell or null if no cell needed
        public ComputeCell PEval(PEnv pEnv)
        {
            CGExpr rCond = null;

            if (evalCond != null)             // Never the case for an output cell
            {
                rCond = evalCond.PEval(pEnv, false /* not dynamic control */);
            }
            if (rCond is CGNumberConst)
            {
                if ((rCond as CGNumberConst).number.value != 0.0)
                {
                    rCond = null;                     // eval cond constant TRUE, discard eval cond
                }
                else
                {
                    return(null);                    // eval cond constant FALSE, discard entire compute cell
                }
            }
            // If residual eval cond is not TRUE then expr has dynamic control
            CGExpr rExpr = expr.PEval(pEnv, rCond != null);

            if (rExpr is CGConst && var != null)
            {
                // If cell's value is constant and it is not an output cell just put in PEnv
                pEnv[cellAddr] = rExpr;
                return(null);
            }
            else
            {
                // Else create fresh local variable for the residual cell, and make
                // PEnv map cell address to that local variable:
                Variable newVar = var != null?var.Fresh() : null;

                pEnv[cellAddr] = new CGCellRef(cellAddr, newVar);
                ComputeCell result = new ComputeCell(rExpr, newVar, cellAddr);
                // result.EvalCond = rCond;  // Don't save residual eval cond, we compute it accurately later...
                return(result);
            }
        }
Beispiel #22
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			List<CGExpr> res = new List<CGExpr>();
			for (int i = 0; i < es.Length; i++) {
				CGExpr ri = es[i].PEval(pEnv, hasDynamicControl || res.Count > 0);
				if (ri is CGNumberConst) {
					// A TRUE operand makes the OR true; a FALSE operand can be ignored
					if ((ri as CGNumberConst).number.value != 0.0) {
						return new CGNumberConst(NumberValue.ONE);
					}
				}
				else {
					res.Add(ri);
				}
			}
			// The residual OR consists of the non-constant operands, if any
			if (res.Count == 0) {
				return new CGNumberConst(NumberValue.ZERO);
			}
			else {
				return new CGOr(res.ToArray());
			}
		}
Beispiel #23
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     return(pEnv[cellAddr]);
 }
Beispiel #24
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) { return this; }
Beispiel #25
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) { return pEnv[cellAddr]; }
Beispiel #26
0
		// Returns residual ComputeCell or null if no cell needed
		public ComputeCell PEval(PEnv pEnv) {
			CGExpr rCond = null;
			if (evalCond != null) // Never the case for an output cell
			{
				rCond = evalCond.PEval(pEnv, false /* not dynamic control */);
			}
			if (rCond is CGNumberConst) {
				if ((rCond as CGNumberConst).number.value != 0.0) {
					rCond = null; // eval cond constant TRUE, discard eval cond
				}
				else {
					return null; // eval cond constant FALSE, discard entire compute cell
				}
			}
			// If residual eval cond is not TRUE then expr has dynamic control
			CGExpr rExpr = expr.PEval(pEnv, rCond != null);
			if (rExpr is CGConst && var != null) {
				// If cell's value is constant and it is not an output cell just put in PEnv
				pEnv[cellAddr] = rExpr;
				return null;
			}
			else {
				// Else create fresh local variable for the residual cell, and make 
				// PEnv map cell address to that local variable:          
				Variable newVar = var != null ? var.Fresh() : null;
				pEnv[cellAddr] = new CGCellRef(cellAddr, newVar);
				ComputeCell result = new ComputeCell(rExpr, newVar, cellAddr);
				// result.EvalCond = rCond;  // Don't save residual eval cond, we compute it accurately later...
				return result;
			}
		}
Beispiel #27
0
		// Partially evaluate the programList with respect to the given static inputs, 
		// producing a new ProgramLines object.
		public ProgramLines PEval(Value[] args, FullCellAddr[] residualInputs) {
			PEnv pEnv = new PEnv();
			// Map static input cells to their constant values:
			for (int i = 0; i < args.Length; i++) {
				pEnv[inputCells[i]] = CGConst.Make(args[i]);
			}
			ProgramLines residual = new ProgramLines(outputCell, residualInputs);
			// PE-time environment PEnv maps each residual input cell address to the delegate argument:
			for (int i = 0; i < residualInputs.Length; i++) {
				FullCellAddr input = residualInputs[i];
				pEnv[input] = new CGCellRef(input, residual.addressToVariable[input]);
			}
			// Process the given function's compute cells in dependency order, output last:
			foreach (ComputeCell ccell in programList) {
				ComputeCell rCcell = ccell.PEval(pEnv);
				if (rCcell != null) {
					residual.AddComputeCell(ccell.cellAddr, rCcell);
				}
			}
			residual = residual.PruneZeroUseCells();
			return residual;
		}
Beispiel #28
0
 /// <summary>
 /// Specialize the expression with respect to the values/residual expressions in pEnv.
 /// </summary>
 /// <param name="pEnv">Maps cell addresses to already-specialized expressions</param>
 /// <returns>The specialized expression</returns>
 public abstract CGExpr PEval(PEnv pEnv, bool hasDynamicControl);
Beispiel #29
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     // Always residualize; external function could have effects or be volatile
     return(new CGExtern(PEvalArgs(pEnv, hasDynamicControl)));
 }
Beispiel #30
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			// Always residualize; external function could have effects or be volatile
			return new CGExtern(PEvalArgs(pEnv, hasDynamicControl));
		}
Beispiel #31
0
 public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl)
 {
     return(this);
 }
Beispiel #32
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			// Partial evaluation may encounter a cached expression in conditionals
			// etc, and should simply partially evaluate the expression inside the cache.
			// No duplication of cached expression happens in the residual program because 
			// a cached expression appears only once in the regular code, and no occurrence 
			// from evaluation conditions is added to the residual program; see ComputeCell.PEval.
			// New evaluation conditions are added later; see ProgramLines.CompileToDelegate.
			return expr.PEval(pEnv, hasDynamicControl);
		}
Beispiel #33
0
		/// <summary>
		/// Specialize the expression with respect to the values/residual expressions in pEnv.
		/// </summary>
		/// <param name="pEnv">Maps cell addresses to already-specialized expressions</param>
		/// <returns>The specialized expression</returns>
		public abstract CGExpr PEval(PEnv pEnv, bool hasDynamicControl);