An Agent-based Model of Small-group Discussion

An Agent-based Model of Small-group Discussion preview image

1 collaborator

Jemc John McEneaney (Author)

Tags

discussion 

Tagged by John McEneaney 6 months ago

education 

Tagged by John McEneaney 6 months ago

learning theory 

Tagged by John McEneaney 6 months ago

small-group interaction 

Tagged by John McEneaney 6 months ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.4.0 • Viewed 405 times • Downloaded 68 times • Run 0 times
Download the 'An Agent-based Model of Small-group Discussion' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


QUICK REFERENCE

Operational Controls Setup - Resets all simulation parameters for a new run Next - Completes a single simulation cycle Go - Starts (and Stops) a specififed number of simulation cycles

Simulation Settings transactions - Number of cycles the Go button will run triad proportion - sets proportion of Triad and Dyad transactions competitivity - sets the overall level of competition for a discussion competitive tolerance - sets sensivity of agents to engage in competition cooperativity - sets the overall level of cooperation for a discussion cooperative tolerance - sets sensivity of agents to engage in cooperation teacher talk - sets probability the teacher will be a source (random otherwise) fixed inst activity - sets teacher activity in a simulation to a fixed value fixed inst discursivity - sets teacher discursivity in a simulation to a fixed value

WHAT IS IT?

This model (version 2.2) simulates both teacher-led and independent student-led small group discussions. The main difference between this model and prior work is that this model distinguishes between student and teacher roles and, as a result, pedagogical strategies can be simulated as well as the traditional approach of modeling a population of discussion agents. In this model, agents have beliefs about their own and other agents' states. Moreover, these beliefs change as a result of transactions during a discussion. The model simulates transactions incorporating both competition and cooperation as factors shaping small-group discussion. Broadly, this model provides a theoretical window on individual and group development of task engagement (activity) and social engagement (discursivity) with peers in independent and teacher-moderated small-group discussion.

HOW IT WORKS

The model simulates a teacher and class of 5 students participating in an open student centered discussion focused on a learning outcome. In this simulation, a discussion is a sequence of verbal transactions. Transactions occur when two or more agents enagage in a verbal transaction. A transaction includes a Source Agent (source) who speaks and one or two Target Agent(s) (target/primary) with whom the Source interacts. A transaction engaging two agents is referred to as a dyadic transaction (e.g., [A B]). A transaction that includes three agents is a triadic transaction (e.g., [A [B C]]) with one source (A) and two targets, a primary target (B) and a collateral target (C). In addition, a triadic transaction adds a third collateral agent that enhances opportunities for students to to develop larger and more interactive discussion groups that include three or more members.

A discussion consists of a sequence of transactions that include two, three, or more discussants. The simulation, however, explicitly represents only dyadic and triadic transaction. Although starting with these two types of transactions, the simulation routinely leads to subgroups of two or more discussants in classes of 5 or more students. Proportions of dyadic and triadic transactions are determined by an interface widget (triad_proportion). In addition to adjusting proportions of transaction types in the discussion, the teacher role is parameterized to allow a more active role in shaping the discussion through either increased probability of assuming a source agent role or through the use of teacher redirects targetting specific students whose activity or discursivitiy levels are low. Although teacher redirects may offer substantive contributions to the discussion, the primary goal of a redirect is to address individual needs or difficulties at a meta-conversational level by promting more active task or social enagagement in the targetted student. In effect, the teacher leads the discussion by shaping the broader patterns of transactions, with the goal of keeping all students engaged with both the discussion task and with other discussants. Learning in the discussion is influenced by both a student's general disposition to be task-engaged and more specific dispositions to interact with classmates in the discussion.

Simulation dynamics revolve around the ways agent beliefs change as a result of discussion transactions. Agents have beliefs both about their own capacity to engage in discussion (activity) and in their dispositions to engage with other agents (discursivities). When agents engage in a transaction, the probability a transaction will lead an agent to change its belief state depends both on stochastic model parameters and on the belief states of the agents participating in the transaction. Agents may enagage in competitive transactions, cooperative transactions, hybrid transactions that incorporate both or "null" transactions that do not change agent beliefs.

Six charts depict agent data during the discussion. One at the bottom left charts the activity levels of all agents (i.e., both the teacher and all students). This activity variable is interpreted as representing an agent's likelihood or inclination to initiate a transaction during the discussion. Other charts depict the discursivity of each student toward the other four students, where discursivity refers to the likelihood or inclination of a student to address another specific student in a transaction. As a student's inclination to socially engage with a specific peer declines, the line depicting the discursivity toward that agent also declines. If an agent's discursivity toward another increases, that line will turn upwards. The discussion graph depicted in the agent view panel also displays these relationships. When an agent has stronger discursivity toward another agent, the arrow from that agent to the other is brighter. As discursivities decline, arrows become dimmer. If a student loses interest in social engagement with peers, other agents will tend to reciprocate and the student may become a social isolate; they are no longer involved in transactions that inform or otherwise change their views. Although that student may still be engaged in the task (i.e., their activity is good), they are not engaging in social interaction, relying instead exclusively on individualistic learning. At this point, they have largely ceased to influence their peers and their peers no longer influence them - they have assumed a stance of non-interdependence.

HOW TO USE IT

Press SETUP to initialize the simulation run. Five students (Nell, Max, Jana, Sally, & Rich) are arrayed in an circle with the teacher (John) at the top. Output from the simulation is displayed in the text field to the left of the discussion window. Ticks refers to the simulation clock, with one discussion transaction occuring during each tick. Dyadic transactions take the form: [source target]. Triadic transactions take the form [source [primary collateral]]. All agents in transactions are identified by their agent numbers indicated in parentheses besdie their names. At each tick, the current transaction is displayed in the center of the discussion window, within the arc of students.

Clicking the NEXT button advances the simulation by one step. A step-by-step simulation helps users see how the simulation actually works since the text appearing in the output window is a current record of all of the transactions that make up the current discussion. Clicking the GO button advances the simulation automatically the number of steps selected by the transactions widget. Manually advancing the simulation better illustrates how the simulation works, while the GO button is more convenient for observing outcomes and broader patterns.

As the simulation progresses, environmental variables are updated to the lower right of the discussion web display window. Environmental variables in this version include student activity and discursivity means and activity/discursivity rankings that a teacher can use to target specific student agents for direct teacher intervention. The first agent listed in each ranking indicates the student in the class with the lowest level of activity or discursivity in each cycle. I experimented with direct teacher intervetions targeting specific student using activity and discursivity but did not find circumstances where these targetted interventions had a statistically significant impact on the dicussion as a whole, so I don't know whether this kind of intevention will be useful. I have, however, retained the code supporting redirect interventions thinking others might be interested in exploring this issue.

A student agent's initial activity level is a random variable drawn from a uniform distribution that ranges from 0.333 to 0.667. Each time a student engages in a transaction, that student's activity level and discursivity toward other agents may change, although whether or not change occurs is a stochastic event that depends on the belief states of agents involved. Face icons for studnet agents are based on agent "happiness," a weighted average of activity and discursivity levels. Students with happiness levels > .5 are smiling. Those with activity levels between .4 and .5 are neutral and those with lower levels are frowning. The happiness of the teacher is the happiness average for all students in the class.

As the discussion plays out, broader patterns of student activity and discursivity often become apparent. As noted previously, some students may join sub-groups and limit their interaction with others to specific individuals. In other instances, the entire class of 5 may enagge in a highly active and open discussion that enages all five students. In other instances one or more individuals may "drop out" of the discussion. These possibilities depend on both random and user-mainpulable parameters, some set by the green slider bars in the interface. The character of the discussion as a whole is a consequence of the patterns of transactions that make up the discussion.

The goal of this simulation is to help us explore how parameters that can be adjusted with the sliders influence the patterns that emerge. In addition, the simulation can be used to test specific hypotheses about how individual attributes and transactional patterns influence the development and ultimate stabilization of the discussion patterns. At the conclusion of the discussion, the output window will include a row of data for each transaction in the discussion. In addition, if a transaction involves a teacher redirect, that is indicated as well.

THINGS TO NOTICE

