public static double dynamicallyEstimateGoalFanout(Proposition goal) {
    if (Proposition.allArgumentsBoundP(goal)) {
      return (1.0);
    }
    { Keyword testValue000 = goal.kind;

      if (testValue000 == Logic.KWD_ISA) {
        return (NamedDescription.dynamicallyEstimateExtensionSize(Logic.getDescription(((Surrogate)(goal.operator)))));
      }
      else if ((testValue000 == Logic.KWD_FUNCTION) ||
          (testValue000 == Logic.KWD_PREDICATE)) {
        if (goal.operator == Logic.SGT_PL_KERNEL_KB_HOLDS) {
          if (!Logic.argumentBoundP((goal.arguments.theArray)[0])) {
            return (Stella.NULL_FLOAT);
          }
          else {
            return (Proposition.dynamicallyEstimatePredicateGoalFanout(goal));
          }
        }
        if (Proposition.allKeyArgumentsBoundP(goal)) {
          return (1.0);
        }
        else {
          return (Proposition.dynamicallyEstimatePredicateGoalFanout(goal));
        }
      }
      else if (testValue000 == Logic.KWD_IMPLIES) {
        return (Logic.ESTIMATED_CARDINALITY_OF_SUBSET_OF);
      }
      else if (testValue000 == Logic.KWD_EQUIVALENT) {
        if (Logic.argumentBoundP((goal.arguments.theArray)[0]) ||
            Logic.argumentBoundP((goal.arguments.theArray)[1])) {
          return (1.0);
        }
        else {
          return (Stella.NULL_FLOAT);
        }
      }
      else if ((testValue000 == Logic.KWD_NOT) ||
          ((testValue000 == Logic.KWD_FAIL) ||
           (testValue000 == Logic.KWD_FORALL))) {
        return (Stella.NULL_FLOAT);
      }
      else if (testValue000 == Logic.KWD_AND) {
        { double fanout = Stella.NULL_FLOAT;
          double minfanout = Stella.NULL_FLOAT;

          { Stella_Object arg = null;
            Vector vector000 = goal.arguments;
            int index000 = 0;
            int length000 = vector000.length();

            for (;index000 < length000; index000 = index000 + 1) {
              arg = (vector000.theArray)[index000];
              fanout = Proposition.dynamicallyEstimateGoalFanout(((Proposition)(arg)));
              if ((minfanout == Stella.NULL_FLOAT) ||
                  (fanout < minfanout)) {
                minfanout = fanout;
              }
            }
          }
          return (minfanout);
        }
      }
      else if (testValue000 == Logic.KWD_OR) {
        { double fanout = Stella.NULL_FLOAT;
          double totalfanout = Stella.NULL_FLOAT;

          { Stella_Object arg = null;
            Vector vector001 = goal.arguments;
            int index001 = 0;
            int length001 = vector001.length();

            for (;index001 < length001; index001 = index001 + 1) {
              arg = (vector001.theArray)[index001];
              fanout = Proposition.dynamicallyEstimateGoalFanout(((Proposition)(arg)));
              if (fanout != Stella.NULL_FLOAT) {
                if (totalfanout == Stella.NULL_FLOAT) {
                  totalfanout = 0.0;
                }
                totalfanout = totalfanout + fanout;
              }
            }
          }
          return (totalfanout);
        }
      }
      else {
        return (Stella.NULL_FLOAT);
      }
    }
  }