fn sizeVocab nat:
   fn numLabels nat:
      fn numDocs nat:
         fn sizeEachDoc nat:
            def dirichlet(as array(prob)):
                xs <~ plate i of int2nat(size(as)-1):
                        beta(summate j from i+1 to size(as): as[j],
                             as[i])
                return array i of size(as):
                         x = product j from 0 to i: xs[j]
                         x * if i+1==size(as): 1 else: real2prob(1-xs[i])
            
            β <~ plate _ of numLabels:
                    dirichlet(array _ of sizeVocab: 1)
            θ <~ dirichlet(array _ of numLabels: 1)
            ζ <~ plate _ of numDocs: categorical(θ)
            docs <~ plate i of numDocs:
                      plate _ of sizeEachDoc:
                        categorical(β[ζ[i]])
            return (docs, ζ)