Although the overall_sensitivity (OS) parameter that defines individual agents' capacity for learning is randomly assigned and not user-manipulable, note how low (e.g., .05) or high (e.g., .35) values influence agent learning. Click the Reset button repeatedly to resample OS values until you get a particularly low or high value. OS values are displayed in the lower left-hand corner of each agents discursivity display.

Setting competitivity greater than cooperativity tends to promote wider dispersion of discursivities across agents. Setting cooperativity greater than competitivity generally reduces dispersion of discursivity values and tends to produce larger discursivity overall.

Notice that sometimes several (or all) students' activities and discursivities tend to follow the same general track. What do you think this means? Is this a good thing? How do the user-adjustable parameters set by sliders influence the patterns displayed in charts?

THINGS TO TRY

Consider replicating the simulations studies I describe in Part 3 of Appendix A in the PT model paper (McEneaney, in press).

In order to get a more general feel for the model, consider experimenting with the competitivity and cooperativity sliders to get a sense for how competition and cooperation influence group dynamics and transactional patterns. Note as well that you can start a discussion with one set of parameters and, when the discussion has developed in response to those settings, stop the simulation and change parameters so that students are nudged into new patterns of interaction.

McEneaney, J. E. (in press). A Pedagogically Oriented Agent-Based Model of Small-Group Discussion. AERA Open.

RELATED MODELS AND WHAT DISTINGUISHES THE PRESENT WORK

This model draws on ideas developed by Koponen & Nousiainen in two recently developed models (Koponen & Nousiainen, 2016 & 2018) and is described in much greater detail in an open access research manuscript published in AERA Open (McEneaney, 2025). Key ideas I have drawn from K&N are formal mechanisms to support agent competition and cooperation as factors influencing patterns of transactions. The major novel contributions of this model are that it 1) defines discussion in pedagogical terms, 2) distinguishes student and teacher roles, 3) extends agent learning to all agents in transactions, and 4) highlights the development of discussion patterns across time and in graph theoretic terms as opposed to more abstract analyses based on the triad census.

Koponen, I. T. & Nousiainen, M. (2018). An Agent-Based Model of Discourse Pattern Formation in Small Groups of Competing and Cooperating Members. Journal of Artificial Societies and Social Simulation 21(2). Doi: 10.18564/jasss.3648 Url: http://jasss.soc.surrey.ac.uk/21/2/1.html

Koponen, I. T. & Nousiainen, M. (2016). Formation of reciprocal appreciation patterns in small groups: an agent‑based model. Complex Adapt Syst Model, 4:24 DOI 10.1186/s40294-016-0035-6

CREDITS AND REFERENCES

This model was developed using NetLogo (Wilensky, 1999). I also relied on Wilensky and Rand (2015) when I set out to learn about agent-based modeling and the NetLogo simulation environment.

  • Wilensky, U. (1999). NetLogo. http://ccl.northwestern.edu/netlogo/. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.

  • Wilensky, U. & Rand, W. (2015). Introduction to Agent-Based Modeling: Modeling Natural, Social and Engineered Complex Systems with NetLogo. Cambridge, MA. MIT Press.

HOW TO CITE

McEneaney, J. E. (2025). An Agent-based Model of Small-group Discussion (V2.2) [Computer software]. NetLogo Modelling Commons. https://modelingcommons.org/browse/one_model/7563

COPYRIGHT AND LICENSE

Copyright 2025 John E. McEneaney.

CC BY-NC-SA 4.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 License. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;
;;   An Agent-based Model of Small-group Discussion (V22)
;;
;; INTERFACE WIDGETS
;; Choosers - Chooser widgets focused on pedagogical modifications *during* a simulation run
;; the inst_protocol and teacher_redirect procedures support modification to simulation parameters *during* a run
;; I did not observe teacher_redirects to have an impact on class levels of performance so they were dropped
;; I continue to use inst_protocol in models, but feel it muddies the clarity of this model, so I removed it from the PT model
;; redirects and instructional protocols can be reintroduced by creating appropriate widgets and modifying the code below.
;; inst_protocol (experimental): supports increasing/decreasing competitivity and cooperativity during a run
;; teacher_redirect (experimental): turns on teacher redirects choosing specific students for transactions
;;
;; Sliders
;; transactions: number of ticks triggered by the GO button
;; triad_proportion: sets proportion of dyad and triad transactions during the simulation
;; adjm_threshold: sets the threshold value for 0/1 in the adjacency matrix produced for use in R
;; activity redirect: adjusts probability a Activity redirect will occur           REMOVE
;; discursivity redirect: adjusts probability a Discursivity redirect will occur   REMOVE
;; fixed_inst_activity: if = 0.0, teacher activity is mean student activity; if != 0.0 teacher activity is slider value
;; fixed_inst_discursivity: if = 0.0, teacher discursivity is mean student discursivity; if != 0.0 teacher activity is slider value
;; competitivity: overall disposition of students to engage in competitive transactions
;; cooperativity: overall disposition of students to engage in cooperative transactions
;; competitive_tolerance: range within which utility function differences trigger belief changes (inverse ZPD?)
;; cooperative_tolerance: range within which utility function differences trigger belief changes (inverse ZPD?)
;;
;; Plots
;; charts depict agent activities in a single chart on the left and agent discursivities in separate charts for each agent on the right.
;;
;; Important Reports
;; R-all       reports an adjacency matrix for all discussants that can be used in R to generate a graph and calculate network metrics
;; R-students  reports an R adjacency matrix for ALL discussants (students & teacher) to generate a graph and calculate network metrics
;; short-class-belief-list                 reports a discursivity matrix for students (used in calculating R-students)
;; mean-discursivity & sigma-discursivity  report mean and sigma values for student discursivity
;; activity-rank
;; class-discursivity-rank
;; student-discursivity-sum reports the sum of student discursivites to four decimal places
;;
;;---------------------------------------------------------------------------------------------------------------------------------

