{"record":{"id":"d91adc6480b92790","repo":"stanfordnlp/CoreNLP","slug":"cannot-make-normalized-counter-with-dynamic-prior","errorCode":null,"errorMessage":"Cannot make normalized counter with Dynamic prior.","messagePattern":"Cannot make normalized counter with Dynamic prior\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/stats/Distribution.java","lineNumber":548,"sourceCode":"  /**\n   * Returns a Distribution that uses prior as a Dirichlet prior\n   * weighted by weight.  Essentially adds \"pseudo-counts\" for each Object\n   * in prior equal to that Object's mass in prior times weight,\n   * then normalizes.\n   * <p>\n   * WARNING: If unseen item is encountered in c, total may not be 1.\n   * NOTE: This will not work if prior is a DynamicDistribution\n   * to fix this, you could add a CounterView to Distribution and use that\n   * in the linearCombination call below\n   *\n   * @param weight multiplier of prior to get \"pseudo-count\"\n   * @return new Distribution\n   */\n  public static <E> Distribution<E> distributionWithDirichletPrior(Counter<E> c, Distribution<E> prior, double weight) {\n    Distribution<E> norm = new Distribution<>();\n    double totalWeight = c.totalCount() + weight;\n    if (prior instanceof DynamicDistribution) {\n      throw new UnsupportedOperationException(\"Cannot make normalized counter with Dynamic prior.\");\n    }\n    norm.counter = Counters.linearCombination(c, 1 / totalWeight, prior.counter, weight / totalWeight);\n    norm.numberOfKeys = prior.numberOfKeys;\n    norm.reservedMass = prior.reservedMass * weight / totalWeight;\n    //System.out.println(\"totalCount: \" + norm.totalCount());\n    return norm;\n  }\n\n  /**\n   * Like normalizedCounterWithDirichletPrior except probabilities are\n   * computed dynamically from the counter and prior instead of all at once up front.\n   * The main advantage of this is if you are making many distributions from relatively\n   * sparse counters using the same relatively dense prior, the prior is only represented\n   * once, for major memory savings.\n   *\n   * @param weight multiplier of prior to get \"pseudo-count\"\n   * @return new Distribution\n   */","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/stats/Distribution.java#L530-L566","documentation":"distributionWithDirichletPrior() mixes a counter with a prior Distribution, but a DynamicDistribution prior can change over time and therefore cannot yield a fixed normalized mixture. The method detects this and throws UnsupportedOperationException rather than producing an incorrect static distribution.","triggerScenarios":"Calling Distribution.distributionWithDirichletPrior(c, prior, weight) where prior is an instance of DynamicDistribution (or a subclass).","commonSituations":"Developers switching from a static prior (e.g. Distribution.uniform) to an adaptive/online prior without realizing the Dirichlet-mixing path does not support dynamic priors.","solutions":["Use a static Distribution as the prior (e.g. Distribution.uniform(counter))","Materialize the dynamic prior into a static snapshot Distribution before mixing","If dynamic behavior is required, implement the mixture manually and recompute on each prior update"],"exampleFix":"// before\nDistribution<String> d = Distribution.distributionWithDirichletPrior(c, dynamicPrior, 1.0);\n// after\nDistribution<String> staticPrior = Distribution.uniform(c);\nDistribution<String> d = Distribution.distributionWithDirichletPrior(c, staticPrior, 1.0);","handlingStrategy":"type-guard","validationCode":"if (prior instanceof DynamicDistribution) {\n  // choose a static prior instead\n}","typeGuard":"boolean isStaticPrior(Distribution<?> prior) { return !(prior instanceof DynamicDistribution); }","tryCatchPattern":"try {\n  Distribution<E> d = Distribution.distributionWithDirichletPrior(c, prior, weight);\n} catch (UnsupportedOperationException e) {\n  prior = Distribution.uniform(c);\n  Distribution<E> d = Distribution.distributionWithDirichletPrior(c, prior, weight);\n}","preventionTips":["Keep dynamic priors out of static-mixing APIs; snapshot them first","Type-check the prior with instanceof DynamicDistribution at call sites","Document prior requirements in wrapper methods"],"tags":["java","unsupported-operation","dirichlet","statistics"],"backgroundTag":"unsupported-operation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}