factValue (factId, params = {}, path = '') {
    let factValuePromise
    const fact = this._getFact(factId)
    if (fact === undefined) {
      if (this.allowUndefinedFacts) {
        return Promise.resolve(undefined)
      } else {
        return Promise.reject(new UndefinedFactError(`Undefined fact: ${factId}`))
      }
    }
    if (fact.isConstant()) {
      factValuePromise = Promise.resolve(fact.calculate(params, this))
    } else {
      const cacheKey = fact.getCacheKey(params)
      const cacheVal = cacheKey && this.factResultsCache.get(cacheKey)
      if (cacheVal) {
        factValuePromise = Promise.resolve(cacheVal)
        debug('almanac::factValue cache hit for fact', { id: factId })
      } else {
        debug('almanac::factValue cache miss, calculating', { id: factId })
        factValuePromise = this._setFactValue(fact, params, fact.calculate(params, this))
      }
    }
    if (path) {
      debug('condition::evaluate extracting object', { property: path })
      return factValuePromise
        .then(factValue => {
          if (factValue != null && typeof factValue === 'object') {
            const pathValue = this.pathResolver(factValue, path)
            debug('condition::evaluate extracting object', { property: path, received: pathValue })
            return pathValue
          } else {
            debug('condition::evaluate could not compute object path of non-object', { path, factValue, type: typeof factValue })
            return factValue
          }
        })
    }

    return factValuePromise
  }
Returns the value of a fact, based on the given parameters.  Utilizes the 'almanac' maintained
by the engine, which cache's fact computations based on parameters provided
@param  {string} factId - fact identifier
@param  {Object} params - parameters to feed into the fact.  By default, these will also be used to compute the cache key
@param  {String} path - object
@return {Promise} a promise which will resolve with the fact computation.