;; GLOBALS AND AGENT DEFINITIONS
globals [                  ;; defines global variables
;; BASIC OPERATIONAL AND INTERFACE VARIABLES
  model                    ;; if model = "PT", concurrent/collateral agents learn, otherwise not
  transaction-patch        ;; patch that displays the current transaction
  environment-patch        ;; patch that displays environment variables
  happy                    ;; activity threshold for an agent to display as "happy"
  neutral                  ;; activity threshold for an agent to display as "neutral"
  adjm_threshold           ;; sets minimum discursivity value for setting an adjacency matrix value = 1
  mu                       ;; mean used in random-normal function
  sigma                    ;; sigma used in random-normal function

;; TRANSACTION VARIABLES
  competitive_tolerance    ;; range within which utility function differences trigger belief changes in competitive transactions
  cooperative_tolerance    ;; range within which utility function differences trigger belief changes in cooperative transactions
  inst_protocol            ;; pedagogical interventions that change during a simulation
  teacher_redirect         ;; pedagogical interventions that target specific students
  activity_redirect        ;; teacher redirect that focuses on student with lowest activity rank
  discursivity_redirect    ;; teacher redirect that focuses on student with lowest discursivity rank
  source_agent             ;; agent that initiates a Dyad or Triad transaction
  target_agent             ;; agent addressed in a Dyad transaction
  primary_agent            ;; primary (P) agent addressed in a Triad transaction
  collateral_agent         ;; collateral (C) agent addressed in a Triad transaction
  triad_target_list        ;; a list [P C] representing primary and collateral targets
  current_transaction_type ;; identifies the type of the curent transaction (dyad or triad)
  current_transaction      ;; identifies the current transaction
  tchint                   ;; identifes a transaction that involves a teacher intervention (e.g., redirect)
  dyad_competition_count   ;;
  dyad_cooperation_count   ;;
  triad_competition_count  ;; these variables are used in tracking numbers of competitive,
  triad_cooperation_count  ;; cooperative, and competitive-cooperative transactions
  dyad_compcoop_count      ;;
  triad_compcoop_count     ;;

;; BELIEF LIST VARIABLES (these variables provide access to beliefs of agents during a transaction)
  source_belief_list       ;; beliefs from source agent used in updating state changes (dyad and triad)
  target_belief_list       ;; beliefs from target agent used in updating state changes (dyad only)
  primary_belief_list      ;; beliefs from primary agent used in updating state changes (triad only)
  collateral_belief_list   ;; beliefs from collateral agent used in updating state changes (triad only)

;; BELIEF VARIABLES ARE MODIFIED 03/20/2023 TO SUPPORT STPC LEARNING
;; BELIEF VARIABLES (these are global, but temporary, variables that change with each transaction - based on KN 2018)
  source_agent_sensitivity     ;; the overall sensitivity of the source agent in the current transaction        STPC
  target_agent_sensitivity     ;; the overall sensitivity of the target agent in the current transaction        STPC
  primary_agent_sensitivity    ;; the overall sensitivity of the primary agent in the current transaction       STPC
  collateral_agent_sensitivity ;; the overall sensitivity of the collateral agent in the current transaction    STPC
  Kii                          ;; activity of the current source agent
  Kij                          ;; discursivity of the current source toward the current target
  Kik                          ;; discursivity of the current source toward the current collateral (triad)
  Kjj                          ;; activity of the current target (dyad) or primary (triad) agent
  Kji                          ;; discursivity of the current target (dyad) or primary (triad) toward the current source
  Kjk                          ;; discusivity of the current primary (triad) toward the current collateral (triad)
  Kkk                          ;; activity of the current collateral agent                                           STPC
  Kki                          ;; discursivity of the current collateral (triad) toward the current source (triad)   STPC
  Kkj                          ;; discursivity of the current collateral (triad) toward the current primary (triad)  STPC
  belief_value                 ;; a belief value variable used in triad census matrix calculations (KN 2018)

;; BELIEF CHANGE VARIABLES ARE MODIFIED 03/20/2023 TO SUPPORT STPC LEARNING
;; BELIEF CHANGE VARIABLES (these are intermediate calculations used in updating beliefs - based on KN 2018)
;;  Spij    (local to function) probability a source agent in a competitive transaction will change belief state                   STPC
;;  Sp*ij   (local to function) probability a source agent in a cooperative transaction will change belief state                   STPC
;;  Tpji    (local to function) probability a target/primary agent in a competitive transaction will change belief state           STPC
;;  Tp*ji   (local to function) probability a target or primary agent in a cooperative transaction will change belief state        STPC
;;  Cpki    (local to function) probability a collateral agent in a competitive transaction will change belief state               STPC
;;  RScomp  (local to function) random float determining whether Source state changes occur in a competitive transaction           STPC
;;  RScoop  (local to function) random float determining whether Source state changes occur in a cooperative transaction           STPC
;;  RTPcomp (local to function) random float determining whether Target/Primary state changes occur in a competitive transaction   STPC
;;  RTPcoop (local to function) random float determining whether Target/Primary state changes occur in a competitive transaction   STPC
;;  RCcomp  (local to function) random float determining whether Collateral state changes occur in a competitive transaction       STPC
  deltaKii                  ;; change in Kii belief resulting from a transaction
  compdeltaKij              ;; change in Kij belief resulting from a competitive transaction
  deltaKik                  ;; change in Kik belief resulting from a transaction
  coopdeltaKij              ;; change in Kij belief resulting from a cooperative transaction
  deltaKjj                  ;; change in Kjj belief resulting from a transaction               STPC
  compdeltaKji              ;; change in Kji belief resulting from a competitive transaction   STPC
  coopdeltaKji              ;; change in Kji belief resulting from a cooperative transaction   STPC
  compdeltaKki              ;; change in Kki belief resulting from a competitive transaction   STPC

;;  BELIEF UPDATE VARIABLES, PARAMETERS, AND CONSTANTS (based on KN 2018)
;;  The first three are set with interface sliders
;;  competitivity              set by slider 0.0 -> 1.0 in steps of 0.05
;;  cooperativity              set by slider 0.0 -> 1.0 in steps of 0.05
;;  competitive_tolerance      set by slider 0.01 -> 1.0 in steps of 0.03
;;  cooperative_tolerance      set by slider 0.01 -> 1.0 in steps of 0.03; a fixed (0.25) agent attribute in KN 2018.
;;  overall_sensitivity        overall_sensitivity (pi-nought in KN 2018) is an agent-specific attribute defined
;;                             in people-own immediately below that is drawn from a uniform distribution
;;                             with mean < 0.3 and sigma = (0.3 * mean) because values within this range are
;;                             stable with variability limited to in iterations to convergence.
  os_mu                        ;; overall_sensitivity mean
  os_sigma                     ;; overall_sensivity sigma
]

breed [ people person ]               ;; defines the type of agents modeled
directed-link-breed [ dlinks dlink ]  ;; defines discursivity links between agents

people-own [             ;; these variables define attributes of people modeled
  role                   ;; role in simulation (student or teacher)
  source_count           ;;
  target_count           ;; These four count variables are used to track reports how frequently
  primary_count          ;; an agent assumes each of the four roles assigned in a transaction
  collateral_count       ;;
  discursivity           ;; social engagement as defined by mean peer discursivity and student mean discursivity for the teacher
  activity               ;; task engagement as defined by activity
  happiness              ;; happiness is an agent's average across its belief state and is used to set facial expressions
  overall_sensitivity    ;; sensitivity of an agent to differences that trigger belief changes
  belief_list            ;; represents an agent's beliefs about its own activity and discursivity toward peers
                         ;; agent activity is indicated by the item corresponding to its person identifier
                         ;; peer discursivity is indicated by items corresponding to their respective person identifiers
                         ;; e.g., [ K00 K01 K02 K03 K04 K05 ] -> for person 0, K00 is activity, K01 is discursivity toward 1, etc.
                         ;; Beliefs, therefore, are defined by their position in the list depending on each individual agent.
]

;;-----------------------------------------------------------------------------------------------

;;SETUP, NEXT, AND GO ROUTINES BEGIN HERE

to setup
  ;; intializes the random number function and resets the simulation
  random-seed new-seed                  ;; seeds the random number generator in each simulation run
  clear-all                             ;; resets simulation data and variables
  ask patches [ set pcolor black ]      ;; colors the background black
  set-default-shape links "new-arrow"   ;; sets default format for links
  ;; initializes global variables
  set model "PT"                        ;; turns on learning by concurrent/collateral agents
  set competitive_tolerance 0.1
  set cooperative_tolerance 0.05
  set inst_protocol "none"
  set teacher_redirect "none"
  set activity_redirect 0
  set discursivity_redirect 0
  set mu 50.0                      ;; sets mean used in random-normal function
  set sigma 7.5                    ;; sets sigma used in random-normal function
  set happy 0.5                    ;; sets happy face threshold
  set neutral 0.4                  ;; sets neutral face threshold
  set adjm_threshold 0.05
  set tchint ""
  set triad_target_list []
  set os_mu 0.2                    ;; mu and sigma define agent-specific overall sensitivity
  set os_sigma 0.06                ;; these parameters are scaled like measures of general ability
  set dyad_competition_count 0
  set dyad_cooperation_count 0
  set triad_competition_count 0
  set triad_cooperation_count 0
  set dyad_compcoop_count 0
  set triad_compcoop_count 0
;;; creates agents, each with a unique screen position, role, and label
  create-people 1 [ set role "teacher" ]  ;; Creates teacher agent 0
  create-people 5 [ set role "student" ]  ;; Creates 5 student agents
  layout-circle sort people 10            ;; sets up the agent transaction graph
  ;; assigns data to other agent attributes
  ask people [
    create-dlinks-to other people
    set color white
    set source_count 0
    set target_count 0
    set primary_count 0
    set collateral_count 0
;;  The code below randomizes agents' overall sensitivity and belief state values and assures os > 0
    set overall_sensitivity random-normal os_mu os_sigma
    if overall_sensitivity <= 0 [set overall_sensitivity .01]
    set belief_list initialize-belief_list
    set happiness update-happiness     ;; revised 03242023
  ]
  update-activity-discursivity
  update-dlinks
  update-environment
  let temp_list (map [ x -> [precision activity 2] of person x ] [1 2 3 4 5])
  output-print (word "Initial Student Activity: " temp_list)
  output-print ""
  output-print "Ticks, Transaction"
  if fixed_inst_activity > 0.0 [ask person 0 [set belief_list replace-item 0 belief_list fixed_inst_activity ]]
  if fixed_inst_discursivity = 0 [ask person 0 [set discursivity mean-discursivity ] ]
  if fixed_inst_discursivity > 0.0
    [foreach [1 2 3 4 5]
      [x -> ask person 0 [set belief_list replace-item x belief_list fixed_inst_discursivity ]]]
  reset-ticks
