src/utility/sortTimables.js
function sortTimables(conjunction, forTime) {
  let earlyConjuncts = [];
  let laterConjuncts = [];

  let dependentTimeVariables = {};

  // determine the time dependent variables
  for (let k = 0; k < conjunction.length; k += 1) {
    let conjunct = conjunction[k];

    if (!(conjunct instanceof Timable)) {
      // skip over non-Timables
      if (conjunct instanceof Functor
          && comparisonTerms.indexOf(conjunct.getId()) !== -1) {
        conjunct.getVariables()
          .forEach((v) => {
            dependentTimeVariables[v] = true;
          });
      }
      continue;
    }

    let conjunctStartTime = conjunct.getStartTime();
    let conjunctEndTime = conjunct.getEndTime();

    if (conjunctEndTime instanceof Variable) {
      let endTimeName = conjunctEndTime.evaluate();
      if (conjunctStartTime instanceof Value
          || (conjunctStartTime instanceof Variable
            && conjunctStartTime.evaluate() !== endTimeName)) {
        // different start/end times
        dependentTimeVariables[endTimeName] = true;
      }
    }
  }

  // sort between early and later
  for (let k = 0; k < conjunction.length; k += 1) {
    let conjunct = conjunction[k];

    if (!(conjunct instanceof Timable)) {
      if (laterConjuncts.length > 0) {
        laterConjuncts.push(conjunct);
        continue;
      }
      earlyConjuncts.push(conjunct);
      continue;
    }

    if (!conjunct.isInRange(forTime)) {
      laterConjuncts.push(conjunct);
      continue;
    }

    let conjunctStartTime = conjunct.getStartTime();

    if (conjunctStartTime instanceof Variable) {
      if (dependentTimeVariables[conjunctStartTime.evaluate()] !== undefined) {
        laterConjuncts.push(conjunct);
        continue;
      }
    }

    earlyConjuncts.push(conjunct);
  }

  return [
    earlyConjuncts,
    laterConjuncts
  ];
}
function sortTimables(conjunction, forTime) {
  let earlyConjuncts = [];
  let laterConjuncts = [];

  let dependentTimeVariables = {};

  // determine the time dependent variables
  for (let k = 0; k < conjunction.length; k += 1) {
    let conjunct = conjunction[k];

    if (!(conjunct instanceof Timable)) {
      // skip over non-Timables
      if (conjunct instanceof Functor
          && comparisonTerms.indexOf(conjunct.getId()) !== -1) {
        conjunct.getVariables()
          .forEach((v) => {
            dependentTimeVariables[v] = true;
          });
      }
      continue;
    }

    let conjunctStartTime = conjunct.getStartTime();
    let conjunctEndTime = conjunct.getEndTime();

    if (conjunctEndTime instanceof Variable) {
      let endTimeName = conjunctEndTime.evaluate();
      if (conjunctStartTime instanceof Value
          || (conjunctStartTime instanceof Variable
            && conjunctStartTime.evaluate() !== endTimeName)) {
        // different start/end times
        dependentTimeVariables[endTimeName] = true;
      }
    }
  }

  // sort between early and later
  for (let k = 0; k < conjunction.length; k += 1) {
    let conjunct = conjunction[k];

    if (!(conjunct instanceof Timable)) {
      if (laterConjuncts.length > 0) {
        laterConjuncts.push(conjunct);
        continue;
      }
      earlyConjuncts.push(conjunct);
      continue;
    }

    if (!conjunct.isInRange(forTime)) {
      laterConjuncts.push(conjunct);
      continue;
    }

    let conjunctStartTime = conjunct.getStartTime();

    if (conjunctStartTime instanceof Variable) {
      if (dependentTimeVariables[conjunctStartTime.evaluate()] !== undefined) {
        laterConjuncts.push(conjunct);
        continue;
      }
    }

    earlyConjuncts.push(conjunct);
  }

  return [
    earlyConjuncts,
    laterConjuncts
  ];
}
Sort timables into set of earlyConjuncts and laterConjuncts
@param  {Array} conjunction The conjunction. Must be an array of functors or timables
@param  {number} forTime     A positive integer of the time to determine earlyConjuncts
@return {Array}             Return a pair of early conjuncts and later conjuncts