-proc get/enum-def {s v} {
- upvar #0 enum/val2name/$s-$v v2n
- set rv [choice-int 1 [array size v2n]]
- set rv [lindex [lsort [array names v2n]] [expr {$rv-1}]]
+proc enum-prepare-choice-list {s v nvalues prand} {
+ upvar #0 "enum/choice-list/$s-${v}($nvalues $prand)" cl
+ upvar #0 enum/val2mult/$s-$v v2m
+ upvar #0 enum/total*/$s-$v total*org
+ upvar #0 enum/total?/$s-$v total?
+
+ set total* ${total*org}
+ if {!${total*}} { set total* [expr {double(${total*org}) + 0.001}] }
+
+ set pr $prand
+ if {!${total?}} { set pr 0.0 }
+ set pm? [expr {$pr / (100.0*double($nvalues))}]
+ set pm* [expr {(1.0 - $pr) / double(${total*})}]
+ debug 1 "epcl $s-$v $nvalues $prand: pr $pr ? pm ${pm?} total ${total?} * pm ${pm*} total ${total*}"
+
+ set cl {}
+ foreach rv [lsort [array names v2m]] {
+ manyset $v2m($rv) kind times
+ set p [expr { double($times) * [set pm$kind] }]
+ debug 1 "epcl $s-$v $nvalues $prand: $rv $kind$times := $p"
+ lappend cl $rv $p
+ }
+ if {${total*org}} {
+ set cl [lreplace $cl end end]
+ } else {
+ lappend cl *
+ }
+}
+
+proc get/enum-def {s v min max prand} {
+ set nvalues [expr {$max-$min+1}]
+ upvar #0 "enum/choice-list/$s-${v}($nvalues $prand)" cl
+ if {![info exists cl]} { enum-prepare-choice-list $s $v $nvalues $prand }
+ set rv [eval choice-mult $cl]
+ if {"$rv" == "*"} { set rv [choice-int $min $max] }