end 

to next ;; moves the simulation forward one tick
  select-transaction
  set-agent-beliefs
;;  update-transaction
  update-activity-discursivity
  update-dlinks
  update-environment
  ifelse display_transactions [output-print (word ticks ", " current_transaction tchint) ] [ ]
  if fixed_inst_activity > 0.0                                               ;; sets a fixed instructor activity
    [ask person 0
      [set belief_list replace-item 0 belief_list fixed_inst_activity ]]
  if fixed_inst_discursivity > 0.0                                           ;; sets fixed instructor discursivities
    [foreach [1 2 3 4 5]
      [x -> ask person 0
        [set belief_list replace-item x belief_list fixed_inst_discursivity ]]]
  if ticks = transactions [update-plots stop]
; The tests below terminate the simulation to avoid rounding errors when values become very large or very small.
  if (mean-discursivity > .96 or mean-discursivity < .04) or (mean-activity > .96 or mean-activity < .04) [update-plots stop] ;
; if (mean-discursivity > .99 or mean-activity > .99) [update-plots stop]
  set tchint ""
  check-inst-protocol
  tick
end 

to go  ;; moves the simulation forward a number of ticks (defined by a slider)
    select-transaction
    set-agent-beliefs
;;    update-transaction
    update-activity-discursivity
    update-dlinks
    update-environment
    ifelse display_transactions [output-print (word ticks ", " current_transaction tchint) ] [ ]
    if fixed_inst_activity > 0.0
      [ask person 0
        [set belief_list replace-item 0 belief_list fixed_inst_activity ]]
    if fixed_inst_discursivity > 0.0
      [foreach [1 2 3 4 5]
        [x -> ask person 0
        [set belief_list replace-item x belief_list fixed_inst_discursivity ]]]
    if ticks = transactions [update-plots stop]
; The tests below terminate the simulation to avoid rounding errors when values become very large or very small.
    if (mean-discursivity > .96 or mean-discursivity < .005) or (mean-activity > .96 or mean-activity < .005) [update-plots stop] ;
;    if (mean-discursivity > .99 or mean-activity > .99) [update-plots stop]
    set tchint ""
    check-inst-protocol
  tick
end 

;;------------------------------------------------------------------------------------------------------------------------------
;; INSTRUCTIONAL PROTOCOL ROUTINES BEGIN HERE - set these protocols up as Chooser items
;; Instructional protocols specify how simulation parameters change *during* a simulation.
;;

to check-inst-protocol
  if inst_protocol = "increase cooperativity" and ticks mod 1000 = 0 [ increase_cooperativity ]
end 
;;
;; decreases competitivity by 10 pct

to increase_cooperativity
  ifelse competitivity >= 0.0 and cooperativity <= 1 [
;;    set competitivity precision (competitivity - ( competitivity * .09 )) 2 ;; reduces competitivty
    set cooperativity precision (cooperativity + (cooperativity * .09 ) ) 2 ] ;; increases cooperativity
    [set cooperativity 1]
end 
;;-------------------------------------------------------------------------------------------------------------

;; TRANSACTION ROUTINES BEGIN HERE
;; starts a discussion with random agent assignments (except for teacher redirects when activity_redirect > 0)

to select-transaction
  select-source
  ifelse random-float 1.0 < triad_proportion [select-triad-target]
  [select-dyad-target]
end 

;; selects a random source weighted by the teacher_talk parameter

to select-source
  ifelse (teacher_talk > random-float 1) [
    set source_agent 0
    ask person source_agent [ set source_count source_count + 1 ] ]
  [set source_agent first (shuffle [ 0 1 2 3 4 5 ])
  ask person source_agent [ set source_count source_count + 1 ] ]
end 

to select-dyad-target
  if teacher_redirect = "none" [ select-dyad-target-none ]
  if teacher_redirect = "Activity" [ select-dyad-target-activity ]
  if teacher_redirect = "Discursivity" [ select-dyad-target-discursivity ]
end 

to select-dyad-target-none
  set target_agent item 0 (remove source_agent (shuffle [0 1 2 3 4 5]))
  ask person target_agent [ set target_count target_count + 1 ]
  set current_transaction_type "dyad"
  set current_transaction (list source_agent target_agent)
end 

;; sets the Target agent for dyad (D) transactions
;; student_focus and redirect alter the likelihood of teacher comments and student redirects

to select-dyad-target-activity
  ifelse (source_agent = 0 and activity_redirect > random-float 1) [
    set target_agent first activity-rank
    ask person target_agent [ set target_count target_count + 1 ]
    set current_transaction_type "dyad"
    set tchint "(AR)"
    ]
    [set target_agent item 0 (remove source_agent (shuffle [0 1 2 3 4 5]))
    ask person target_agent [ set target_count target_count + 1 ]
    set current_transaction_type "dyad"]
  set current_transaction (list source_agent target_agent)
end 

to select-dyad-target-discursivity
  ifelse (source_agent = 0 and discursivity_redirect > random-float 1) [
    set target_agent first class-discursivity-rank
    ask person target_agent [ set target_count target_count + 1 ]
    set current_transaction_type "dyad"
    set tchint "(DR)"
    ]
    [set target_agent item 0 (remove source_agent (shuffle [0 1 2 3 4 5]))
    ask person target_agent [ set target_count target_count + 1 ]
    set current_transaction_type "dyad"]
  set current_transaction (list source_agent target_agent)
end 
;; Selects the triad target incorporating teacher redirects

to select-triad-target
  if teacher_redirect = "none" [ select-triad-target-none ]
  if teacher_redirect = "Activity" [ select-triad-target-activity ]
  if teacher_redirect = "Discursivity" [ select-triad-target-discursivity ]
end 

;; sets Primary and Collateral targets for triad (T) transactions
;; student_focus and redirect alter the likelihood of teacher comments and student redirects

to select-triad-target-none
    let temp_list (remove source_agent (shuffle [0 1 2 3 4 5]))    ;; includes teacher in triad transactions
    set primary_agent item 0 temp_list
    ask person primary_agent [ set primary_count primary_count + 1 ]
    set collateral_agent item 1 temp_list
    ask person collateral_agent [ set collateral_count collateral_count + 1 ]
;    set target_agent primary_agent
    set current_transaction_type "triad"
    set current_transaction (list source_agent (list primary_agent collateral_agent) )
end 

;; sets Primary and Collateral targets for triad (T) transactions
;; student_focus and redirect alter the likelihood of teacher comments and student redirects

to select-triad-target-activity
  ifelse (source_agent = 0 and activity_redirect > random-float 1) [
    set primary_agent first activity-rank
    ask person primary_agent [ set primary_count primary_count + 1 ]
    let temp_list (remove primary_agent (shuffle [1 2 3 4 5]))
    set collateral_agent first temp_list
    ask person collateral_agent [ set collateral_count collateral_count + 1 ]
;    set target_agent primary_agent
    set current_transaction_type "triad"
    set tchint "(AR)"
  ]
  [
    let temp_list (remove source_agent (shuffle [0 1 2 3 4 5]))    ;; includes teacher in triad transactions
    set primary_agent item 0 temp_list
    ask person primary_agent [ set primary_count primary_count + 1 ]
    set collateral_agent item 1 temp_list
    ask person collateral_agent [ set collateral_count collateral_count + 1 ]
;    set target_agent primary_agent
    set current_transaction_type "triad"
  ]
    set current_transaction (list source_agent (list primary_agent collateral_agent) )
end 

;; sets Primary and Collateral targets for triad (T) transactions
;; student_focus and redirect alter the likelihood of teacher comments and student redirects

