public static double dynamicallyEstimateUnboundVariablePenalty(Proposition goal) {
    { Keyword testValue000 = goal.kind;

      if ((testValue000 == Logic.KWD_NOT) ||
          (testValue000 == Logic.KWD_FAIL)) {
        return (Proposition.dynamicallyEstimateUnboundVariablePenalty(((Proposition)((goal.arguments.theArray)[0]))));
      }
      else if (testValue000 == Logic.KWD_AND) {
        { double penalty = Stella.NULL_FLOAT;
          double minpenalty = 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];
              penalty = Proposition.dynamicallyEstimateUnboundVariablePenalty(((Proposition)(arg)));
              if ((minpenalty == Stella.NULL_FLOAT) ||
                  (penalty < minpenalty)) {
                minpenalty = penalty;
              }
            }
          }
          return (minpenalty);
        }
      }
      else if (testValue000 == Logic.KWD_OR) {
        { double totalpenalty = 0.0;

          { 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];
              totalpenalty = totalpenalty + Proposition.dynamicallyEstimateUnboundVariablePenalty(((Proposition)(arg)));
            }
          }
          return (totalpenalty);
        }
      }
      else if ((testValue000 == Logic.KWD_FUNCTION) ||
          ((testValue000 == Logic.KWD_PREDICATE) ||
           ((testValue000 == Logic.KWD_EQUIVALENT) ||
            (testValue000 == Logic.KWD_ISA)))) {
        { Vector arguments = goal.arguments;
          GeneralizedSymbol operator = goal.operator;
          boolean holdsP = operator == Logic.SGT_PL_KERNEL_KB_HOLDS;
          boolean isfunctionP = (goal.kind == Logic.KWD_FUNCTION) ||
              (holdsP &&
               ((!Logic.unboundVariableP((arguments.theArray)[0])) &&
                Logic.functionP(Logic.argumentBoundTo((arguments.theArray)[0]))));
          int firstkeyargindex = (holdsP ? 1 : 0);
          int lastkeyargindex = (isfunctionP ? (arguments.length() - 2) : (arguments.length() - 1));
          int nofunboundvars = ((holdsP &&
              Logic.unboundVariableP((arguments.theArray)[0])) ? 10 : 0);

          if (lastkeyargindex < firstkeyargindex) {
            return (0.0);
          }
          { int i = Stella.NULL_INTEGER;
            int iter000 = firstkeyargindex;
            int upperBound000 = lastkeyargindex;
            boolean unboundedP000 = upperBound000 == Stella.NULL_INTEGER;

            for (;unboundedP000 ||
                      (iter000 <= upperBound000); iter000 = iter000 + 1) {
              i = iter000;
              if (Logic.unboundVariableP((arguments.theArray)[i])) {
                nofunboundvars = nofunboundvars + 1;
              }
            }
          }
          if (Proposition.computedPredicateP(goal)) {
            switch (nofunboundvars) {
              case 0: 
                return (0.0);
              case 1: 
                if (Description.computedConstraintP(Logic.getDescription(operator)) &&
                    ((!isfunctionP) ||
                     (!Logic.unboundVariableP((arguments.theArray)[(lastkeyargindex + 1)])))) {
                  return (0.0);
                }
              break;
              default:
              break;
            }
            return (10000.0);
          }
          return (1.0 + (nofunboundvars * (((double)(nofunboundvars)) / ((lastkeyargindex - firstkeyargindex) - -1))));
        }
      }
      else {
        return (3.0);
      }
    }
  }