Ejemplo n.º 1
0
        /// <summary>
        /// Divides one Tnum by another.
        /// </summary>
        public static Tnum operator /(Tnum tn1, Tnum tn2)
        {
            Tnum result = new Tnum();

            foreach (KeyValuePair <DateTime, List <Hval> > slice in TimePointValues(tn1, tn2))
            {
                Hstate  top         = PrecedingState(slice.Value);
                decimal denominator = Convert.ToDecimal(slice.Value[1].Val);

                if (denominator == 0)   // Short circuit 1: Div-by-zero
                {
                    result.AddState(slice.Key, new Hval(null));
                }
                else if (top != Hstate.Known)                     // Short circuit 2: Hstates
                {
                    result.AddState(slice.Key, new Hval(null, top));
                }
                else                                              // Do the math
                {
                    decimal r = Convert.ToDecimal(slice.Value[0].Val) / denominator;
                    result.AddState(slice.Key, new Hval(r));
                }
            }

            return(result.Lean);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Unstated Things.
 /// </summary>
 public Thing(Hstate h)
 {
     if (h == Hstate.Unstated)  Id = "#Unstated#";
     else if (h == Hstate.Uncertain) Id = "#Uncertain#";
     else if (h == Hstate.Stub)      Id = "#Stub#";
     else Id = "";
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Multiplies two Tnums together.
        /// </summary>
        public static Tnum operator *(Tnum tn1, Tnum tn2)
        {
            Tnum result = new Tnum();

            foreach (KeyValuePair <DateTime, List <Hval> > slice in TimePointValues(tn1, tn2))
            {
                Hstate  top  = PrecedingState(slice.Value);
                decimal val1 = Convert.ToDecimal(slice.Value [0].Val);
                decimal val2 = Convert.ToDecimal(slice.Value [1].Val);

                // Short circuit 1
                if (val1 == 0 || val2 == 0)
                {
                    result.AddState(slice.Key, new Hval(0));
                }
                else if (top != Hstate.Known)      // Short circuit 2
                {
                    result.AddState(slice.Key, new Hval(null, top));
                }
                else                               // Do the math
                {
                    decimal prod = val1 * val2;
                    result.AddState(slice.Key, new Hval(prod));
                }
            }

            return(result.Lean);
        }
Ejemplo n.º 4
0
        public static Tnum IntervalsUntil(Tdate startDate, Tdate endDate, IntervalType interval, int startAt)
        {
            // Handle unknowns
            Hstate top = PrecedingState(startDate.FirstValue, endDate.FirstValue);

            if (top != Hstate.Known)
            {
                return(new Tnum(new Hval(null, top)));
            }

            DateTime start = startDate.ToDateTime;
            DateTime end   = endDate.ToDateTime;

            Tnum result = new Tnum();

            DateTime indexDate   = end;
            int      indexNumber = startAt - 1;

            while (indexDate > start)
            {
                if (indexNumber != startAt - 1)
                {
                    result.AddState(indexDate, Convert.ToString(indexNumber));
                }
                indexNumber++;
                indexDate = indexDate.SubtractInterval(interval);
            }

            result.AddState(Time.DawnOf, 0);
            result.AddState(start, Convert.ToString(indexNumber));
            result.AddState(end, 0);

            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Applies an aggregation function to a Tset and an argument function.
        /// </summary>
        private static T ApplyFcnToTset <T>(Tset theSet,
                                            Func <Thing, Tvar> argumentFcn,
                                            Func <List <Tuple <Thing, Hval> >, Hval> aggregationFcn) where T : Tvar
        {
            Dictionary <Thing, Tvar> fcnValues = new Dictionary <Thing, Tvar>();
            List <Tvar> listOfTvars            = new List <Tvar>();

            // Get the temporal value of each distinct entity in the set
            foreach (Thing le in DistinctEntities(theSet))
            {
                Tvar val = argumentFcn(le);
                fcnValues.Add(le, val);
                listOfTvars.Add(val);
            }

            // At each breakpoint, for each member of the set,
            // aggregate and analyze the values of the functions
            T result = (T)Util.ReturnProperTvar <T>();

            foreach (DateTime dt in AggregatedTimePoints(theSet, listOfTvars))
            {
                Hval membersOfSet = theSet.ObjectAsOf(dt);

                // If theSet is unknown...
                if (!membersOfSet.IsKnown)
                {
                    result.AddState(dt, membersOfSet);
                }
                else
                {
                    // Cube that gets sent to the aggregation function
                    List <Tuple <Thing, Hval> > thingValPairs = new List <Tuple <Thing, Hval> >();

                    // Values to check for uncertainty
                    List <Hval> values = new List <Hval>();

                    foreach (Thing le in (List <Thing>)membersOfSet.Val)
                    {
                        Tvar funcVal   = (Tvar)fcnValues[le];
                        Hval funcValAt = funcVal.ObjectAsOf(dt);
                        values.Add(funcValAt);
                        thingValPairs.Add(new Tuple <Thing, Hval>(le, funcValAt));
                    }

                    Hstate top = PrecedingState(values);
                    if (top != Hstate.Known)
                    {
                        result.AddState(dt, new Hval(null, top));
                    }
                    else
                    {
                        result.AddState(dt, aggregationFcn(thingValPairs));
                    }
                }
            }

            return(result.LeanTvar <T>());
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Known object values and null values.
 /// </summary>
 public Hval(object val)
 {
     if (val == null)
     {
         Obj   = null;
         State = Hstate.Uncertain;
     }
     else
     {
         Obj   = val;
         State = Hstate.Known;
     }
 }
Ejemplo n.º 7
0
 /// <summary>
 /// States.
 /// </summary>
 public Hval(object ignored, Hstate state)
 {
     if (state == Hstate.Known)
     {
         // Should not happen?
         Obj = null;
         State = Hstate.Known;
     }
     else
     {
         Obj = null;
         State = state;
     }
 }
Ejemplo n.º 8
0
 /// <summary>
 /// States.
 /// </summary>
 public Hval(object ignored, Hstate state)
 {
     if (state == Hstate.Known)
     {
         // Should not happen?
         Obj   = null;
         State = Hstate.Known;
     }
     else
     {
         Obj   = null;
         State = state;
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Provides a running count of how many whole intervals a Tbool
        /// has been continuously true.
        /// </summary>
        /// <remarks>
        /// Example:
        ///         tb = <--FTFTTF-->
        ///     tb.ICT = <--010120-->
        ///
        /// Use judiciously with TheDay and TheCalendarWeek, as they have thousands of time intervals.
        /// </remarks>
        public Tnum ContinuousElapsedIntervals(Tnum interval)
        {
            // If base Tnum is ever unknown during the time period, return
            // the state with the proper precedence
            Hstate baseState = PrecedenceForMissingTimePeriods(this);

            if (baseState != Hstate.Known)
            {
                return(new Tnum(baseState));
            }

            int      intervalCount            = 0;
            DateTime dateNextTrue             = this.DateNextTrue(Time.DawnOf);
            DateTime dateNextTrueIntervalEnds = this.NextChangeDate(dateNextTrue.AddTicks(1));

            Tnum result = new Tnum(0);

            // Iterate through the time intervals in the input Tnum
            for (int i = 0; i < interval.IntervalValues.Count - 1; i++)
            {
                DateTime start = interval.IntervalValues.Keys[i];
                DateTime end   = interval.IntervalValues.Keys[i + 1];

                // If base Tbool is always true during the interval, increment the count
                if (end <= dateNextTrueIntervalEnds)
                {
                    if (start >= dateNextTrue)
                    {
                        intervalCount++;
                        result.AddState(end, intervalCount);
                        continue;
                    }
                }
                else
                {
                    // Otherwise, skip to next true interval
                    intervalCount = 0;
                    result.AddState(end, intervalCount);
                    dateNextTrue             = this.DateNextTrue(end);
                    dateNextTrueIntervalEnds = this.NextChangeDate(dateNextTrue.AddTicks(1));
                }
            }

            return(result);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Apply a function to all values in a list of zipped Tvar values.
        /// </summary>
        public static T ApplyFcnToTimeline <T>(Func <List <Hval>, Hval> fcn, params Tvar[] list) where T : Tvar
        {
            T result = (T)Util.ReturnProperTvar <T>();

            foreach (KeyValuePair <DateTime, List <Hval> > slice in TimePointValues(list))
            {
                Hstate top = PrecedingState(slice.Value);
                if (top != Hstate.Known)
                {
                    result.AddState(slice.Key, new Hval(null, top));
                }
                else
                {
                    result.AddState(slice.Key, fcn(slice.Value));
                }
            }

            return(result.LeanTvar <T>());
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Apply a function to the values in a single Tvar.
        /// </summary>
        /// <remarks>
        /// This is used for unary functions (those that only operate on a single Tvar).
        /// </remarks>
        public static T ApplyFcnToTimeline <T>(Func <Hval, Hval> fcn, Tvar tv) where T : Tvar
        {
            T result = (T)Util.ReturnProperTvar <T>();

            foreach (KeyValuePair <DateTime, Hval> slice in tv.IntervalValues)
            {
                Hstate top = PrecedingState(slice.Value);
                if (top != Hstate.Known)
                {
                    result.AddState(slice.Key, new Hval(null, top));
                }
                else
                {
                    result.AddState(slice.Key, fcn(slice.Value));
                }
            }

            return(result.LeanTvar <T>());
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Unstated Things.
 /// </summary>
 public Thing(Hstate h)
 {
     if (h == Hstate.Unstated)
     {
         Id = "#Unstated#";
     }
     else if (h == Hstate.Uncertain)
     {
         Id = "#Uncertain#";
     }
     else if (h == Hstate.Stub)
     {
         Id = "#Stub#";
     }
     else
     {
         Id = "";
     }
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Takes a Tnum representing some value per unit time, and sums or
        /// accumulates it over a given type of time interval to obtain a
        /// running total.
        /// </summary>
        /// <example>
        /// Calculate lifetime accrued income, given a person's annual income:
        ///
        ///   AccruedIncome = AnnualIncome.RunningSummedIntervals(TheYear)
        ///
        /// The time units cancel: [$/year] * [year] yields [$].
        /// </example>
        public Tnum RunningSummedIntervals(Tnum interval)
        {
            // TODO: Review how uncertainty is handled here:

            // Handle unknowns
            Hstate top = PrecedingState(this.FirstValue, interval.FirstValue);

            if (top != Hstate.Known)
            {
                return(new Tnum(new Hval(null, top)));
            }

            // If base Tnum is ever unknown during the time period, return
            // the state with the proper precedence
            Hstate baseState = PrecedenceForMissingTimePeriods(this);

            if (baseState != Hstate.Known)
            {
                return(new Tnum(baseState));
            }

            // Start accumulating...
            Tnum    result      = new Tnum(0);
            decimal total       = 0;
            decimal previousVal = 0;

            // Iterate through the intervals, totaling
            for (int i = 1; i < interval.TimeLine.Count - 1; i++)
            {
                total += Convert.ToDecimal(this.ObjectAsOf(interval.TimeLine.Keys[i]).Val);

                // Only add changepoint if value actually changes
                if (total != previousVal)
                {
                    result.AddState(interval.TimeLine.Keys[i + 1], total);
                }

                // Set for next iteration
                previousVal = total;
            }

            return(result);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Determines whether the Tvar is ever the specified boolean val.
        /// </summary>
        private Tbool IsEver(Hval val)
        {
            // If val is unknown and base Tvar is eternally unknown,
            // return the typical precedence state
            if (!val.IsKnown && this.TimeLine.Count == 1)
            {
                if (!this.FirstValue.IsKnown)
                {
                    Hstate s = PrecedingState(this.FirstValue, val);
                    return(new Tbool(s));
                }
            }

            // If val is unknown, return its state
            if (!val.IsKnown)
            {
                return(new Tbool(val));
            }

            // If the base Tvar is ever val, return true
            foreach (Hval h in this.TimeLine.Values)
            {
                if (h.IsEqualTo(val))
                {
                    return(true);
                }
            }

            // If base Tvar has a time period of unknownness, return
            // the state with the proper precedence
            Hstate returnState = PrecedenceForMissingTimePeriods(this);

            if (returnState != Hstate.Known)
            {
                return(new Tbool(returnState));
            }

            return(false);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Returns the all-time minimum value of the Tnum.
        /// </summary>
        public Tnum Min()
        {
            // Deal with unknowns
            Hstate state = PrecedenceForMissingTimePeriods(this);

            if (state != Hstate.Known)
            {
                return(new Tnum(state));
            }

            // Determine the maximum value
            decimal min = Convert.ToDecimal(this.FirstValue.Val);

            foreach (Hval s in TimeLine.Values)
            {
                if (Convert.ToDecimal(s.Val) < min)
                {
                    min = Convert.ToDecimal(s.Val);
                }
            }
            return(new Tnum(min));
        }
Ejemplo n.º 16
0
        //*********************************************************************
        // TEMPORAL "RECURRENCE" FUNCTIONS
        //*********************************************************************

        /// <summary>
        /// Loops (cycles) through numbers over time (e.g. 1 2 3 4 1 2 3 4 ...)
        /// </summary>
        public static Tnum Recurrence(Tdate startDate, Tdate endDate, IntervalType interval, int min, int max)
        {
            // Handle unknowns
            Hstate top = PrecedingState(startDate.FirstValue, endDate.FirstValue);

            if (top != Hstate.Known)
            {
                return(new Tnum(new Hval(null, top)));
            }

            DateTime start = startDate.ToDateTime;
            DateTime end   = endDate.ToDateTime;

            Tnum result = new Tnum();

            if (start != Time.DawnOf)
            {
                result.AddState(Time.DawnOf, 0);
            }

            DateTime indexDate   = start;
            int      indexNumber = min;

            while (indexDate < end)
            {
                result.AddState(indexDate, Convert.ToString(indexNumber));
                indexDate = indexDate.AddInterval(interval, 1);

                // Reset sequence
                indexNumber++;
                if (indexNumber > max)
                {
                    indexNumber = min;
                }
            }

            result.AddState(end, 0);
            return(result);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Private non-temporal AND function
        /// </summary>
        private static Hval CoreAnd(List <Hval> list)
        {
            // One false falsifies the conclusion
            foreach (Hval h in list)
            {
                if (h.IsFalse)
                {
                    return(new Hval(false));
                }
            }

            // Any higher-precedence states go next
            Hstate top = PrecedingStateForLogic(list);

            if (top != Hstate.Known)
            {
                return(new Hval(null, top));
            }

            // Otherwise, true
            return(new Hval(true));
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Returns the value of a Tvar at a specified point in time.
        /// </summary>
        /// <remarks>
        /// If the Tdate varies over time, only the first value is used.
        /// </remarks>
        public T AsOf <T>(Tdate date) where T : Tvar
        {
            Hval result;

            // If base Tvar has eternal, known value, return that.
            // (In these cases, the Tdate is irrelevant.)
            if (this.IsEternal && !this.IsEternallyUnknown)
            {
                result = this.FirstValue;
            }
            // If either the base Tvar or Tdate are unknown...
            else if (!date.FirstValue.IsKnown || this.IsEternallyUnknown)
            {
                Hstate top = PrecedingState(this.FirstValue, date.FirstValue);
                result = new Hval(null, top);
            }
            else
            {
                result = this.ObjectAsOf(date.ToDateTime);
            }

            return((T)Util.ReturnProperTvar <T>(result));
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Returns the total elapsed days that a Tvar has a given value,
        /// for each of a given set of intervals.
        /// Example: meetsAnnualTest = var.ElapsedDaysPerInterval(theYear) > 183;
        /// </summary>
        public Tnum TotalElapsedDaysPer(Tnum period)
        {
            // If base Tnum is ever unknown during the time period, return
            // the state with the proper precedence
            Hstate baseState   = PrecedenceForMissingTimePeriods(this);
            Hstate periodState = PrecedenceForMissingTimePeriods(period);
            Hstate top         = PrecedingState(baseState, periodState);

            if (top != Hstate.Known)
            {
                return(new Tnum(top));
            }

            Tnum result = new Tnum();

            int count = period.IntervalValues.Count;

            for (int i = 0; i < count; i++)
            {
                DateTime spanEnd = Time.EndOf;
                if (i < count - 1)
                {
                    spanEnd = period.IntervalValues.Keys[i + 1];
                }

                TimeSpan time = this.TotalElapsedTime(period.IntervalValues.Keys[i], spanEnd);

                // Add the state, but not if it's at the end of time
                if (period.IntervalValues.Keys[i] < Time.EndOf)
                {
                    result.AddState(period.IntervalValues.Keys[i], time.TotalDays);
                }
            }

            return(result.Lean);
        }
Ejemplo n.º 20
0
        public static Tnum IntervalsSince(Tdate startDate, Tdate endDate, IntervalType interval, int?startAt)
        {
            // Handle unknowns
            Hstate top = PrecedingState(startDate.FirstValue, endDate.FirstValue);

            if (top != Hstate.Known)
            {
                return(new Tnum(new Hval(null, top)));
            }

            DateTime start = startDate.ToDateTime;
            DateTime end   = endDate.ToDateTime;

            Tnum result = new Tnum();

            if (start != Time.DawnOf)
            {
                result.AddState(Time.DawnOf, 0);
            }

            DateTime indexDate   = start;
            int?     indexNumber = startAt;

            while (indexDate < end)
            {
                result.AddState(indexDate, Convert.ToDecimal(indexNumber));
                indexNumber++;
                indexDate = indexDate.AddInterval(interval, 1);
            }

            if (end < Time.EndOf)
            {
                result.AddState(end, 0);
            }
            return(result);
        }
Ejemplo n.º 21
0
 public Tdate(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 22
0
 public Tnum(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Determines whether the rule should short-circuit before firing the actual rule logic.
        /// </summary>
        public static RulePreCheckResponse ShortCircuitValue <T>(string rel, string symIndicator, string questionIndicator, params object[] argList) where T : Tvar
        {
            // First, determine whether any of the Things are unknown.
            Hstate h = EntityArgIsUnknown(argList);

            if (h != Hstate.Known)
            {
                T scv = (T)Util.ReturnProperTvar <T>(new Hval(null, h));
                return(new RulePreCheckResponse(scv, true));
            }

            // Extract argument parameters from argList
            object param1 = argList[0];
            object param2 = argList.Length > 1 ? argList[1] : null;
            object param3 = argList.Length > 2 ? argList[2] : null;

            // Adds the function node to the proof tree
            Engine.AddToProofTree(new Facts.Fact(rel, param1, param2, param3, "?"));

            // Handle symmetrical facts
            if (symIndicator == "Sym")
            {
                // If the fact has not been asserted, add it to the list of unknown facts, so it gets asked.
                if (!Facts.HasBeenAssertedSym(param1, rel, param2))
                {
                    // EXPERIMENTAL: First, ask any assumed facts
                    if (Facts.GetUnknowns)
                    {
//                        if (Facts.Sym(param1, rel, param2).IsEternallyUncertain)
//                        {
//                            Assumptions.AskAssumedFacts(rel, param1, param2, param3);
//                            Assumptions.AskAssumedFacts(rel, param2, param1, param3);
//                        }

                        // "?" indicates that this node is a question to be asked of the user
                        if (questionIndicator == "?")
                        {
                            Facts.AddUnknown(rel, param1, param2, null);
                        }
                    }
                }

                // If the fact has been asserted and is not "uncertain", return the asserted value.
                else
                {
                    Tbool f = Facts.Sym(param1, rel, param2);
                    if (!f.IsEternallyUncertain)
                    {
                        return(new RulePreCheckResponse(f, true));
                    }
                }
            }

            // Handle non-symmetrical facts (same code pattern as above)
            else
            {
                if (!Facts.HasBeenAsserted(rel, param1, param2, param3))
                {
                    if (Facts.GetUnknowns)
                    {
                        // EXPERIMENTAL: First, ask any assumed facts
//                        Assumptions.AskAssumedFacts(rel, param1, param2, param3, false);

                        if (questionIndicator == "?")
                        {
                            Facts.AddUnknown(rel, param1, param2, param3);
                        }
                    }
                }
                else
                {
                    T f = Facts.QueryTvar <T>(rel, param1, param2, param3);
                    if (!f.IsEternallyUncertain)
                    {
                        return(new RulePreCheckResponse(f, true));
                    }
                }
            }

            // Otherwise, proceed to examine the rule conditions and sub-rules.
            return(new RulePreCheckResponse(null, false));
        }
Ejemplo n.º 24
0
 public Tdate(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 25
0
 public Tnum(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 26
0
 public Tbool(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 27
0
        }                                   // State of knowledge of the object.

        /// <summary>
        /// Empty or unstated values.
        /// </summary>
        public Hval()
        {
            Obj   = null;
            State = Hstate.Unstated;
        }
Ejemplo n.º 28
0
 public Tset(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 29
0
 public Tset(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 30
0
 public Tbool(Hstate state)
 {
     this.SetEternally(state);
 }
Ejemplo n.º 31
0
        /// <summary>
        /// Takes a Tnum representing some value per unit time, and accumulates it
        /// over a given number of successive time intervals.
        /// </summary>
        /// <example>
        /// Calculate income accumulated over a three month period, where the
        /// person earned $3,000/month:
        ///
        ///   Income = MonthlyIncome.SlidingSummedIntervals(TheMonth, 3)
        ///
        /// The time units cancel: [$/mo.] * [mo.] yields [$].
        /// </example>
        public Tnum SlidingSummedIntervals(Tnum interval, Tnum windowSize)
        {
            // TODO: Review how uncertainty is handled here:

            // Handle unknowns
            Hstate top = PrecedingState(this.FirstValue, interval.FirstValue, windowSize.FirstValue);

            if (top != Hstate.Known)
            {
                return(new Tnum(new Hval(null, top)));
            }

            // If base Tnum is ever unknown during the time period, return
            // the state with the proper precedence
            Hstate baseState = PrecedenceForMissingTimePeriods(this);

            if (baseState != Hstate.Known)
            {
                return(new Tnum(baseState));
            }

            // Handle eternal values
            if (this.IsEternal)
            {
                return(this * windowSize);
            }

            // Start accumulating...
            int num = windowSize.ToHardInt;

            // Get first accumulated value
            decimal firstVal = 0;

            for (int j = 0; j < num; j++)
            {
                // Don't walk off the end of the timeline
                if (j < interval.TimeLine.Count)
                {
                    firstVal += this.AsOf(interval.TimeLine.Keys [j]).ToHardDecimal;
                }
            }
            Tnum result = new Tnum(firstVal);

            // Iterate through the subsequent intervals
            decimal previousVal = firstVal;

            for (int i = 1; i < interval.TimeLine.Count - num; i++)
            {
                // Take the value from the last iteration, and slide it the time window to the right,
                // subtracting the left interval and adding the new right one.
                decimal lastOldInterval = Convert.ToDecimal(this.ObjectAsOf(interval.TimeLine.Keys[i - 1]).Val);
                decimal nextNewInterval = Convert.ToDecimal(this.ObjectAsOf(interval.TimeLine.Keys[i + num - 1]).Val);
                decimal newVal          = previousVal - lastOldInterval + nextNewInterval;

                // Only add changepoint if value actually changes
                if (newVal != previousVal)
                {
                    // The value of an interval is counted after it has elapsed
                    result.AddState(interval.TimeLine.Keys[i + num], newVal);
                }

                // Set for next iteration
                previousVal = newVal;
            }

            return(result);
        }