to select-triad-target-discursivity
  ifelse (source_agent = 0 and discursivity_redirect > random-float 1) [
    set primary_agent first class-discursivity-rank
    ask person primary_agent [ set primary_count primary_count + 1 ]
    let temp_list (remove primary_agent (shuffle [1 2 3 4 5]))
    set collateral_agent first temp_list
    ask person collateral_agent [ set collateral_count collateral_count + 1 ]
;    set target_agent primary_agent
    set current_transaction_type "triad"
    set tchint "(DR)"
  ]
  [
    let temp_list (remove source_agent (shuffle [0 1 2 3 4 5]))    ;; includes teacher in triad transactions
    set primary_agent item 0 temp_list
    ask person primary_agent [ set primary_count primary_count + 1 ]
    set collateral_agent item 1 temp_list
    ask person collateral_agent [ set collateral_count collateral_count + 1 ]
;    set target_agent primary_agent
    set current_transaction_type "triad"
  ]
    set current_transaction (list source_agent (list primary_agent collateral_agent) )
end 

;; including agent 0 in activity update allows it to assume the mean student activity

to update-activity-discursivity
  foreach [0 1 2 3 4 5] [x -> ask person x [set activity item x belief_list]]
  foreach [1 2 3 4 5] [x -> ask person x [set discursivity mean-student-discursivity x]]
  foreach [1 2 3 4 5] [x -> ask person x [set happiness update-student-happiness x]]
  if fixed_inst_activity = 0.0 [ask person 0 [set activity mean-activity ] ]
  if fixed_inst_discursivity = 0.0 [reset-inst-discursivity]
  if fixed_inst_discursivity > 0.0 [ask person 0 [set discursivity fixed_inst_discursivity]]
    ask people [
      (ifelse happiness >= happy [set shape "face happy" ]
        happiness < happy and happiness > neutral [ set shape "face neutral" ]
        [ set shape "face sad" ])
      set size 3 ]
    ask person 0 [
      (ifelse mean-student-happiness >= happy [set shape "face happy" ]
        mean-student-happiness < happy and mean-student-happiness > neutral [ set shape "face neutral" ]
        [ set shape "face sad" ])
      set size 3 ]
;  ]
end 

;; this version of update-dlinks provides more visual emphasis as discursivities exceed initial values

to update-dlinks
  let temp_list []
  foreach agent-list [ x ->
    set temp_list ([belief_list] of person x)
    foreach agent-list [ y ->
      ifelse x = y [ let tempval 0 ]
        [ ask dlink x y [
          if (item y temp_list) <= .5 [set color ((item y temp_list) * 0)]
          if (item y temp_list) > .6 [set color ((item y temp_list) * 1)]
          if (item y temp_list) > .7 [set color ((item y temp_list) * 3)]
          if (item y temp_list) > .8 [set color ((item y temp_list) * 7)]
          if (item y temp_list) > .9 [set color ((item y temp_list) * 10)]]
  ] ] ]
end 

; This version dims links at initialization levels so changes are more apparent
;to update-dlinks
;  let temp_list []
;  foreach agent-list [ x ->
;    set temp_list ([belief_list] of person x)
;    foreach agent-list [ y ->
;      ifelse x = y [ let tempval 0 ]
;        [ ask dlink x y [
;          if (item y temp_list) <= .7 [set color ((item y temp_list) * 1)]
;          if (item y temp_list) > .76 [set color ((item y temp_list) * 1.5)]
;          if (item y temp_list) > .82 [set color ((item y temp_list) * 4.5)]
;          if (item y temp_list) > .88 [set color ((item y temp_list) * 7.5)]
;          if (item y temp_list) > .94 [set color ((item y temp_list) * 7.5 )] ]
;  ] ] ]
;end

to reset-inst-discursivity
  foreach [1 2 3 4 5] [x -> ask person 0 [
    set belief_list replace-item x belief_list mean-discursivity
    set discursivity mean-discursivity ] ]
end 

;;updates the environmental variables displayed in the lower right corner

to update-environment
;;    ask patch 15 -6 [ set environment-patch self set plabel-color white
;;      set plabel "Aggregate Student Data" ]
    ask patch 16 -12 [ set environment-patch self set plabel-color white
      set plabel (word "Mean Activity (SD): " mean-activity " (" sigma-activity ")") ]
    ask patch 16 -13 [ set environment-patch self set plabel-color white
      set plabel (word "Mean Discursivity (SD): " mean-discursivity " (" sigma-discursivity ")") ]
    ask patch 16 -14 [ set environment-patch self set plabel-color white
      set plabel word "Activity Rank (L->H): " activity-rank ]
    ask patch 16 -15 [ set environment-patch self set plabel-color white
      set plabel word "Discursivity Rank (L->H): " class-discursivity-rank ]
    ask patch 16 -16 [ set environment-patch self set plabel-color white
      set plabel word "Student Discursivity Sum (SDS): " precision student-discursivity-sum 4 ]
;;    ask patch -5 15 [ set environment-patch self set plabel-color white
;;      set plabel "Weighted A/D Affect Displayed" ]
end 

;;------------------------------------------------------------------------------------------------------------
;; The code in this section extends the Koponen & Nousiainen (2018) model to support learning by all agents in
;; every dyadic and triadic transaction including Source, Target, Primary, and Collateral.
;;
;; SET DYAD/TRIAD BELIEFS CODE FOLLOWS
;; Setting agent beliefs reads individual agent beliefs and assigns appropropriate values
;; to activity and discursivity for agents participating in a dyad or triad transaction.
;; The following belief variables are assigned values in transaction:
;; Kii = source agent activity
;; Kij = source agent discursivity toward target (dyad) or primary (triad) agent
;; Kik = source agent discursivity toward collateral agent (triad)
;; Kjj = target (dyad) or primary agent (triad) activity
;; Kji = target agent (dyad) or primary agent (triad) discursivity toward the source agent
;; Kjk = primary agent (triad) discursivity toward the collateral agent
;; Kkk = collateral agent (triad) activity
;; Kki = collateral agent (triad) discursivity toward the source agent
;; Kkj = collateral agent (triad) discursivity toward the primary agent

;; selects routines to set accommodate dyad and triad transactions

to set-agent-beliefs
  ifelse current_transaction_type = "triad" [
    set-triad-beliefs
    set-triad-deltas
    update-triad-beliefs]
    [
    set-dyad-beliefs
    set-dyad-deltas
    update-dyad-beliefs]
end 

to set-dyad-beliefs
  ask person source_agent [set source_belief_list belief_list]                ;; assigns agent belief list to a temporary variable for this transaction
  ask person source_agent [set source_agent_sensitivity overall_sensitivity]  ;; assigns overall_sensitivity to a temporary variable for this transaction
  set Kii item source_agent source_belief_list
  set Kij item target_agent source_belief_list
;  set Kik item collateral_agent source_belief_list
  ask person target_agent [set target_belief_list belief_list]
  ask person target_agent [set target_agent_sensitivity overall_sensitivity]
  set Kjj item target_agent target_belief_list
  set Kji item source_agent target_belief_list
;  set Kjk item collateral_agent target_belief_list
end 

to set-triad-beliefs
  ask person source_agent [set source_belief_list belief_list]                ;; assigns agent belief list to a temporary variable
  ask person source_agent [set source_agent_sensitivity overall_sensitivity]  ;; assigns overall_sensitivity to a temporary variable
  set Kii item source_agent source_belief_list
  set Kij item primary_agent source_belief_list
  set Kik item collateral_agent source_belief_list
  ask person primary_agent [set primary_belief_list belief_list]
  ask person primary_agent [set primary_agent_sensitivity overall_sensitivity]
  set Kjj item primary_agent primary_belief_list
  set Kji item source_agent primary_belief_list
  set Kjk item collateral_agent primary_belief_list
  ask person collateral_agent [set collateral_belief_list belief_list]
  ask person collateral_agent [set collateral_agent_sensitivity overall_sensitivity]
  set Kki item source_agent collateral_belief_list
  set Kkj item primary_agent collateral_belief_list
end 

;; the code below determines whether a transaction requires dyadic or triadic processing

to set_agent_deltas
  ifelse current_transaction_type = "triad" [set-triad-deltas]
  [set-dyad-deltas]
end 

to set-dyad-deltas
  set-dyad-source-deltas
  set-dyad-target-deltas
end 

