135
141
void cb_perm(int *data, int count, void *arg, float farg) {
136
142
struct val_list **pret = (struct val_list**)arg;
137
struct val_list *current = (struct val_list*)malloc(sizeof(struct val_list));
138
current->count = count;
139
current->values = (int*)malloc(current->count * sizeof(int));
143
struct val_list *current = list_new(count, farg);
140
144
memcpy(current->values, data, current->count * sizeof(int));
141
current->next = NULL;
142
current->prob = farg;
143
145
// XXX pass this from the tree instead of using caring all the time
144
146
// or even better, don't do the permutations if we don't care about the
146
148
list_add(pret, current, caring);
150
#line 3 "optimize.tc"
156
#define MINFLOAT 0.0000001
159
// this is taken from http://en.wikipedia.org/wiki/Dice
160
// calculates the probability for value "pos" in the sum of "num"
161
// dice with "sides" faces
162
double Fsumdice(double *cache, int mnum, int num, int sides, int pos) {
163
if (pos > ((num*sides-num)/2)+num) {
164
pos = num*sides - pos + num;
168
if ((pos < 1) || (pos > sides)) {
178
if (cache[mnum*(pos-num)+num] < -0.5) {
180
for (i = 1; i < min(pos, sides+1); i++) {
181
ret += Fsumdice(cache, mnum, 1, sides, i)
182
* Fsumdice(cache, mnum, num-1, sides, pos-i);
184
cache[mnum*(pos-num)+num] = ret;
187
return cache[mnum*(pos-num)+num];
191
// calculates the probability that the sum of "num" rolls of
192
// distribution "dist" have the value "pos"
193
double Fsumany(double *cache, int mnum, int minval, int maxval, int num,
194
struct val_list *dist, int pos) {
195
struct val_list *cdist = dist;
198
if (cdist->values[0] == pos) {
206
int cpos = pos*mnum+num;
207
if ((pos < minval * num) || (pos > maxval * pos)) {
210
if (cache[cpos] < -0.5) {
213
ret += cdist->prob * Fsumany(cache, mnum, minval, maxval,
214
num - 1, dist, pos - cdist->values[0]);
150
226
#define YYNODESTATE_TRACK_LINES 1
151
227
#line 1 "c_skel.c"
773
876
(void (*)(expression *this__, struct symtab * st))variable_set_symtab__,
774
877
(void (*)(expression *this__, ordering_type ordering))variable_set_ordering__,
775
878
(struct val_list * (*)(expression *this__))variable_eval__,
879
(expression * (*)(expression *this__))expression_optimize__,
882
void sumrepdice_printtree__(sumrepdice *this, int depth)
883
#line 89 "optimize.tc"
885
// unsupported, only used in eval
889
struct roll_value * sumrepdice_roll__(sumrepdice *this)
890
#line 85 "optimize.tc"
892
// unsupported, only used in eval
896
void sumrepdice_set_symtab__(sumrepdice *this, struct symtab * st)
897
#line 93 "optimize.tc"
899
// not needed, don't use symtab
903
struct val_list * sumrepdice_eval__(sumrepdice *this)
904
#line 97 "optimize.tc"
907
struct val_list *ret = NULL;
908
struct val_list *cnum = this->num_dice;
910
if (cnum->count != 1) {
911
yyerror("Argument 1 to sumrep operator is not scalar");
912
list_free(this->num_dice);
916
int num_dice_val = cnum->values[0];
917
if (num_dice_val > 0) {
918
int expected = num_dice_val*
919
((num_dice_val*this->num_sides-num_dice_val)/2)
921
double *cache = malloc(sizeof(double) * expected);
922
for (n = 0; n < expected; n++) {
925
for (n = num_dice_val * this->num_sides;
926
n >= num_dice_val; n--) {
927
struct val_list *cret =
928
(struct val_list*)malloc(sizeof(struct val_list));
931
cret->prob = Fsumdice(cache, num_dice_val, num_dice_val,
932
this->num_sides, n) * cnum->prob;
933
cret->values = (int*)malloc(sizeof(int));
935
list_add(&ret, cret, this->ordering);
942
return list_new(1, 1.0);
948
struct sumrepdice_vtable__ const sumrepdice_vt__ = {
952
(void (*)(expression *this__, int depth))sumrepdice_printtree__,
953
(struct roll_value * (*)(expression *this__))sumrepdice_roll__,
954
(void (*)(expression *this__, struct symtab * st))sumrepdice_set_symtab__,
955
(void (*)(expression *this__, ordering_type ordering))expression_set_ordering__,
956
(struct val_list * (*)(expression *this__))sumrepdice_eval__,
957
(expression * (*)(expression *this__))expression_optimize__,
960
void sumrepany_printtree__(sumrepany *this, int depth)
961
#line 149 "optimize.tc"
963
// unsupported, only used in eval
967
struct roll_value * sumrepany_roll__(sumrepany *this)
968
#line 145 "optimize.tc"
970
// unsupported, only used in eval
974
void sumrepany_set_symtab__(sumrepany *this, struct symtab * st)
975
#line 153 "optimize.tc"
977
// not needed, don't use symtab
981
struct val_list * sumrepany_eval__(sumrepany *this)
982
#line 157 "optimize.tc"
985
struct val_list *ret = NULL;
986
struct val_list *cnum = this->number;
989
struct val_list *cval = this->data;
991
if ((minval == -1) || (cval->values[0] < minval)) {
992
minval = cval->values[0];
994
if (cval->values[0] > maxval) {
995
maxval = cval->values[0];
1000
if (cnum->count != 1) {
1001
yyerror("Argument 1 to sumrep operator is not scalar");
1002
list_free(this->number);
1003
list_free(this->data);
1007
if (cnum->values[0] == 0) {
1008
struct val_list *cret =
1009
(struct val_list*)malloc(sizeof(struct val_list));
1012
cret->prob = cnum->prob;
1013
cret->values = (int*)malloc(sizeof(int));
1014
cret->values[0] = 0;
1015
list_add(&ret, cret, this->ordering);
1018
int expected = (cnum->values[0] * maxval + 1) * cnum->values[0] + 1;
1019
double *cache = malloc(sizeof(double) * expected);
1020
for (n = 0; n < expected; n++) {
1023
for (n = cnum->values[0] * minval; n <= cnum->values[0] * maxval; n++) {
1024
struct val_list *cret =
1025
(struct val_list*)malloc(sizeof(struct val_list));
1028
cret->prob = Fsumany(cache, cnum->values[0], minval, maxval,
1029
cnum->values[0], this->data, n) * cnum->prob;
1030
cret->values = (int*)malloc(sizeof(int));
1031
cret->values[0] = n;
1032
if (cret->prob > MINFLOAT) {
1033
list_add(&ret, cret, this->ordering);
1044
return list_new(1, 1.0);
1050
struct sumrepany_vtable__ const sumrepany_vt__ = {
1054
(void (*)(expression *this__, int depth))sumrepany_printtree__,
1055
(struct roll_value * (*)(expression *this__))sumrepany_roll__,
1056
(void (*)(expression *this__, struct symtab * st))sumrepany_set_symtab__,
1057
(void (*)(expression *this__, ordering_type ordering))expression_set_ordering__,
1058
(struct val_list * (*)(expression *this__))sumrepany_eval__,
1059
(expression * (*)(expression *this__))expression_optimize__,
778
1062
void mathop_printtree__(mathop *this, int depth)
2047
2316
struct val_list *cret = (struct val_list*)
2048
2317
malloc(sizeof(struct val_list));
2049
2318
cret->next = NULL;
2320
// ready, start the actual filtering:
2321
// we want up to cnum->values[0] items from cexp in cret
2050
2323
int *slist = (int*)malloc(sizeof(int) * cexp->count);
2324
int *mask = (int*)malloc(sizeof(int) * cexp->count);
2051
2325
memcpy(slist, cexp->values, sizeof(int) * cexp->count);
2326
memset(mask, 0, sizeof(int) * cexp->count);
2052
2327
quicksort(slist, 0, cexp->count - 1);
2328
reverse(slist, 0, cexp->count - 1);
2054
2331
if (this->type == keep) {
2332
// how many do we want?
2055
2333
cret->count = min(cexp->count, cnum->values[0]);
2056
2334
cret->values = (int*)malloc(sizeof(int) * cret->count);
2057
2336
for (i = 0; (i < cexp->count) && (p < cnum->values[0]); i++) {
2058
2337
int j, found = 0;
2059
for (j = cexp->count - 1;
2060
j >= cexp->count - cnum->values[0]; j--) {
2061
if (cexp->values[i] == slist[j]) {
2338
for (j = 0; j < cnum->values[0]; j++) {
2339
if ((cexp->values[i] == slist[j]) && (!mask[j])) {
2225
2494
struct val_list *cret = (struct val_list*)
2226
2495
malloc(sizeof(struct val_list));
2227
2496
cret->next = NULL;
2498
// ready, start the actual filtering:
2499
// we want up to cnum->values[0] items from cexp in cret
2228
2501
int *slist = (int*)malloc(sizeof(int) * cexp->count);
2229
2502
int *mask = (int*)malloc(sizeof(int) * cexp->count);
2230
2503
memcpy(slist, cexp->values, sizeof(int) * cexp->count);
2231
2504
memset(mask, 0, sizeof(int) * cexp->count);
2232
2505
quicksort(slist, 0, cexp->count - 1);
2234
2508
if (this->type == keep) {
2509
// how many do we want?
2235
2510
cret->count = min(cexp->count, cnum->values[0]);
2236
2511
cret->values = (int*)malloc(sizeof(int) * cret->count);
2237
2513
for (i = 0; (i < cexp->count) && (p < cnum->values[0]); i++) {
2238
2514
int j, found = 0;
2239
2515
for (j = 0; j < cnum->values[0]; j++) {
2240
if (cexp->values[i] == slist[j]) {
2516
if ((cexp->values[i] == slist[j]) && (!mask[j])) {
2642
2915
for (i = 0; i < cside->count; i++) {
2643
2916
sum += cside->values[i];
2645
struct val_list *cret = (struct val_list*)
2646
malloc(sizeof(struct val_list));
2648
cret->values = (int*)malloc(sizeof(int));
2918
struct val_list *cret = list_new(1, cside->prob);
2649
2919
cret->values[0] = sum;
2651
cret->prob = cside->prob;
2652
2920
list_add(&ret, cret, this->ordering);
2653
2921
cside = cside->next;
2655
2923
list_free(sides);
2928
expression * sum_optimize__(sum *this)
2929
#line 251 "optimize.tc"
2931
if (yykind(this->expr) == rep_kind) {
2932
rep *crep = (rep*)this->expr;
2933
if (yykind(crep->expr2) == dice_kind) {
2934
dice *cdice = (dice*)crep->expr2;
2935
if (yykind(cdice->expr) == number_kind) {
2937
expression *replace = sumrepdice_create(
2939
((number*)cdice->expr)->num);
2945
expression *replace = sumrepany_create(
2947
eval(sum_create(crep->expr2)));
2951
return (expression*)this;
2660
2955
struct sum_vtable__ const sum_vt__ = {
3028
3320
return (expression *)node__;
3323
expression *sumrepdice_create(struct val_list * num_dice, int num_sides)
3325
sumrepdice *node__ = (sumrepdice *)yynodealloc(sizeof(struct sumrepdice__));
3326
if(node__ == 0) return 0;
3327
node__->vtable__ = &sumrepdice_vt__;
3328
node__->kind__ = sumrepdice_kind;
3329
node__->filename__ = yycurrfilename();
3330
node__->linenum__ = yycurrlinenum();
3331
node__->symtab = NULL;
3332
node__->ordering = caring;
3333
node__->num_dice = num_dice;
3334
node__->num_sides = num_sides;
3335
return (expression *)node__;
3338
expression *sumrepany_create(struct val_list * number, struct val_list * data)
3340
sumrepany *node__ = (sumrepany *)yynodealloc(sizeof(struct sumrepany__));
3341
if(node__ == 0) return 0;
3342
node__->vtable__ = &sumrepany_vt__;
3343
node__->kind__ = sumrepany_kind;
3344
node__->filename__ = yycurrfilename();
3345
node__->linenum__ = yycurrlinenum();
3346
node__->symtab = NULL;
3347
node__->ordering = caring;
3348
node__->number = number;
3349
node__->data = data;
3350
return (expression *)node__;
3031
3353
expression *scat_create(expression * expr1, expression * expr2)
3033
3355
scat *node__ = (scat *)yynodealloc(sizeof(struct scat__));