-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathprotocol.nls
More file actions
721 lines (519 loc) · 18.7 KB
/
Copy pathprotocol.nls
File metadata and controls
721 lines (519 loc) · 18.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
; holds the reporters and procedures needed for the BehaviorSpace runs
; if `necessary-convergence` is selected in the interface and at least one
; theory is fully red this procedure determines which situation the run is in:
; case 1: some scientists are on non-red theories or case 2: all scientists are
; on red theories
to exit-case-distinction
let exit-case-cache 0
ifelse sum [myscientists] of g-red-theories = scientists [
set exit-case-cache 2
][
set exit-case-cache 1
]
if exit-case-cache != g-exit-case [
if g-exit-case != 0 [
set-exit-case-duration g-exit-case
]
set-exit-case-start exit-case-cache
set g-exit-case exit-case-cache
if exit-case-cache = 1 [
reset-static-phase
]
]
end
; records the duration of exit-case 1 & 2 during the run
; argument: case = which exit-case just ended, type: integer
to set-exit-case-duration [case]
set case (case - 1)
let last-exit-case-start last item case g-exit-case-start
let new-duration (ticks - last-exit-case-start)
set g-exit-case-duration lput-subitem case g-exit-case-duration new-duration
end
; if the static phase changed to zero the active-colla-networks need to be reset
; as well
to reset-static-phase
set g-static-phase 0
set g-active-colla-networks colla-networks
end
; records the time-point at which an exit-case begins during the run
; argument: case = which exit-case begins now, type: integer
to set-exit-case-start [case]
set case (case - 1)
set g-exit-case-start lput-subitem case g-exit-case-start ticks
end
; Inserts a value at the end of a list which is nested in another list
to-report lput-subitem [index lists value]
let old-sublist item index lists
report replace-item index lists (lput value old-sublist)
end
; records the durations of the convergences during the run
; argument: present-time = the time-point at which the last convergence ended,
; type: integer
to set-convergence-duration [present-time]
if last-converged-th != -1 [
let new-duration (present-time - last g-convergence-start)
set g-convergence-duration lput new-duration g-convergence-duration
]
end
; records the durations during the run when the best theory was not populated
; argument: present-time = the time-point at which best theory got populated,
; type: integer
to set-non-on-best-duration [present-time]
if not none-before [
let new-duration (present-time - last g-none-on-best-start)
set g-none-on-best-duration lput new-duration g-none-on-best-duration
]
end
; the exit-condition determines when a given run is considered to be finished.
; In case `necessary-convergence` is selected in the interface a run is
; finished as soon as all researchers converge on the best theory. Otherwise a
; run is finished as soon as there exists one theory which is fully discovered
; (i.e. has only red arguments). In any case a run will be aborted when it
; hits the global time limit. A run will also be immediately terminated if
; `necessary-convergence` is selected and there is more than one theory with
; maximal admissibility. These runs must then be filtered from the dataset.
to-report exit-condition
if ticks >= g-max-ticks [
report true
]
ifelse necessary-convergence [
if (g-exit-case > 0 and [myscientists] of (start 0) = scientists and
not any? researchers with [social-action != "biased-deceptive" and
not member? (start 0) cur-best-th]) or
(count starts with-max [objective-admissibility] > 1) [
report true
]
][
if any? g-red-theories [
report true
]
]
report false
end
; as soon as a run is finished (cf. exit-condition) researchers can one final
; time jump to a best theory (ignoring the `jump-threshold`) if
; they’re not already on a theory they consider best. To determine what their
; final best theories are, they do a final update of their memory, share with
; their group and do an admissibility calculation.
to final-commands
ask researchers [update-memories nobody]
share-with-group
compute-subjective-attacked
ask researchers with [social-action != "biased-deceptive"
and not member? [mytheory] of mygps cur-best-th][
move-to-nextargu one-of cur-best-th
set times-jumped times-jumped + 1
]
compute-popularity true
end
to-report monist-success
let popularity []
let find-good-m 0
ask starts [
set popularity lput myscientists popularity
]
ask start 0 [
if max popularity = myscientists and max popularity = scientists [
set find-good-m 1
]
]
report find-good-m
end
to-report pluralist-success
let popularity []
let find-good-p 0
ask starts [
set popularity lput myscientists popularity
]
ask start 0 [
if max popularity = myscientists [
set find-good-p 1
]
]
report find-good-p
end
to-report average-jumps
let jumps 0
let avgjumps 0
ask researchers with [social-action != "biased-deceptive"][
set jumps times-jumped + jumps
]
set avgjumps (jumps / scientists)
report avgjumps
end
to-report perc-landscape-discoverd
let tot-arguments count startsargum
let disc-arguments count startsargum with [
color != gray and color != turquoise]
let perc-disc-argu ((disc-arguments / tot-arguments) * 100)
report perc-disc-argu
end
to-report perc-best-th-discoverd
let tot-best-arguments count startsargum with [mytheory = start 0]
let disc-best-arguments count startsargum with [
mytheory = start 0 and color != gray and color != turquoise]
let perc-disc-best-argu ((disc-best-arguments / tot-best-arguments) * 100)
report perc-disc-best-argu
end
to-report translate-from-string [string]
let value-to-report 0
if string = "th1" [
report item 0 sort starts
]
if string = "th2" [
report item 1 sort starts
]
if string = "th3" [
if number-of-theories < 3 [
report false
]
report item 2 sort starts
]
end
; reports the objective admissibility of th#
to-report objective-admiss-of [th#]
set th# translate-from-string th#
if th# = false [
report 0
]
report [objective-admissibility] of th#
end
; reports time researchers spent on th#:
; "monist" - cf. `research-time-monist`
; or time researchers considered theory th# to be a best theory:
; "pluralist" - cf. `research-time-pluralist`
to-report research-time [pluralist-monist th#]
ifelse pluralist-monist = "monist" [
set pluralist-monist [ -> research-time-monist]
][
set pluralist-monist [ -> research-time-pluralist]
]
set th# translate-from-string th#
if th# = false [
report 0
]
report [runresult pluralist-monist] of th#
end
; reports the number of researchers on th# at the end of the run ("monist")
; or the number of scientists who consider th# to be a best theory ("pluralist")
; i.e. it reports the `myscientists`- ("monist") or the
; `myscientists-pluralist`-value ("pluralist") (cf. Variables)
to-report run-end-scientists [pluralist-monist th#]
ifelse pluralist-monist = "monist" [
set pluralist-monist [ -> myscientists]
][
set pluralist-monist [ -> myscientists-pluralist]
]
set th# translate-from-string th#
if th# = false [
report 0
]
report [runresult pluralist-monist] of th#
end
; This metric tracks how well researchers perform during a run as opposed to
; 'at the end' - and therefore also after - a run like the
; `pluralist-/monist-success` metric does. It also takes the objective
; admissibility of the landscape into account and is normalized to a [0,100]
; interval where 100 corresponds to the best performance.
; For details cf. documentation
to-report in-run-performance [pluralist-monist]
if g-comp-pop-counter = 0 [
report 0
]
ifelse pluralist-monist = "monist" [
set pluralist-monist [ -> research-time-monist]
][
set pluralist-monist [ -> research-time-pluralist]
]
let performance 0
ask starts [
set performance (performance
+ runresult pluralist-monist * objective-admissibility)
]
set performance ((performance * 100) / (scientists *
g-comp-pop-counter * [objective-admissibility] of first sort starts))
report performance
end
; reports how many scientists were on each theory at the start of the run
to-report run-start-scientists [th#]
set th# translate-from-string th#
if th# = false [
report 0
]
report [initial-scientists] of th#
end
; reports the percentage of arguments which are known to an average researcher.
; Either for the whole landscape (argument = "all") or for the best theory only
; (argument = "best")
to-report perc-subj-disc-argu [best-all]
let tot-arguments 0
ifelse best-all = "all" [
set tot-arguments startsargum
][
set tot-arguments startsargum with [mytheory = (start 0)]
]
let #groups colla-groups
let max-score count tot-arguments * #groups
if max-score = 0 [
report 100
]
let realized-score 0
ask tot-arguments [
set realized-score realized-score + length filter [subj-color ->
subj-color < cyan] group-color-mem
]
report realized-score / max-score * 100
end
; reports the percentage of attacks which are known to an average researcher.
; Either for the whole landscape (argument = "all") or from the best theory only
; (argument = "best")
to-report perc-subj-disc-attacks [best-all]
let tot-attacks 0
ifelse best-all = "all" [
set tot-attacks attacks
][
set tot-attacks attacks with [mytheory-end1 = (start 0)]
]
let #groups colla-groups
let max-score count tot-attacks * #groups
if max-score = 0 [
report 100
]
let realized-score 0
ask tot-attacks [
set realized-score realized-score + length filter [subj-known ->
subj-known = true] in-group-i-memory
]
report realized-score / max-score * 100
end
; reports the input value (communication costs) in the form: communication costs
; in days per researcher
to-report normalize-days-per-scientist [input]
let normalization-factor (1 / (all-scientists * max-learn))
report input * normalization-factor
end
; reports the cumulative communication costs per researcher in days
to-report cum-com-costs
report normalize-days-per-scientist g-cum-com-costs
end
; reports the maximal communication costs per researcher in days
; (argument = "value") or the round in which the maximal communication occurred
; (argument = "round")
to-report max-com-costs [round-value]
ifelse round-value = "value"[
report normalize-days-per-scientist item 0 g-max-com-costs
][
report item 1 g-max-com-costs
]
end
; reports the unpaid communication costs per researcher in days
to-report unpaid-com-costs
report normalize-days-per-scientist g-unpaid-com-costs
end
; This procedure draws a heatmap where the brightness of a patch is proportional
; to the proportion of researcher which know the arguments (and optionally
; attacks) concerning this patch.
; This procedure is intended to be used for visualization purposes and is not
; recommended in its current form for performance critical applications
; argument: including-attacks?, type: boolean
; whether or not knowledge about the attack relations connected to
; arguments on this patch is taken into account for drawing the heatmap
to heatmap [including-attacks?]
let #groups colla-groups
let sorted-starts sort starts
ask patches with [any? turtles-here][
let my-startsargum-attacks 0
let #my-startsargum-attacks 0
let my-startsargum (turtle-set arguments-here starts-here)
if including-attacks? [
set my-startsargum-attacks (link-set [my-attacks] of my-startsargum)
set #my-startsargum-attacks count my-startsargum-attacks
]
let #my-startsargum count my-startsargum
; In case of ties, the first theory among the tied ones is picked,
; in order to avoid border patches switching colors randomly
let my-theory first sort modes [mytheory] of my-startsargum
let max-score #groups * (#my-startsargum + #my-startsargum-attacks)
let realized-score 0
ask my-startsargum [
set realized-score realized-score + length filter [subj-color ->
subj-color < cyan] group-color-mem
]
if including-attacks? [
ask my-startsargum-attacks [
set realized-score realized-score + length filter [subj-known ->
subj-known = true] in-group-i-memory
]
]
let my-color 0
ifelse my-theory = item 0 sorted-starts [
set my-color red
][
ifelse my-theory = item 1 sorted-starts [
set my-color turquoise
][
set my-color green
]
]
set pcolor scale-color my-color realized-score 0 max-score
]
end
; knowledge and belief tracking during the run . Called during
; `set-current-theory-info`. Arguments:
; #theory: which theory is currently processed (integer)
; #non-admiss-argu: number of non admissible arguments for the current theory
; (integer)
; curtheory: the (start x) for the current theory (turtle)
to track-knowledge [#theory #non-admiss-argu curtheory]
let cur-group-id group-id
let known-args subjective-arguments with [mytheory = curtheory]
let #known-args count known-args
; division by 10 to keep numbers compact as colors are multiple of 10
let knowledge sum [(cyan - item cur-group-id group-color-mem) / 10] of
known-args
let #defargs #known-args - #non-admiss-argu
; the +1 for #theory is for readability: so the first theory is named "1"
let new-knowledge-entry (list (ticks + 1) cur-group-id (#theory + 1) #defargs
#known-args knowledge)
set g-knowledge lput new-knowledge-entry g-knowledge
end
; saves the information tracked by `track-knowledge` during the run to a csv
; file at the end of the run
to save-tracked-knowledge
let sorted-admissibility map [start-x -> [objective-admissibility] of start-x]
sort starts
let random-start one-of starts
let #args-per-th count startsargum with [mytheory = (random-start)]
let filename behaviorspace-experiment-name
set filename (word filename "-in-run-knowledge.csv")
file-open filename
foreach g-knowledge [curentry ->
let cur-th-admiss item (item 2 curentry - 1) sorted-admissibility
; concatenating the lists this way was fastest in some quick profiling
; file-output takes ~5 times as long as concatenating itself
set curentry (sentence behaviorspace-run-number #args-per-th cur-th-admiss
curentry)
file-print csv:to-row curentry
]
file-close
end
; reports the cumulative time the run stayed in the particular exit-case
; argument: case = for which exit-case the duration should be reported,
; type: integer
to-report cum-exit-case-duration [case]
set case (case - 1)
report sum item case g-exit-case-duration
end
; reports how many periods of the particular exit-case occurred during the run
; argument: case = for which exit-case the frequency should be reported,
; type: integer
to-report frequency-exit-case [case]
set case (case - 1)
report length item case g-exit-case-duration
end
; reports when the first red theory appeared in the landscape during the run
; i.e. when "g-exit-case = 0" ended
to-report time-of-first-red-theory
; making a non-nested list out of g-exit-case-start
let reduced-case-starts reduce sentence g-exit-case-start
if empty? reduced-case-starts [
report ticks
]
report min reduced-case-starts
end
; reports the cumulative time researchers were converged (=all on the same
; theory) during the run
to-report cum-convergence-duration
report sum g-convergence-duration
end
; reports how many periods of convergence (=all researchers continuously on the
; same theory) occurred during the run
to-report frequency-convergence
report length g-convergence-duration
end
; reports how often during the run convergence flipped from being on one theory
; directly to another theory without any diversity period in between
to-report frequency-convergence-flips
if empty? g-convergence-duration [
report 0
]
let convergence-end (map + g-convergence-start g-convergence-duration)
let flip-freq length filter [curentry -> member? curentry g-convergence-start]
convergence-end
; the last convergence in the last round of the run (if it happens) is not a
; convergence flip (although a 2nd to last convergence happening there can be)
if last g-convergence-duration = 0 [
set flip-freq flip-freq - 1
]
report flip-freq
end
; reports the cumulative time no researchers were on the best theory
to-report cum-none-on-best-duration
report sum g-none-on-best-duration
end
; reports how many periods there where no agents on the best theory
to-report frequency-none-on-best
report length g-convergence-duration
end
; calculates the when diversity existed during the run. Diversity is defined as
; having at least one researcher on the best theory and at least one researcher
; on any of the other theories
to record-diversity [present-time]
; nob = none on best
let nob-end (map + g-none-on-best-start g-none-on-best-duration)
let nob-start g-none-on-best-start
if empty? nob-start [
set nob-end [0]
]
if empty? nob-start or last nob-end != present-time [
set nob-start lput present-time nob-start
]
if last nob-end = present-time [
set nob-end but-last nob-end
]
ifelse first nob-start = 0 [
set nob-start but-first nob-start
][
if empty? nob-end or first nob-end != 0 [
set nob-end fput 0 nob-end
]
]
let cur-pos 0
foreach nob-end [cur-end ->
let next-nob-start item cur-pos nob-start
set g-diversity-start lput cur-end g-diversity-start
let interrupting-convergence-start filter [cur-conv ->
cur-conv >= cur-end and cur-conv < next-nob-start
] g-convergence-start
foreach interrupting-convergence-start [cur-int-start ->
let cur-div-duration cur-int-start - last g-diversity-start
set g-diversity-duration lput cur-div-duration g-diversity-duration
let cur-int-pos position cur-int-start g-convergence-start
let cur-int-end cur-int-start + item cur-int-pos g-convergence-duration
set g-diversity-start lput cur-int-end g-diversity-start
]
let last-interval-duration next-nob-start - last g-diversity-start
set g-diversity-duration lput last-interval-duration g-diversity-duration
set cur-pos cur-pos + 1
]
; cleanup all the 0 length diversity entries
set cur-pos 0
foreach g-diversity-duration [cur-div-duration ->
if cur-div-duration = 0 [
set g-diversity-start replace-item cur-pos g-diversity-start -1
]
set cur-pos cur-pos + 1
]
set g-diversity-duration filter [cur-div-duration ->
cur-div-duration != 0] g-diversity-duration
set g-diversity-start filter [cur-div-start ->
cur-div-start != -1] g-diversity-start
end
; reports the cumulative time diversity existed during the run
to-report cum-diversity-duration
report sum g-diversity-duration
end
; reports how many periods of diversity existed during the run
to-report frequency-diversity
report length g-diversity-duration
end