to set-dyad-source-deltas
  let RScomp random-float 1.0
  let RScoop random-float 1.0
  let Spij ( 1 / ( 1 + ( exp ( - (Kij - Kii) / competitive_tolerance ))))
  let Sp*ij  ( 1 / ( 1 + ( exp ( - (Kji - Kij) / cooperative_tolerance ))))
  ifelse RScomp < Spij [
    set deltaKii ( Kji - Kii )
    set dyad_competition_count dyad_competition_count + 1 ]  ;; counts dyad competition transactions
    [set deltaKii 0 ]
  ifelse RScoop < Sp*ij [
    set coopdeltaKij (cooperativity * ( ( Kji - Kij ) / ( abs ( Kji - Kij ) ) ) * sqrt ( Kii * Kjj ) )
    set dyad_cooperation_count dyad_cooperation_count + 1                ;; counts dyad cooperation transactions
    if deltaKii != 0 [set dyad_compcoop_count dyad_compcoop_count + 1] ] ;; counts dyads that compete *and* cooperate
    [set coopdeltaKij 0 ]
  ifelse RScomp < Spij [
    set compdeltaKij ( ( competitivity * (Kji - Kii ) ) + ( ( 1 - competitivity ) * ( Kjj - Kij ) ) ) ]
    [set compdeltaKij ( competitivity * ( Kji - Kii) ) ]
end 

to set-dyad-target-deltas
  let RTcomp random-float 1.0
  let RTcoop random-float 1.0
  let Tpji ( 1 / ( 1 + ( exp ( - (Kji - Kjj) / competitive_tolerance ))))
  let Tp*ji  ( 1 / ( 1 + ( exp ( - (Kij - Kji) / cooperative_tolerance ))))
  ifelse RTcomp < Tpji [
    set deltaKjj ( Kij - Kjj )
    set dyad_competition_count dyad_competition_count + 1 ]  ;; counts dyad competition transactions
    [set deltaKjj 0 ]
  ifelse RTcoop < Tp*ji [
    set coopdeltaKji (cooperativity * ( ( Kij - Kji ) / ( abs ( Kij - Kji ) ) ) * sqrt ( Kii * Kjj ) )
    set dyad_cooperation_count dyad_cooperation_count + 1                ;; counts dyad cooperation transactions
    if deltaKjj != 0 [set dyad_compcoop_count dyad_compcoop_count + 1] ] ;; counts dyads that compete *and* cooperate
    [set coopdeltaKji 0 ]
  ifelse RTcomp < Tpji [
    set compdeltaKji ( ( competitivity * (Kij - Kjj ) ) + ( ( 1 - competitivity ) * ( Kii - Kji ) ) ) ]
    [set compdeltaKji ( competitivity * ( Kij - Kjj) ) ]
end 

to set-triad-deltas
  set-triad-source-deltas
  set-triad-primary-deltas
  set-triad-collateral-deltas
end 

to set-triad-source-deltas
  let RScomp random-float 1.0
  let RScoop random-float 1.0
  let Spij ( 1 / ( 1 + ( exp ( - (Kij - Kii) / competitive_tolerance ))))
  let Sp*ij  ( 1 / ( 1 + ( exp ( - (Kji - Kij) / cooperative_tolerance ))))
  ifelse RScomp < Spij [
    set deltaKii ( Kji - Kii )
    set triad_competition_count triad_competition_count + 1 ]  ;; counts triad competition transactions
    [set deltaKii 0 ]
  ifelse RScoop < Sp*ij [
    set coopdeltaKij (cooperativity * ( ( Kji - Kij ) / ( abs ( Kji - Kij ) ) ) * sqrt ( Kii * Kjj ) )
    set triad_cooperation_count triad_cooperation_count + 1                ;; counts triad cooperation transactions
    if deltaKii != 0 [set triad_compcoop_count triad_compcoop_count + 1] ] ;; counts triadss that compete *and* cooperate
    [set coopdeltaKij 0 ]
  ifelse RScomp < Spij [
    set compdeltaKij ( ( competitivity * (Kji - Kii ) ) + ( ( 1 - competitivity ) * ( Kjj - Kij ) ) ) ]
    [set compdeltaKij ( competitivity * ( Kji - Kii) ) ]
end 

to set-triad-primary-deltas
  let TPcomp random-float 1.0
  let TPcoop random-float 1.0
  let Tpji ( 1 / ( 1 + ( exp ( - (Kji - Kjj) / competitive_tolerance ))))
  let Tp*ji  ( 1 / ( 1 + ( exp ( - (Kij - Kji) / cooperative_tolerance ))))
  ifelse TPcomp < Tpji [
    set deltaKjj ( Kij - Kjj )
    set triad_competition_count triad_competition_count + 1 ]  ;; counts triad competition transactions
    [set deltaKjj 0 ]
  ifelse TPcoop < Tp*ji [
    set coopdeltaKji (cooperativity * ( ( Kij - Kji ) / ( abs ( Kij - Kji ) ) ) * sqrt ( Kii * Kjj ) )
    set triad_cooperation_count triad_cooperation_count + 1                  ;; counts triad cooperation transactions
    if deltaKjj != 0 [set triad_compcoop_count triad_compcoop_count + 1] ]   ;; counts triads that compete *and* cooperate
    [set coopdeltaKji 0 ]
  ifelse TPcomp < Tpji [
    set compdeltaKji ( ( competitivity * (Kij - Kjj ) ) + ( ( 1 - competitivity ) * ( Kii - Kji ) ) ) ]
    [set compdeltaKji ( competitivity * ( Kij - Kjj) ) ]
end 

; commenting out this update replicates the original KN collateral update
; uncommenting introduces full reciprocity between source and collateral

to set-triad-collateral-deltas
  let CPcomp random-float 1.0
  let Cpki ( 1 / ( 1 + ( exp ( - (Kki - Kkk) / competitive_tolerance ))))
  ifelse CPcomp < Cpki [
    set compdeltaKki ( Kkj - Kki ) ]
    [set compdeltaKki 0 ]
end 

to update-dyad-beliefs
  update-dyad-source-beliefs
  update-dyad-target-beliefs
end 

to update-dyad-source-beliefs
  let newKii ( Kii + ( source_agent_sensitivity * deltaKii * kii * ( 1 - Kii) ) )
  let newKij ( Kij + ( source_agent_sensitivity * ( compdeltaKij + coopdeltaKij ) * Kij * ( 1 - Kij ) ) )
  ask person source_agent [
    set source_belief_list replace-item source_agent source_belief_list newKii
    set source_belief_list replace-item target_agent source_belief_list newKij
    set belief_list source_belief_list ]
end 

to update-dyad-target-beliefs
  let newKjj ( Kjj + ( target_agent_sensitivity * deltaKjj * kjj * ( 1 - Kjj) ) )
  let newKji ( Kji + ( target_agent_sensitivity * ( compdeltaKji + coopdeltaKji ) * Kji * ( 1 - Kji ) ) )
  ask person target_agent [
    set target_belief_list replace-item target_agent target_belief_list newKjj
    set target_belief_list replace-item source_agent target_belief_list newKji
    set belief_list target_belief_list ]
end 

to update-triad-beliefs
  update-triad-source-beliefs
  update-triad-primary-beliefs
  update-triad-collateral-beliefs
end 

to update-triad-source-beliefs
  let newKii ( Kii + ( source_agent_sensitivity * deltaKii * kii * ( 1 - Kii) ) )
  let newKij ( Kij + ( source_agent_sensitivity * ( compdeltaKij + coopdeltaKij ) * Kij * ( 1 - Kij ) ) )
  let newKik ( Kik + ( source_agent_sensitivity * deltaKik * Kik * ( 1 - Kik ) ) )
  ask person source_agent [
    set source_belief_list replace-item source_agent source_belief_list newKii
    set source_belief_list replace-item primary_agent source_belief_list newKij
    set source_belief_list replace-item collateral_agent source_belief_list newKik
    set belief_list source_belief_list]
end 

to update-triad-primary-beliefs
  let newKjj ( Kjj + ( primary_agent_sensitivity * deltaKjj * kjj * ( 1 - Kjj) ) )
  let newKji ( Kji + ( primary_agent_sensitivity * ( compdeltaKji + coopdeltaKji ) * Kji * ( 1 - Kji ) ) )
  ask person primary_agent [
    set primary_belief_list replace-item primary_agent primary_belief_list newKjj
    set primary_belief_list replace-item source_agent primary_belief_list newKji
    set belief_list primary_belief_list ]
end 

;; If the model is not "PT" collateral agent beliefs are not changed (simulating KN instead)

to update-triad-collateral-beliefs
  let newKki ( Kki + ( collateral_agent_sensitivity * compdeltaKki * Kki * ( 1 - Kki ) ) )
  if model = "PT" [
  ask person collateral_agent [
    set collateral_belief_list replace-item source_agent collateral_belief_list newKki
    set belief_list collateral_belief_list ] ]
end 

;; THESE to-report FUNCTIONS RETURN VARIABLES AND OUTPUT GENERATED DURING A SIMULATION RUN
;; a belief_list represents what an agent believes about its own activity and discursivity toward peers

;; reports a list of all agents in the model

to-report agent-list
  report n-values 6 [ i -> i ]
end 

to-report initialize-belief_list  ;; this function assigns an inital belief_list to each agent in setup
  report map [ i -> (random-float i) + i ] [ 0.3 0.3 0.3 0.3 0.3 0.3]
end 

to-report update-happiness
  let temp_list []
  set temp_list belief_list
  report mean temp_list
end 

to-report update-student-happiness [x]
  ask person x [set happiness update-happiness]
  report happiness
end 

to-report mean-student-happiness
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [happiness] of person x ] temp_list )
  report mean temp_list
end 

;; activity ranking does not include the teacher

to-report activity-rank
  let temp_list sort-on [activity] people
  set temp_list remove (person 0) temp_list
  set temp_list (map [ x -> [who] of x ] temp_list )
  report temp_list
end 

to-report mean-activity
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [activity] of person x ] temp_list )
  report precision mean temp_list 3
end 

to-report activity-sum
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [activity] of person x ] temp_list )
  report sum temp_list
end 

to-report sigma-activity
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [activity] of person x ] temp_list )
  report precision standard-deviation temp_list 3
end 

to-report transaction-role-stats         ;; This procedure reports the mean and standard deviations for transaction role counts.
  report (word                           ;; SC values *will not* depend on the proportions of dyad and triad transactions, but
    "SC:" source-count-stats             ;; TC, PC, & CC counts *will* depend on proportions of dyad and triad transactions because,
    " TC:" target-count-stats            ;; while sources are in all transactions, dyads have a target agent and triads have primary
    " PC:" primary-count-stats           ;; and collateral agents. For transactions t, agents n, and triad_proportion p:
    " CC:" collateral-count-stats)       ;; dyad probabilities = [t/n t*p/n 0 0] and Triad probabilities = [t/n 0 t*p/n t*p/n]
end                                       ;; These tests help verify that the model behavior adheres to its intended design.

to-report source-count-stats
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [source_count] of person x ] temp_list )
  report (list precision mean temp_list 3 precision standard-deviation temp_list 3)
end 

to-report target-count-stats
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [target_count] of person x ] temp_list )
  report (list precision mean temp_list 3 precision standard-deviation temp_list 3)
end 

to-report primary-count-stats
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [primary_count] of person x ] temp_list )
  report (list precision mean temp_list 3 precision standard-deviation temp_list 3)
end 

to-report collateral-count-stats
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> [collateral_count] of person x ] temp_list )
  report (list precision mean temp_list 3 precision standard-deviation temp_list 3)
end 

;; this code produces a mean of student discursivities for a single student

to-report mean-student-discursivity [x]                          ;; strips instructor discursivity and agent activity
  let temp_list []                                      ;; from the belief_list so we can focus on discursivity
  set temp_list ([belief_list] of person x)             ;; set temp_list to agent x belief_list
  set temp_list remove (item x temp_list) temp_list     ;; remove agent activity from list
  set temp_list remove (item 0 temp_list) temp_list     ;; remove teacher discursivity from list
  report mean temp_list                                 ;; report the mean of remaining discursivities
end 

;; this code produces the sigma for a mean of student discursivities for a single student

to-report sigma-belief-list [x]                         ;; strips instructor discursivity and agent activity
  let temp_list []                                      ;; from the belief_list so we can focus on discursivity
  set temp_list ([belief_list] of person x)             ;; set temp_list to agent x belief_list
  set temp_list remove (item x temp_list) temp_list     ;; remove agent activity from list
  set temp_list remove (item 0 temp_list) temp_list     ;; remove teacher discursivity from list
  report standard-deviation temp_list                                 ;; report the mean of remaining discursivities
end 

;; this code produces an unordered list of mean student discursivities for all 5 students

to-report student-discursivity-list
  let temp_list []
  foreach [1 2 3 4 5] [ x ->
    set temp_list lput mean-student-discursivity x temp_list ]
  report temp_list
end 

;; this code produces an ordered list of mean student discursivities for all 5 students

to-report ordered-student-discursivity-list
  let temp_list []
  report map [ x -> sentence list x mean-student-discursivity x temp_list ] [1 2 3 4 5]
end 

; this code produces a low-to-high discursivity student ranking

to-report class-discursivity-rank
  let temp_list_3 []
  let temp_list_1 ( sort-by [ [ list1 list2 ] -> item 1 list1 < item 1 list2 ] ordered-student-discursivity-list )
  foreach [0 1 2 3 4] [ x ->
    let temp_list_2 ( item x temp_list_1 )
    set temp_list_3 lput item 0 temp_list_2 temp_list_3 ]
  report temp_list_3
end 

to-report agent-belief-list [agent]    ;; this code produced agent-belief_lists with length > 255
  let temp_list []                     ;; short-agent-belief-list reduced entries to 4 decimal places
  ask person agent [                   ;; this code sets entries to 0 that are not peer discursivities
    set temp_list belief_list
    set temp_list replace-item 0 temp_list 0          ;; sets discursivity toward teacher to 0
    set temp_list replace-item agent temp_list 0 ]    ;; sets activity to 0
  report temp_list
end 

to-report short-agent-belief-list [agent]     ;; this code reduces belief list entries to 4 decimal places
  let temp_list []
  ask person agent [ set temp_list belief_list ]
  foreach [0 1 2 3 4 5] [ x -> set temp_list replace-item x temp_list precision item x temp_list 4
    set temp_list replace-item agent temp_list 0 ]
  report but-first temp_list
end 

;; this code creates a student-only list of belief lists

to-report short-class-belief-list
  let temp_list []
  foreach [1 2 3 4 5] [x ->
    set temp_list lput short-agent-belief-list x temp_list ]
  report temp_list
end 

;; this code calculates student discussion discursivity
;; the teacher is excluded from this sum

to-report student-discursivity-sum
  let temp_var 0
  foreach [0 1 2 3 4] [x ->
    set temp_var temp_var + sum item x short-class-belief-list ]
  report 2 * temp_var
end 

;; this code calculates discussion discursivity for agent x
;; the teacher is excluded from this sum, as is the agent's activity

to-report agent-discursivity-sum [ x ]
  report 2 * ( sum agent-belief-list x )
end 

to-report mean-discursivity
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> (mean-student-discursivity x)] temp_list)
  report precision mean temp_list 3
end 

to-report sigma-discursivity
  let temp_list [1 2 3 4 5]
  set temp_list (map [ x -> (mean-student-discursivity x)] temp_list)
  report precision standard-deviation temp_list 3
end 

to-report teacher-source-count
  let temp_var 0
  ask person 0 [ set temp_var source_count ]
  report temp_var
end 

;; the following functions report percentage frequencies for transaction types during a run
;; Dyad Competitive = DComp, Dyad Cooperative = DCoop, Triad Competitive = TComp,
;; Triad Cooperative = TCoop, Dyad Hybrid = DHbd, Triad Hybrid = THbd

;; Use transaction-counts to report all frequencies

to-report transaction-counts
  report (word "DComp=" DComp ", DCoop=" DCoop ", TComp=" TComp ", TCoop=" TCoop ", DHbd=" DHbd ", THbd=" THbd)
end 

to-report DComp
  report precision
  (dyad_competition_count /
   (dyad_competition_count +
    dyad_cooperation_count +
    triad_competition_count +
    triad_cooperation_count +
    dyad_compcoop_count +
    triad_compcoop_count)) 2
end 

to-report DCoop
  report precision
  (dyad_cooperation_count /
   (dyad_competition_count +
    dyad_cooperation_count +
    triad_competition_count +
    triad_cooperation_count +
    dyad_compcoop_count +
    triad_compcoop_count)) 2
end 

to-report TComp
  report precision
  (triad_competition_count /
   (dyad_competition_count +
    dyad_cooperation_count +
    triad_competition_count +
    triad_cooperation_count +
    dyad_compcoop_count +
    triad_compcoop_count)) 2
end 

to-report TCoop
  report precision
  (triad_cooperation_count /
   (dyad_competition_count +
    dyad_cooperation_count +
    triad_competition_count +
    triad_cooperation_count +
    dyad_compcoop_count +
    triad_compcoop_count)) 2
end 

to-report DHbd
  report precision
  (dyad_compcoop_count /
   (dyad_competition_count +
    dyad_cooperation_count +
    triad_competition_count +
    triad_cooperation_count +
    dyad_compcoop_count +
    triad_compcoop_count)) 2
end 

to-report THbd
  report precision
  (triad_compcoop_count /
   (dyad_competition_count +
    dyad_cooperation_count +
    triad_competition_count +
    triad_cooperation_count +
    dyad_compcoop_count +
    triad_compcoop_count)) 2
end 

;;----------------------------------------------------------------------------------------------------------------------------
;; THESE UTILITY FUCTIONS GENERATE FORMATTED DATA FOR VISUALIZING AND ANALYZING SIMULATION OUTPUT
;; threshold function used to assign values in an adjacency matrix, with the threshold values set by the adjm_threshold widget
;; The following procedures create an adjacency matrix and derivatives used in graphing and the triad census.
;; I have opted to rely on the igraph package in R for graphing and matrix functions rather than recoding them in NetLogo.

;; reports R test value "1," if value > adjm_threshold

to-report R-test-value-1 [value]                                ;; sets belief_list values < .05 to 0 in K'
  ifelse value < adjm_threshold [ report 0 ] [ report 1 ]       ;; sets belief_list values >= .05 to 1 in K'
end 

;; reports 1 if value argument > 0.0

to-report test-value-1 [value]                                 ;; sets belief_list values < .05 to 0 in K'
  ifelse value < adjm_threshold [ report 0 ] [ report 1 ]       ;; sets belief_list values >= .05 to 1 in K'
end 

;; reports 1 if value argument > adjm_threshold

to-report test-value-2 [value]                         ;; sets belief_list values > 0.0 to 1 in K
  ifelse value > 0.0 [ report 1 ] [ report 0 ]       ;; sets belief_list values >= .05 to 1 in K
end 

;; sets all diagonal elements (i.e., activity levels) in the adjacency matris to 0

to-report test-position [ individual x value ]       ;; sets activity levels in the adjacency matrix to 0
  ifelse x = individual [ report 0 ] [report value ]
end 

;; creates a 6 X 6 adjacency matrix for all discussants, including the teacher

to-report R-all
  let temp_list []
  foreach [0 1 2 3 4 5] [ x ->                                 ;; creates a nested list of adjacency lists
    set temp_list lput create-R-adjacency-list x temp_list ]  ;; then converts the list of adjacency lists to a matrix
  report temp_list
end 

;; creates a 5 X 5 student-only discursivity adjacency matrix

to-report R-students
  let temp_list []
  foreach [1 2 3 4 5] [ x ->
    set temp_list lput student-adjacency-list x temp_list ]
  report temp_list
end 

to-report student-adjacency-list [x]
  let temp_list1 []
  set temp_list1 short-agent-belief-list x
  let temp_list2 map [x2 -> R-test-value-1 (item x2 temp_list1) ] [0 1 2 3 4]
  report temp_list2
end 

to-report create-R-adjacency-list [individual]                               ;; starts with an individual's belief_list
  let temp_list1 []                                                          ;; then sets values to 0 or 1 based on list values
  ask person individual [set temp_list1 belief_list]                         ;; then sets activity level items to 0
  let temp_list2 map [ x2 -> R-test-value-1 (item x2 temp_list1) ] [0 1 2 3 4 5]
  let temp_list3 map [ x -> test-position individual x (item x temp_list2) ] [0 1 2 3 4 5]
  report temp_list3
end 

;; creates an adjacency list using a threshold of 0.05 for assigning a value of 1 to an entry (by using test-value-1)

to-report create-adjacency-list_1 [individual]                               ;; starts with an individual's belief_list
  let temp_list1 []                                                          ;; then sets values to 0 or 1 based on list values
  ask person individual [set temp_list1 belief_list]                         ;; then sets activity level items to 0
  let temp_list2 map [ x2 -> test-value-1 (item x2 temp_list1) ] [0 1 2 3 4 5]
  let temp_list3 map [ x -> test-position individual x (item x temp_list2) ] [0 1 2 3 4 5]
  report temp_list3
end 

;; creates an adjacency list using a threshold of 0.0 for assigning a value of 1 to an entry (by using test-value-2)

to-report create-adjacency-list_2 [individual]                                 ;; starts with an individual's belief_list
  let temp_list1 []                                                          ;; then sets values to 0 or 1 based on list values
  ask person individual [set temp_list1 belief_list]                         ;; then sets activity level items to 0
  let temp_list2 map [ x2 -> test-value-2 (item x2 temp_list1) ] [0 1 2 3 4 5]
  let temp_list3 map [ x -> test-position individual x (item x temp_list2) ] [0 1 2 3 4 5]
  report temp_list3
end 

;;---------------------------------------------------------------------------------------------------------------
;; Moody provides background on the triad census, graph matrices, and other related network metrics.
;; Moody, J. (1998). Matrix methods for calculating the triad census. Social Networks, 20(4), 291–299.
;;
;; The adjacency matrix R has entry Rij = 1 if the discursivity of Kij exceeds the adjm_threshold, otherwise it is 0.
;; Elements of the triad census of special practical interest in studying discourse patterns are listed below.
;;
;; an egalitarian triad (300) consists of three fully connected agent pairs
;; a leader triad (210) consists of two fully-connected agent pairs and a partially connected pair
;; a dyadic leader triad (201) is two fully connected agent pairs and a fully disconnected pair
;; a broker triad (120D) is a fully-connected agent pair and an agent with indegree=0 and outdegree=2
;; a collateral triad (120U) is a fully-connected agent pair and an agent with outdegree=0 and indegree=2
;; a dyad triad (102) is a fully-connected agent pair and one isolated agent without any links
;; an isolate triad (003) is three agents without any connections at all, resulting in three isolated nodes
;;
;; The R code below creates a discussion graph and triad matrix from an R formatted adjacency matrix
;;
;; library(igraph) ## (igraph library must already be installed)
;;                 ##  paste in a row X column adjacency matrix into the code below
;; A = matrix( c(0,1,1,0,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,1,0,0,1,1,1,0,1,1,0,1,0,1,0,0,1,0),
;; nrow = 6, ncol = 6, byrow = TRUE)
;;
;; g <- graph_from_adjacency_matrix(A)
;; V(g)$label = c("John", "Nell", "Max", "Jana", "Sally", "Rich")
;; g$layout <- layout_in_circle ;; provides consistent layout so graphs are easier to compare
;; par(mar=c(0,0,0,0))
;; plot(g, vertex.size=40, vertex.color="white", edge.color="black")
;;
;; triad_census(g)
;; degree(g, v = V(g), mode = c("in"), loops = TRUE, normalized = FALSE)
;; degree(g, v = V(g), mode = c("out"), loops = TRUE, normalized = FALSE)
;; degree(g, v = V(g), mode = c("total"), loops = TRUE, normalized = FALSE)
;;---------------------------------------------------------------------------------------------------------------
;;
;; Copyright 2025 John E. McEneaney
;; See Info tab for full copyright and license.

There are 5 versions of this model.

Uploaded by When Description Download
John McEneaney 5 months ago Info tab link updated. Download this version
John McEneaney 5 months ago Info tab link updated. Download this version
John McEneaney 6 months ago Modification to display Info tab. Download this version
John McEneaney 6 months ago Modification to display Info tab. Download this version
John McEneaney 6 months ago Initial upload Download this version

Attached files

File Type Description Last updated
An Agent-based Model of Small-group Discussion.png preview Preview for 'An Agent-based Model of Small-group Discussion' 6 months ago, by John McEneaney Download

This model does not have any ancestors.

This model does not have any descendants.