Paper deep dive
sGLP: Specifying Stochastic Agents that Simulate People
Ehud Shapiro
Intelligence
Status: succeeded | Model: Gemma-4-26B-A4B | Prompt: intel-v1 | Confidence: 94%
Last extracted: 10/14/2026, 10:21:22 AM
Summary
The paper introduces stochastic GLP (sGLP), an extension of the Grassroots Logic Program (GLP) language, to enable large-scale simulation of grassroots platforms. sGLP replaces human users with stochastic agents defined by behavioral profiles, utilizing Gillespie's algorithm for discrete-event simulation. The authors demonstrate the framework on social graphs and currency circulation scenarios, proving that sGLP simulations are sound with respect to the underlying volition-guarded GLP (vGLP) semantics.
Entities (7)
Relation Signals (6)
Ehud Shapiro → authored → sGLP
confidence 99% · Ehud Shapiro Affiliation... Abstract... Here, we present stochastic GLP (sGLP)
sGLP → extends → GLP
confidence 95% · sGLP is GLP with a rate extension for specifying stochastic behaviour.
Stochastic Agent → replaces → Person
confidence 93% · A stochastic agent is an sGLP program replacing both the vGLP UI and the person behind it.
sGLP → implements → Gillespie's method
confidence 92% · We implemented sGLP in GLP by Gillespie’s method
vGLP → iscompiledto → GLP
confidence 90% · The program is compiled onto GLP
sGLP → simulates → Grassroots Platforms
confidence 90% · sGLP, designed to allow grassroots platforms to be simulated at scale
Cypher Suggestions (0)
No Cypher suggestions yet.
Abstract
Abstract:Grassroots platforms are designed to be owned, operated and governed by their participants, and thus are constituted from person-to-person smartphone apps that run on participants' smartphones. A grassroots app is specified using a grassroots social contract, which is compiled through an abstraction cascade into a volition-guarded Grassroots Logic Program (vGLP), a multiagent concurrent logic programming language. A vGLP program in turn specifies a smartphone UI via which people express their volitions and thus control the app. Prudence dictates large-scale evaluation and testing of grassroots platforms prior to deployment, but using the many people needed to do that is a contradiction in terms. Hence another solution is needed. Here, we present stochastic GLP (sGLP), designed to allow grassroots platforms to be simulated at scale from the vGLP programs that deploy them, with stochastic agents in place of people. sGLP is GLP with a rate extension for specifying stochastic behaviour. A stochastic agent is an sGLP program replacing both the vGLP UI and the person behind it. It is typed by the dual of the interactive type of the UI and specifies a stochastic profile of a person's behaviour. We demonstrate sGLP on the grassroots social graph, with a population of men and women drawn from four stochastic profiles --- homophile or indifferent, wary or sociable --- and on grassroots currencies, with four profiles --- spenders or savers, cautious or generous --- and report what the mix of profiles does to the social graph that forms and to the currencies that circulate. We prove that every run of a vGLP program in which sGLP agents replace the UI and the people behind it is a vGLP run. We implemented sGLP in GLP by Gillespie's method, and ran reproducible simulations with it.
Tags
Links
- Source: https://arxiv.org/abs/2610.14738v1
- Canonical: https://arxiv.org/abs/2610.14738v1
Trouble viewing inline? Open PDF directly →
Full Text
110,153 characters extracted from source content.
Expand or collapse full text
sGLP: Specifying Stochastic Agents that Simulate People CCS: Theory of computation Operational semanticsCCS: Software and its engineering Constraint and logic languagesCCS: Software and its engineering Concurrent programming languagesCCS: Computing methodologies Discrete-event simulationCCS: Computing methodologies Agent / discrete modelsCCS: Mathematics of computing Markov processes Ehud Shapiro Affiliation: London School of Economics and Weizmann Institute of Science, UK and Israel Abstract. Grassroots platforms are designed to be owned, operated and governed by their participants, and thus are constituted from person-to-person smartphone apps that run on participants’ smartphones. A grassroots app is specified using a grassroots social contract, which is compiled through an abstraction cascade into a volition-guarded Grassroots Logic Program (vGLP), a multiagent concurrent logic programming language. A vGLP program in turn specifies a smartphone UI via which people express their volitions and thus control the app. Prudence dictates large-scale evaluation and testing of grassroots platforms prior to deployment, but using the many people needed to do that is a contradiction in terms. Hence another solution is needed. Here, we present stochastic GLP (sGLP), designed to allow grassroots platforms to be simulated at scale from the vGLP programs that deploy them, with stochastic agents in place of people. sGLP is GLP with a rate extension for specifying stochastic behaviour. A stochastic agent is an sGLP program replacing both the vGLP UI and the person behind it. It is typed by the dual of the interactive type of the UI and specifies a stochastic profile of a person’s behaviour. We demonstrate sGLP on the grassroots social graph, with a population of men and women drawn from four stochastic profiles — homophile or indifferent, wary or sociable — and on grassroots currencies, with four profiles — spenders or savers, cautious or generous — and report what the mix of profiles does to the social graph that forms and to the currencies that circulate. We prove that every run of a vGLP program in which sGLP agents replace the UI and the people behind it is a vGLP run. We implemented sGLP in GLP by Gillespie’s method, and ran reproducible simulations with it. Keywords: Stochastic Simulation, Gillespie Algorithm, Agent-Based Simulation, Operational Semantics, Concurrent Logic Programming, GLP, Volitional Programming, Grassroots Platforms 1. Introduction Grassroots platforms (Shapiro, 2023a; Shapiro, 2025a; Shapiro, 2024) are designed to be owned, operated and governed by their participants, and thus are constituted from person-to-person smartphone apps that run on participants’ smartphones. A grassroots app is specified using a grassroots social contract (Golike et al., 2026), which is compiled through an abstraction cascade (Golike et al., 2026; Shapiro, 2026d) into a volition-guarded Grassroots Logic Program (vGLP) (Shapiro, 2026d), a multiagent concurrent logic programming language (Shapiro, 1989; Shapiro, 2025b; Shapiro, 2026c). A vGLP program in turn specifies a smartphone UI via which people express their volitions (Lewis-Pye and Shapiro, 2026) and thus control the app. In vGLP a procedure may put a question to its person, and a clause that reads the answer reduces only after the person has given it, so the transitions of the platform are guarded by the volitions of its people (Lewis-Pye and Shapiro, 2026). Each question has an interactive type, and the UI is derived from these types, a widget per question (Shapiro, 2026d). The program is compiled onto GLP (Shapiro, 2025b; Shapiro, 2026b) and deployed as a smartphone app (Google, 2024). What such a platform does at scale — whether a grassroots social graph (Shapiro, 2023b) coalesces from separate groups into one, whether grassroots currencies (Shapiro, 2022; Shapiro, 2026a) circulate — depends on what the people using it do, and cannot be found out by running the app with a handful of them. Prudence dictates large-scale evaluation and testing of grassroots platforms prior to deployment, but using the many people needed to do that is a contradiction in terms. Hence another solution is needed. Here, we present stochastic GLP (sGLP), designed to allow grassroots platforms to be simulated at scale from the vGLP programs that deploy them, with stochastic agents in place of people. sGLP is GLP with a rate extension for specifying stochastic behaviour. A rated goal is reduced at a time drawn, when it is spawned, from the exponential distribution with its rate; the machine runs to rest between two such times, so simulated time advances only with them; and the law of a run is that of Gillespie’s first reaction method (Gillespie, 1977), which we prove equivalent here to the direct method, since a spawned goal is never withdrawn (Section 2). A stochastic agent is an sGLP program replacing both the vGLP UI and the person behind it, typed by the dual of the interactive type specifying the UI, with a stochastic profile of a person’s behaviour. A profile is such a program, named, and a population is a mix of profiles from which each agent draws its person (Section 3). We demonstrate sGLP on the grassroots social graph (Shapiro, 2023b), with a population of men and women drawn from four stochastic profiles — homophile or indifferent, wary or sociable — and on grassroots currencies (Shapiro, 2022; Shapiro, 2026a), with four profiles — spenders or savers, cautious or generous — and report what the mix of profiles does to the social graph that forms and to the currencies that circulate (Sections 5 and 6). The social graph is the platform on which the other grassroots platforms are built, and the currencies are coins among friends in it. Each demonstration runs 100 agents for a simulated year, over nine mixes of profiles and twenty seeds, and the social graph runs at 1,000 agents for five simulated years. We prove that every run of a vGLP program in which sGLP agents replace the UI and the people behind it is a vGLP run. So what a simulation reports is something the deployed platform can do (Section 3). We implemented sGLP in GLP by Gillespie’s method (Gillespie, 1977), and ran reproducible simulations with it. The implementation is as the stochastic pi-calculus (Priami, 1995) was implemented in Flat Concurrent Prolog (Regev et al., 2000; Priami et al., 2001; Silverman et al., 1988): a transformation of sGLP programs into GLP, and a monitor written in GLP that draws the next event by Gillespie’s method over a guard that succeeds when the machine rests; every draw is from the run’s seed, so a run is reproducible (Section 4). Section 7 reviews related work and Section 8 concludes. 2. sGLP: Stochastic GLP A stochastic agent is a program that replaces the UI of a vGLP program and the person behind it: it holds the person’s end of each question and answers it, as the widget does on the phone. sGLP is the language such a program is written in: GLP (Shapiro, 2025b; Shapiro, 2026c) with a rate on a goal, which runs in simulated time. This section defines the language; Section 3 puts a person written in it in the place of the person of a vGLP program. 2.1. Syntax An sGLP program is a typed GLP program (Shapiro, 2026c) with a rate on a goal. Its draws are GLP’s: random(S?S?, N?N?, K, S1S_1) assigns K an integer uniform from 11 to N, drawn from the seed S, and S1S_1 the next seed (Shapiro, 2025b). <rated_goal> ::= <goal> @ <rate> <rate> ::= <positive_real> / <time_unit> <time_unit> ::= second | minute | hour | day | week | year Definition 2.1 (Rated Goal). A rated goal A @ r in the body of a clause is a goal A with a rate r, a positive real per unit of time. A rated goal is spawned as any body goal is, and is reduced only once its time has come, which is drawn when it is spawned from the exponential distribution with its rate. A choice among alternatives with given probabilities is a draw and a guard on it in each clause, as the profiles of Sections 5 and 6 show. 2.2. Operational Semantics Throughout, N is an sGLP program, P⊂ΠP⊂ a finite set of agents, and c a configuration of the maGLP transition system over P and N (Shapiro, 2025b) (Definition E.6), whose transitions are Reduce, Communicate and Cold-call. sGLP adds to a configuration a clock and the activation times of its rated goals, and to the transitions one that advances the clock. Definition 2.2 (Configuration, Pending, Quiescent). A configuration of sGLP over P and N is a triple (c,t,α)(c,t,α): c a configuration of the maGLP transition system over P and N, t≥0t≥ 0 the simulated time, and α a partial function from the goals of c to activation times α(A)≥tα(A)≥ t, the goals in its domain being pending. It is quiescent if no Communicate, no Cold-call and no Reduce of a goal that is not pending is enabled in c. Definition 2.3 (sGLP Transition System). The sGLP transition system over P, N and a configuration c0c^0 of the maGLP transition system over P and N has the configurations of Definition 2.2, the initial configuration (c0,0,∅)(c^0,0, ), and the transitions (c,t,α)→(c′,t′,α′)(c,t,α)→(c ,t ,α ): (1) Machine: c→c′c→ c is a Communicate or Cold-call transition, or a Reduce of a goal A that is not pending; t′=t =t; and α′α is α with α′(B)=t+τα (B)=t+τ for each rated goal B @ r in the body the Reduce spawns, τ drawn from the exponential distribution with rate r, the draws independent. (2) Release: (c,t,α)(c,t,α) is quiescent, A is a pending goal with α(A)α(A) least, c′=c =c, t′=α(A)t =α(A), and α′α is α without A. Definition 2.4 (sGLP Run). An sGLP run of N over P from c0c^0 is a sequence of configurations of the sGLP transition system over P, N and c0c^0, the first initial and each a transition of the one before, such that its configurations of the maGLP transition system, with each repeated one taken once, form a proper safe computation of that system from c0c^0 (Definitions E.1 and E.5); an sGLP run of N over P is one from the initial configuration of the maGLP transition system over P and N. Simulated time advances only at a Release: a machine step takes no time, and the clock jumps to the earliest activation time once the machine has nothing to do at the present time. A released goal is an ordinary goal: where its input has not arrived it suspends and reduces when it does, with no further delay. Proposition 2.5 (Time to the Next Release). Let (c,t,α)(c,t,α) be a quiescent configuration of an sGLP run with pending goals A1,…,AmA_1,…,A_m of rates r1,…,rmr_1,…,r_m, and R=∑iriR= _ir_i. Conditional on the run up to it, the next Release comes after a time exponentially distributed with rate R, and releases AiA_i with probability ri/Rr_i/R, independently of that time. Proof. α(Ai)=ti+τiα(A_i)=t_i+ _i, with ti≤t_i≤ t the time AiA_i was spawned and τi _i exponential with rate rir_i, the τi _i independent of one another and of every other draw of the run. The run up to (c,t,α)(c,t,α) depends on τi _i only through α(Ai)≥tα(A_i)≥ t, so conditional on it α(Ai)−tα(A_i)-t is exponential with rate rir_i, by memorylessness, and the α(Ai)−tα(A_i)-t are independent. The minimum of independent exponential variates with rates r1,…,rmr_1,…,r_m is exponential with rate R, and is the i-th with probability ri/Rr_i/R, independently of its value. ∎ This is Gillespie’s first reaction method (Gillespie, 1977), and the proposition is its equivalence to the direct method, which holds here because a spawned goal is never withdrawn. 3. Simulating a vGLP Program On the phone, the person’s end of each interactive variable is held by a construct process, which has the question’s widget drawn and assigns the person’s answer; the widget’s type is the dual of the interactive type, writing where the program reads and reading where the program writes (Shapiro, 2026d). In a simulation the person’s end is held by a goal of a person procedure of the dual type, and the population is a mix of profiles of person, each profile a program. The vGLP program, its types and its clauses are those the phone runs. <person_declaration> ::= <type> =::= <procedure_name> . <profile> ::= person <name> . <person_declarations> <program> <run> ::= run <integer> agents [ <mix_list> ] until <time> seed <integer> . <mix_list> ::= <mix> | <mix> , <mix_list> <mix> ::= <dimension> ~ ( <name> : <probability> ; ... ) The definitions and results of vGLP (Shapiro, 2026d) that this section and Theorem 3.10 rest on — interactive types, the vmaGLP transition system, the canonical compilation and its mapping back to the source — are recalled in Appendix E. Throughout, M is a vGLP program, (M)T(M) the set of its interactive types, each in writer or reader mode, and ⌈M⌉ M its canonical compilation (Definition E.10), which gives the interactive types distinct functors, A being the type of its asks. Definition 3.1 (Dual, Person Procedure, Person Declaration). The dual of an interactive type T is T∘:=T′?T :=T ? where T=T′T=T and T∘:=T′T :=T where T=T′?T=T ?; a person procedure of T in an sGLP program N is a procedure p of N declared procedure p(T∘CLOSEp(T , Integer?); and a person declaration is a pair (T,p)(T,p), written T =::= p, of an interactive type T∈(M)T (M) and a person procedure p of T. The person’s end of an interactive variable is of the dual type, and a person procedure takes it with a seed. Definition 3.2 (Profile, Dimension). A profile over M is a triple ϕ=(,N,Δ)φ=(name,N, ) of a name, an sGLP program N and a finite set Δ of person declarations with distinct interactive types, each naming a person procedure of N, (ϕ)T(φ) being the set of those types; a dimension over M is a pair (d,Φ)(d, ) of a name and a finite set Φ of profiles over M with one set of interactive types, (Φ)T( ); and dimensions (d1,Φ1),…,(dk,Φk)(d_1, _1),…,(d_k, _k) over M are disjoint and covering if (Φ1),…,(Φk)T( _1),…,T( _k) are pairwise disjoint with union (M)T(M). Definition 3.3 (Stochastic Person, Population). A stochastic person over disjoint and covering dimensions (d1,Φ1),…,(dk,Φk)(d_1, _1),…,(d_k, _k) is a tuple (ϕ1,…,ϕk)( _1,…, _k) with ϕj∈Φj _j∈ _j for j=1,…,kj=1,…,k, and a population over M is a tuple (n,D,μ,s)(n,D,μ,s) of an integer n≥1n≥ 1, disjoint and covering dimensions D=((d1,Φ1),…,(dk,Φk))D=((d_1, _1),…,(d_k, _k)) over M, a tuple μ=(μ1,…,μk)μ=( _1,…, _k) of probability distributions, μj _j on Φj _j, and an integer s, its seed; its agents are P=1,…,nP=\1,…,n\. A stochastic person therefore declares each interactive type of M exactly once, by one of its profiles. Definition 3.4 (Single-Answer, Well-Formed). A clause is single-answer if, of the positions the person writes in the arguments of its head, by the moded types of the arguments (Shapiro, 2026c), at most one holds a term that is not a variable; and a population is well formed if each person procedure its profiles declare is declared with the type its declaration requires, the predicates of the profiles’ programs are distinct from those of ⌈M⌉ M , μj _j sums to one over Φj _j for each j, and every clause of a profile’s program is single-answer. A single-answer clause assigns at most one question of the person when it reduces, as a submission on the phone does; the profiles of Sections 5 and 6 are single-answer. The transformation of Section 4 refuses a population that is not well formed. A run declaration draws from the population’s seed, for each agent, a stochastic person — one profile per dimension, by that dimension’s distribution — and a seed; Section 4 says how. For the rest of the section, (n,D,μ,s)(n,D,μ,s) is a well-formed population over M with agents P and, for each a∈Pa∈ P, π(a)π(a) is a stochastic person over D, sas_a an integer and gag_a a goal of M, its initial goal, with ga′g _a the goal gag_a extended with an ask stream UaU_a and with its calls of volitional procedures replaced, as in ⌈M⌉ M . Definition 3.5 (Person Process). The person process of a stochastic person ϕφ over D is the procedure ϕperson_φ, written person_phi and declared procedure person_phi(Stream(A)?, Integer?), with the clause person_phi([], _). and, for each person declaration (T,p)(T,p) of a profile of ϕφ, t the functor ⌈M⌉ M gives T and E the end of the interactive variable the ask carries, the clauseperson_phi([ask(T, t(E))|As], S) :- random(S?, 2147483646, K, S1), p(E, K?), person_phi(As?, S1?). The end the ask carries is the writer where T is in reader mode and the reader where it is in writer mode (Definition E.10). On each ask the person process hands the person’s end of the question to the person procedure its profile declares for the question’s type, with a seed drawn from its own. Definition 3.6 (Simulation Program). The simulation program of (M,P,π)(M,P,π) is the sGLP program N whose clauses are those of ⌈M⌉ M other than the construct processes’ and the dispatcher’s, those of the programs of the profiles of π(a)π(a) for every a∈Pa∈ P, and those of π(a)person_π(a) for every a∈Pa∈ P, and whose initial configuration c0c^0 has at each a∈Pa∈ P the resolvent (ga′,π(a)(Ua?,sa),∅)(\g _a,\ person_π(a)(U_a?,s_a)\, ). A stochastic agent is an agent of the sGLP transition system over P, N and c0c^0: it runs the platform’s program as the phone does, with the person process and the programs of its stochastic person in place of the dispatcher, the construct processes and the person behind them. A run declaration run n agents […] until T seed s runs the simulation program of M over agents 1,…,n1,…,n with the stochastic persons and seeds its population draws from s, until the simulated clock reaches T; the initial goal of each agent is stated with the program, as Sections 5 and 6 state theirs. Every draw of a person is from a seed derived from the population’s seed, so the draws of a run are reproducible from that seed, and the run itself is reproducible where the machine’s schedule is deterministic. For the rest of the section, r=(c1,t1,α1),(c2,t2,α2),…r=(c^1,t_1, _1),(c^2,t_2, _2),… is an sGLP run of N over P from c0c^0. Definition 3.7 (Platform Goal, Person Goal, Interactive Variable, Interface Variable, Ask-Stream Variable). A goal in a resolvent of r is a person goal if its predicate is of a profile’s program or is ϕperson_φ for some ϕφ, and a platform goal otherwise; the interactive variables of an agent a in r are the variables X of the asks ask(T, t(X)) written by the reductions of asking clauses at a in r; the interface variables IaI_a of a in r form the least set that contains the interactive variables of a and the variables of every term assigned, by a transition of r at a, to a variable in IaI_a; and the ask-stream variables of a are the variables at the ask-stream argument of a platform goal of a in a configuration of r and the tail variable of each list assigned to one of them. Definition 3.8 (Log). For i≥1i≥ 1, let θi _i be the restriction to IaI_a of the assignments the transition ci→ci+1c^i→ c^i+1 adds at a, the identity substitution where it adds none; the transition is logged if it is a Reduce of a person goal of a and θi _i is not the identity, and its entries are the triples (ti,a,Vθ1⋯θi)(t_i,a,V _1·s _i) for the interactive variables V of a such that a variable of Vθ1⋯θi−1V _1·s _i-1 is in the domain of θi _i; and the log of r is the sequence of the entries of its logged transitions, in the order of r. An entry of the log is an answer with the question it answers, as the person was shown it, so the log is what the people were asked and what they answered and nothing else; a run adds nothing to the program it runs. Reading the logs and analysing the runs — counting, aggregating, comparing populations, plotting — is separate software, outside the language and outside this paper. A simulated run is a run of the platform. The mapping that says so reads the platform’s configuration off the platform goals, as vGLP’s compilation mapping (Definition E.11) reads it off the compiled goals, with the person goals in the place of the construct processes and the dispatcher. Definition 3.9 (Simulation Mapping). The simulation mapping σ of r takes a configuration (c,t,α)(c,t,α) of r, with σa _a the readers substitution of a in c, to the configuration of the vmaGLP transition system over P and M with, at each agent a∈Pa∈ P: • G = the multiset of the platform goals of a in c, each read back to its source with its ask stream dropped: q(S1,…,Sn,D)q(S_1,…,S_n,D) as the n-ary goal q(S1,…,Sn)q(S_1,…,S_n), q1(S1,…,Sn,X?,D)q_1(S_1,…,S_n,X?,D), and q1(S1,…,Sn,X,D)q_1(S_1,…,S_n,X,D) as the asked goal, and any other platform goal as itself; the merge goals the compilation adds and the person goals contributing nothing; • H = the variables of IaI_a that occur in a person goal of a in c or in an ask in σa _a, each with its type, a writer where the person writes and a reader where the program writes; • σr _r = the restriction of σa _a to the assignments added by a Reduce of a platform goal of a to variables other than ask-stream variables, and to those added by a Reduce of a person goal of a to variables X∈IaX∈ I_a with X?X? occurring in c. Let r be an sGLP run of the simulation program N of (M,P,π)(M,P,π) over P from its initial configuration c0c^0, π over a well-formed population, and σ the simulation mapping of r. Theorem 3.10 (Soundness). σ(r)σ(r) is a proper safe computation of the vmaGLP transition system over P and M from σ(c0)σ(c^0) in which every Answer and every Dismiss is the image of a Reduce of a person goal. Corollary 3.11. Where every gag_a is the initial goal agent(ch(_?,_),ch(_?,_)) of M, σ(r)σ(r) is a proper safe run of the vmaGLP transition system over P and M. The proofs are in Appendix A. What a simulation reports is therefore something the deployed platform can do, with the people’s answers given by the stochastic agents: a person procedure’s goal computes the answer, and the person process, which logs it, may be the one that assigns the program’s variable with it. Simulated time advances only at a Release, and ⌈M⌉ M has no rated goal, so it advances only with the persons’ acts. The converse — that every run of the platform is the image of a simulated run under some population — is not claimed: a simulation shows what its profiles do. 4. Implementation sGLP is implemented in GLP by Gillespie’s method (Gillespie, 1977), as the stochastic pi-calculus was implemented in Flat Concurrent Prolog (Regev et al., 2000; Priami et al., 2001; Silverman et al., 1988): by a transformation of sGLP programs into GLP, a monitor process written in GLP, and one thing from the machine, a guard that succeeds when it has come to rest. The engine, the compiler and the type checker of GLP (Shapiro, 2026b) are not changed. The guard. A machine step carries no simulated time, so the monitor may draw only when no transition of the machine is possible; with no way to learn that, it cannot know when to draw. GLP has the guard when_idle, which suspends while the machine has a Reduce or a Communicate to make and succeeds when it has none (Shapiro, 2025b). It is sound for one machine and not for many — in a multiagent system a communication changes an agent’s configuration without that agent taking a transition — which is why the simulator hosts the whole population in one machine. SpiFcp’s monitor did the same, waiting on the Logix system’s idle_wait before its next draw (Silverman et al., 1988). The monitor. The monitor is Gillespie’s algorithm (Gillespie, 1977) written in GLP, in its first reaction form (Section 2): a GLP goal holding the simulated clock, the pending requests in a queue by activation time, the run’s seed and its horizon. Its input is one stream, a mutual reference of GLP’s into which every person goal appends; a request rated(R, Tok) asks for a goal of rate R to be released, and the monitor assigns it an activation time, the clock plus −lnU/R- U/R with U=K/(231−1)U=K/(2^31-1) and K drawn by random from its seed, and queues it. Its release clause is guarded by when_idle: when the machine rests, every request sent has arrived, so the queue is that of the configuration; the monitor advances the clock to the least activation time and binds that request’s Tok, which is Release. It stops when the least activation time is past the horizon or the queue is empty at rest, and writes the clock. The clock counts simulated seconds. The module, the implementation of the core of Gillespie’s algorithm, is Appendix C. The transformation. A profile is translated into GLP: its person procedures take a third argument, the monitor’s reference, which the procedures they call that hold rated goals take as well; and a rated goal G @ r becomes the request rated(r, Tok) appended to that reference, followed by G with Tok? as an added first argument, matched by a clause that takes the goal only once the monitor has bound it. A person declaration T =::= p becomes a clause of the person process, and the run declaration becomes the initial goals of the run. The transformation is a GLP program: it reads an sGLP program in a term form, one GLP term per declaration and clause, checks that its population is well formed (Section 3), and prints GLP source, as the compiler of grassroots social contracts reads contracts (Golike et al., 2026); the syntax printed in this paper is the surface form of that term form. The profiles and populations of Sections 5 and 6 are translated by it; the vGLP program’s compilation and the harness of a run are written by hand. GLP’s own Goal@Agent, which places a goal at an agent in a boot clause, is untouched. The person process. In vGLP’s canonical compilation an asking clause writes an ask — the question’s interactive type and the person’s end of its variable — on an ask stream that the compiler threads through every procedure that reaches a question, and the dispatcher, reading the initial goal’s ask stream, spawns on each ask the construct process that has the bridge draw the widget (Shapiro, 2026d). In a simulation the dispatcher’s place is taken by a GLP process, the person process of the agent: it holds the agent’s stochastic person, one profile per dimension, and a seed, and on each ask it spawns the goal p(X,S,)p(X,S,Mon) of the person procedure p that its profile declares for the type, with X the person’s end, S a seed it draws from its own generator, a value with the full range, and Mon the monitor’s reference. The person goal answers into a copy of the question, and the person process hands the program’s variable the answer once the positions the person writes are ground, with fresh writers at the positions the program writes, whose readers it hands the person goal — vGLP’s Answer, which waits on nothing the program writes — and that is how it comes to log it. The platform’s program compiles as for the phone. The run. The population runs as one program in one machine, and an agent is an attribution: its initial goal as the program states it, with the agent’s number and the lists it is created with, its person process, and what they spawn. The agents are numbered 1,…,n1,…,n. The harness’s goals are the network between the agents, a mutual-write merge of their output streams and a tree of routing goals delivering each message to the input stream of the agent it names, and the monitor. Every draw of the run is by random from the run’s seed: the monitor draws from it directly, and the harness draws each agent’s profiles and its person process’s seed from a separate block of a second generator started from it, so that the agents’ draws are independent streams and the run is reproducible where the machine’s schedule is deterministic, as GLP’s is. The log. The person process writes the log of its agent: one line for each answer of a person procedure, with the simulated time, which it asks of the monitor, the agent, the interactive type and the term handed over, the positions the program writes as variables. Everything the log records crosses the person process, and nothing else does. The harness names the log’s sink when the run starts. The implementation decisions beyond Sections 2 and 3 are in Appendix B. We claim, informally, that a run of the transformed program is an sGLP run of the simulation program: the transformed clauses reduce as the source clauses do, a request’s token is bound only by the monitor, only when when_idle has succeeded, which is quiescence, and only for the least activation time, which is Release; and the monitor’s reductions, the harness’s and the person process’s but the one that assigns the program’s variable are stutters. The claim, tested. Two tests in the repository check the claim where it bites. With a rated goal and an unrated goal that runs on, the unrated goal runs to rest before the rated one is released, whichever is spawned first: when_idle succeeds at quiescence and not before. With four pending requests of rates 1/second, 2/second, 30/minute and 3600/hour and nothing else, the first 10,000 times between releases have mean 0.22060.2206 s and variance 0.049340.04934 s2, against 1/4.5=0.22221/4.5=0.2222 and 1/4.52=0.049381/4.5^2=0.04938 of Proposition 2.5, 0.7%0.7\% and 0.08%0.08\% under. The cost. Measured on one machine, the social graph of Section 5 at its mix: 100 agents for a year is 14,459 answers in 9.1 s of wall-clock time, 1,596 releases a second, at 80 MiB; 30 days at 100, 200 and 500 agents cost 29, 32 and 46 ms an agent and 2.3, 2.6 and 3.8 ms an answer; and 1,000 agents for five years is 740,622 answers in 2,291 s, 323 releases a second from start to end, at 555 MiB at the peak, the memory flat throughout. The draw of a population of 100 costs about 2 s besides. How it was built. The implementation — the monitor, the person process, the two translations, the harnesses, the replays and the tests — was written by Claude (Anthropic) from this paper, by the Human–Science–AI methodology (Golike et al., 2026; Shapiro, 2026b): the paper is the source of authority for coding, and every gap coding found was repaired in the paper before it was repaired in the code; the runs’ analyses and the figures were made the same way. 5. Example: The Grassroots Social Graph The platform’s agent offers friendship to a peer its person picks, and puts each offer that arrives to its person as a card. The agents are numbered 11 to n; the first half are male and the rest female, and each agent is created with the list of the other agents of its sex and the list of those of the other sex, and starts by asking its person the first menu, by its exported procedure start. Peer ::= Constant. YesNo ::= yes ; no. Peers ::= [] ; [Peer | Peers]. Choice ::= same(Peer) ; other(Peer). Menu ::= menu(Peers, Peers, Choice?). Card ::= card(Peer, YesNo?). %% Show the person both lists, and hand them the choice. procedure (Menu)*ask(Peers?, Peers?, Choice). (menu(Ss?, Os?, C))*ask(Ss, Os, C?). %% Show the person who offers, and hand them yes or no. procedure (Card)*respond(Peer?, YesNo). (card(From?, A))*respond(From, A?). The agent’s own question is Menu, in writer mode: ask writes the two lists at once and hands the person the choice, which stays open while offers come and go, and each offer the person makes is followed by a new menu. An arriving offer is Card, also in writer mode: respond shows the person who offers and hands them yes or no, and the reply carries their answer back when they give it. The agent’s clauses, in the repository11 1 https://github.com/EShapiro2/GLP, directory programs/sglp., send an offer to the peer the person picks and ask again, put each offer that arrives to the person and reply with their answer, and drop the replies to their own offers; both interactive types are in writer mode, so their person procedures take readers. The profiles are two dimensions of two. one_of(Xs?, S?, X) draws X uniformly from the list Xs by random from the seed S, and is never called on an empty list; it is ordinary GLP, in the repository. person homophile. Menu =::= homophile_menu. procedure homophile_menu(Menu?, Integer?). homophile_menu(M, S) :- random(S?, 100, K, S1), pick(K?, S1?, M?) @ 1/week. procedure pick(Integer?, Integer?, Menu?). pick(K, S, menu(Ss, _, same(P?))) :- K? =< 98, ground(Ss?) | one_of(Ss?, S?, P). pick(K, S, menu(_, Os, other(P?))) :- K? > 98, ground(Os?) | one_of(Os?, S?, P). person wary. Card =::= wary_card. procedure wary_card(Card?, Integer?). wary_card(C, S) :- random(S?, 100, K, _), answer(K?, C?) @ 1/day. procedure answer(Integer?, Card?). answer(K, card(_, yes)) :- K? =< 20 | true. answer(K, card(_, no)) :- K? > 20 | true. run 100 agents [ approach ~ (homophile : 0.6 ; indifferent : 0.4), response ~ (wary : 0.7 ; sociable : 0.3) ] until 1 year seed 20260927. A homophile answers a menu after a week on average, from when it is asked, and picks a peer of their own sex 98 times in 100, uniformly from the list the menu shows; the indifferent is the homophile at 2/week and 50. A wary person answers a card after a day on average and declines four times in five; the sociable is the wary at 1/hour and 90. Approach and response make four profiles, and with sex eight kinds of agent. Each agent starts by asking its person the first menu. Definition 5.1 (Friendship Graph of a Run). The friendship graph at simulated time t of a run of this population is the graph on its agents P whose edges are the a,b\a,b\ for which the run’s log (Definition 3.8) has an entry (t′,a,card(b, yes))(t ,a, |card(|b |, yes)|) or an entry (t′,b,card(a, yes))(t ,b, |card(|a |, yes)|) with t′<t <t. An edge is a card answered yes by either of its two agents before t, the card showing the other. A line chart of the edges of the friendship graph by month for two seeds, split into edges within a sex and across the sexes. Figure 1. The edges of the friendship graph at the end of each month, in two runs of 100 agents for one year: all edges, those within a sex and those across the sexes.A line chart of the edges of the friendship graph by month for two seeds, split into edges within a sex and across the sexes. Results. We ran this population with 100 agents for one year, with the seeds 20260927 and 1, each run nine seconds of wall-clock time (Section 4); 61 agents drew homophile and 74 wary with the first seed, 55 and 61 with the second. With seed 20260927 the agents answered 7,235 menus, each answer an offer sent, and 7,224 cards, 2,767 of them yes; with seed 1, 7,523 menus and 7,507 cards, 3,543 of them yes. Figure 1 shows the edges of the friendship graph at the end of each month. At the end of the year the graph has 1,810 edges with seed 20260927 and 2,199 with seed 1; it is one component from the third month on with the first seed and from the second with the other, and at the end of the first month two agents have no friend yet. Of the 2,450 pairs within a sex, 50% and 59% are friends by the end of the year, and of the 2,500 pairs across the sexes, 23% and 30%: the indifferent answer a menu twice as often as the homophile, so 28% and 32% of the offers cross the sexes, and the edges across the sexes are 32% and 35% of the edges. A yes to the card of one who is already a friend adds no edge; with seed 20260927 that was 730 of the 1,962 yeses within a sex and 227 of the 805 across the sexes. Table 1. The friendship graph at the end of the year by the mix of profiles, 100 agents, over the seeds 1 to 20: the edges and those across the sexes, mean ± standard deviation, and the month by whose end the graph is one component, mean and latest. homophile wary edges across the sexes one by month none none 4,199±264,199± 26 2,113±182,113± 18 1.0, 1 none 70% 2,634±1592,634± 159 1,322±821,322± 82 1.3, 2 none all 1,698±321,698± 32 845±25845± 25 2.1, 3 60% none 3,213±883,213± 88 1,130±731,130± 73 1.0, 1 60% 70% 1,926±1471,926± 147 626±73626± 73 2.2, 4 60% all 1,216±511,216± 51 385±37385± 37 3.0, 5 all none 2,163±222,163± 22 91±791± 7 1.1, 2 all 70% 1,335±741,335± 74 41±541± 5 2.4, 3 all all 850±20850± 20 20±420± 4 3.8, 7 Figure 2. The friendship graph at the end of the year of the run with seed 20260927 as an adjacency matrix, a dot per edge: blue between two men, red between two women, green between a man and a woman. The agents are ordered by sex and within a sex by profile: homophile wary (HW), homophile sociable (HS), indifferent wary (IW), indifferent sociable (IS).An adjacency matrix of the friendship graph at the end of the year, agents ordered by sex and profile, edges coloured by the sexes of the pair. What the mix does. Table 1 has the friendship graph at the end of the year for each mix of none, 60% or all homophile with none, 70% or all wary, over twenty seeds, 1 to 20, the mean and the standard deviation of each count, and Figure 2 shows the graph of the run with seed 20260927 by profile: a sociable agent’s row is dense, a wary one’s sparse, and between two homophile of different sexes there is hardly an edge. The edges go from about 850 with all homophile and all wary to about 4,200 with none of either, the spread over the seeds a few per cent of the mean at every mix: the homophile offer half as often as the indifferent and to half the peers, and the wary accept a fifth of the offers where the sociable accept nine in ten, though many of the sociable’s yeses go to friends already, so all sociable in place of all wary has four and a half times the yeses and two and a half times the edges. With all homophile the edges across the sexes are 2% to 4% of the edges and the graph within each sex is near complete, 2,072 edges of the 2,450 pairs with all sociable; with none homophile they are half the edges. In every one of the 180 runs the graph is one component by the end of the year: by the end of the first month at every mix with none wary, and at the latest by the seventh, with all homophile and all wary. Scale. The same population at 1,000 agents, 500 of each sex, for five simulated years, seed 20260927, is 740,622 answers in 38 minutes of wall-clock time (Section 4), 147,543 of the 370,245 cards answered yes. The friendship graph has 28,211 edges at the end of the first year, 8,697 of them across the sexes, and 116,892 at the end of the fifth, 37,126 across; it is one component from the third month on, and at the end of the first month 19 agents have no friend yet. 6. Example: Coins Among Friends The second platform is coins among friends, the coins-only restriction of grassroots currencies (Shapiro, 2022; Shapiro, 2026d): a person’s coins are units of their debt, a person holds only their friends’ coins, and a swap at par between friends is mutual credit. The agent’s question is a menu showing its friends and its wallet and taking a request, to pay a friend or to propose a swap to one; a friend’s proposal is a card showing who offers how many and how many of that friend’s coins one holds, taking yes or no. A payment sends the friend their own coins, which redeems them; an accepted swap issues to each party K coins of the other’s; and while a card waits for its answer the agent takes neither a message nor a request. Peer, Peers and YesNo are those of Section 5. Holding ::= holding(Peer, Integer). Wallet ::= [] ; [Holding | Wallet]. Request ::= pay(Peer, Integer) ; swap(Peer, Integer). Menu ::= menu(Peers, Wallet, Request?). Offer ::= offer(Peer, Integer, Integer, YesNo?). %% Show the person their friends and wallet, and hand them %% the request. procedure (Menu)*ask(Peers?, Wallet?, Request). (menu(Fs?, W?, R))*ask(Fs, W, R?). %% Show the person who offers how many, and how many of %% theirs they hold; hand them yes or no. procedure (Offer)*respond(Peer?, Integer?, Integer?, YesNo). (offer(From?, K?, Held?, A))*respond(From, K, Held, A?). The agent’s clauses, in the repository, send a friend the person pays what the wallet holds of that friend’s coins, up to the amount asked, and ask again; send a friend the person chooses a proposal of K and ask again; put a proposal that arrives to the person, and on yes hold K of the proposer’s coins and send them K of the agent’s own, on no send a decline; hold coins that arrive from a friend, or redeem them where they are the agent’s own; and drop the declines of their own proposals. The profiles are two dimensions of two; one_of is that of Section 5: %% Pay a friend whose coins I hold one to five; holding none, %% propose a swap of ten to a friend. procedure request(Integer?, Menu?). request(S, menu(Fs, [], swap(F?, 10))) :- ground(Fs?) | one_of(Fs?, S?, F). request(S, menu(_, [H|Hs], pay(F?, K?))) :- ground(H?), ground(Hs?) | random(S?, 5, K, S1), one_of([H?|Hs?], S1?, Hd), issuer(Hd?, F). person spender. Menu =::= spender_menu. procedure spender_menu(Menu?, Integer?). spender_menu(M, S) :- request(S?, M?) @ 1/day. person cautious. Offer =::= cautious_offer. procedure cautious_offer(Offer?, Integer?). cautious_offer(O, _) :- weigh(O?) @ 1/hour. procedure weigh(Offer?). weigh(offer(_, _, Held, yes)) :- Held? =< 20 | true. weigh(offer(_, _, Held, no)) :- Held? > 20 | true. run 100 agents [ spending ~ (spender : 0.5 ; saver : 0.5), credit ~ (cautious : 0.5 ; generous : 0.5) ] until 1 year seed 20260927. A spender acts daily and a saver weekly, with the same request: each pays a friend whose coins they hold one to five, and holding none proposes a swap of ten to a friend drawn from the list; issuer reads the issuer of a holding. The cautious accept a proposal while holding at most twenty of the proposer’s coins, and the generous accept one as it comes, each within an hour on average. Each agent is created with its identifier, its friends in the friendship graph at one year of the run of Section 5, and an empty wallet, and starts by asking its person the first menu, by its exported procedure start. Definition 6.1 (Wallet, Circulation). Let Wa(c)W_a(c) be the term at the argument of type Wallet of the goal of the procedure agent at agent a in a configuration c, the wallet of a in c. The circulation at simulated time t of a run r of this population is ∑a∈P∑holding(_, k)∈Wa(c)k _a∈ P _ holding(\_ , k )∈ W_a(c)k, c the last configuration of r with simulated time at most t. The configuration c is quiescent, the clock advancing only at a Release (Definition 2.3), so every wallet in it is ground. Every holding is of another’s coins, so the circulation is the debt the agents hold of one another. Results. We ran this population with 100 agents for one year over the friendship graph at one year of Section 5’s run of the same seed, with the seeds 20260927 and 1 (1,810 and 2,199 edges), each run about ten seconds of wall-clock time. With seed 20260927 the agents paid 17,232 times and proposed 2,908 swaps, 2,840 accepted and 68 declined; with seed 1, 15,873 pays and 2,726 proposals, 2,693 accepted and 33 declined. An accepted swap of ten issues twenty coins and a payment redeems what it pays, so the circulation is what has been issued less what has been redeemed: it is 2,567 and 2,837 coins at the end of the first month and grows by about 700 and 800 a month to 10,467 and 11,355 at the end of the year, held in 711 and 830 holdings by 97 of the 100 agents with the first seed and by all of them with the second. The cautious decline a proposal from a friend of whose coins they hold more than twenty, so declines come as holdings grow: 68 of the 2,908 proposals were declined with seed 20260927, 57 of them in the second half of the year. Figure 3 shows who holds whose coins in the run with seed 20260927, in which 48 agents drew spender and 59 cautious: at the end of the year 9,754 of the 10,467 coins are spenders’ coins in savers’ wallets, the spenders having issued 10,109 of the coins out and the savers holding 9,916 of them, and the two run together from the first month; the other three pairs hold about seven hundred between them. Figure 4 shows the holdings one by one at the end of that year: the generous savers hold 6,341 coins and the cautious savers 3,575, where no cautious holding passes thirty, since the cautious decline above twenty; the cautious spenders have 7,164 coins out and the generous spenders 2,945; and the two spender profiles hold about five hundred and fifty between them. Two charts by month: the circulation split by which profile holds which profile's coins, and the coins issued and held by spenders and by savers. Figure 3. The run with seed 20260927, 100 agents, half spenders and half cautious, by month. Left: the circulation by who holds whose coins. Right: the coins issued by the spenders and by the savers, and those held by each — the credit each profile has given and received.Two charts by month: the circulation split by which profile holds which profile's coins, and the coins issued and held by spenders and by savers. Figure 4. Who holds whose coins at the end of the year of the run with seed 20260927: holders by row, issuers by column, a cell the coins held, white where none. The agents are ordered by profile — spender (Sp) or saver (Sa), cautious (C) or generous (G) — the holders’ profiles by the coins they hold and the issuers’ by the coins they have out, most first.A matrix of who holds whose coins at the end of the year, holders by row and issuers by column, ordered by profile, coloured by the coins held. Table 2. Coins among friends at the end of the year by the mix of profiles, 100 agents over the friendship graphs of Section 5, over the seeds 1 to 20, mean ± standard deviation: the circulation, the proposals made and those declined. spenders cautious circulation proposals declined none none 1,660±1161,660± 116 687±10687± 10 00 none half 1,660±1161,660± 116 687±10687± 10 00 none all 1,655±1151,655± 115 687±10687± 10 0.1±0.20.1± 0.2 half none 11,546±72211,546± 722 2,917±1312,917± 131 00 half half 11,282±79711,282± 797 2,961±1432,961± 143 64±2564± 25 half all 10,328±62110,328± 621 3,030±1503,030± 150 190±49190± 49 all none 1,702±1481,702± 148 4,369±274,369± 27 00 all half 1,683±1551,683± 155 4,368±274,368± 27 0.1±0.30.1± 0.3 all all 1,675±1351,675± 135 4,370±294,370± 29 1.2±1.71.2± 1.7 A line chart of the coins in circulation by month for none, half and all spenders, two seeds. Figure 5. The circulation at the end of each month with half the agents cautious and none, half or all of them spenders, 100 agents for one year over the friendship graphs of Section 5, seeds 20260927 and 1.A line chart of the coins in circulation by month for none, half and all spenders, two seeds. What the mix does. Table 2 has the circulation at the end of the year for each mix of none, half or all spenders with none, half or all cautious, over the seeds 1 to 20, each over the friendship graph of Section 5’s run of the same seed, and Figure 5 the circulation by month with half cautious, for the two seeds of the figures. The circulation is highest where spenders and savers mix: about 11,300 coins at half and half, within 800 over the seeds, and still growing, against about 1,700 with all savers or all spenders. A payment carries a friend’s own coins back to them, and a spender pays daily, so with all spenders a swap’s twenty coins are redeemed within days and after 4,369 swaps 1,702 coins are out; a saver pays weekly, so with all savers few swaps are made and few coins are out; and at half and half a saver holds for weeks the coins of the spenders who pay it, which is where the circulation is. The credit dimension hardly bites at these holdings: with all savers or all spenders a holding passes twenty in a run or two of the twenty, so those runs are the same whatever the credit mix but for a decline or two, and only with half the agents spenders do the cautious decline, 64 of 2,961 proposals on average, and 190 of 3,030 with all cautious. 7. Related Work Six lines of work meet here: process calculi and languages with rates, simulated exactly; rule-based languages whose simulators do not enumerate the species they generate; languages and formalisms for continuous-time agent-based simulation; the agent-based platforms and the testing of multiagent systems in simulation; simulated people with designated profiles; and what the two examples study, homophily in the formation of friendships and the circulation of mutual credit. sGLP differs from all of them in one way: it simulates the program the platform deploys, and its stochastic specification covers the person. Appendix D expands each line. Calculi and languages with rates. The stochastic pi-calculus attaches a rate to each prefix (Priami, 1995); its biochemical variant moves the rate onto the channel and settles the race among the enabled communications by Gillespie’s direct method (Priami et al., 2001; Gillespie, 1977), and BioSPI implemented it in Flat Concurrent Prolog (Shapiro, 1989; Regev et al., 2000; Priami et al., 2001; Silverman et al., 1988), a monitor drawing the channel and advancing the clock, as ours does. The stochastic pi-machine groups identical processes and counts the copies, and is proved reduction-equivalent to the calculus (Phillips and Cardelli, 2007); a later machine carries the grouping to restricted channels (Paulevé et al., 2010). Bio-PEPA is a stochastic process algebra with the same simulation (Ciocchetta and Hillston, 2009), and stochastic concurrent constraint programming attaches rates to a concurrent constraint language and simulates it by Gillespie’s method (Bortolussi and Policriti, 2008), the nearest language to sGLP. The grouping is not available to us, since no two agents of a grassroots platform share a state; the proof we meet in the same form, Theorem 3.10. Rule-based languages. Kappa’s simulator does not count species at all (Danos et al., 2007): it over-approximates the next events, rejects the draws that apply no rule, corrects the time advance, and wakes only the rules a static activation relation names; in sGLP the rules are the interactive types, few, and the instances the open questions, many, and the activation relation follows from the semantics, since a reduction reaches one agent. Continuous-time agent-based simulation. ML3 specifies an agent by stochastic rules of a guard, a rate and an effect, alternative decisions competing by stochastic race, and simulates by the direct method with a dynamic dependency graph (Köster et al., 2024); DEVS is the discrete-event formalism such simulators rest on (Zeigler et al., 2000). ML3 is the nearest prior work to sGLP, and the difference is what is simulated: there the rules are the model, here a vGLP program deployed as it stands, and the stochastic specification covers the person’s answers. Agent-based platforms, and testing in simulation. NetLogo, Repast, MASON, Mesa and krABMaga schedule every agent at each step of a discrete clock (Antelmi et al., 2024), where a stochastic race has no formulation (Köster et al., 2024), and none has a place for the person. Testing a multiagent system by simulating the code it deploys, with no surrogate, is argued for BDI agents mapped onto a discrete-event simulator (Baiardi et al., 2026); there the agents are the system and no person is simulated, where here the program is the platform’s and the person is what is drawn. Simulated people with profiles. Generative agents give each simulated person a text persona and have a language model answer for them (Park et al., 2023), OASIS runs a million such agents on a social platform (Yang et al., 2024), and user simulation evaluates interactive systems by simulated users with personas (Balog and Zhai, 2024; Liu et al., 2026). An sGLP profile is a program with rates, typed by the dual of the question it answers, drawn from a seed and reproducible, and the simulation is a run of the deployed program; a persona is a text and its answers are a model’s. What the examples study. Homophily, the tendency to befriend one’s like, is the best-attested regularity of social networks (McPherson et al., 2001), and Currarini, Jackson and Pin model friendship formation under it, with the mixing set by a group’s size and bias (Currarini et al., 2009); Section 5’s runs are such a model’s dynamics, with the bias a profile and the platform the one deployed. Mutual credit is studied on the Sardex network, its transactions’ cycles and the liquidity they save (Iosifidis et al., 2018; Fleischman et al., 2020; Littera et al., 2017), and modelled for LETS (Schraven, 2001); Section 6 simulates coins among friends over the friendship graph the social graph formed, with spending and credit as profiles. The exponential assumption. The inter-event times of human activity are heavier-tailed than exponential; the non-Markovian and the Laplace Gillespie algorithms simulate renewal processes with other distributions (Masuda and Vestergaard, 2021), and nothing in sGLP fixes the exponential: drawing a rated goal’s activation time from another distribution changes the draw and leaves the language as it is. What is new. To the best of our knowledge, sGLP is the first language in which the person of a deployed multiagent program is specified as a stochastic agent answering the questions that program puts to them, so that one program is simulated at scale and deployed on a phone without being rewritten, and the first in which the stochastic specification is confined to the person while the machine keeps a nondeterministic semantics with no scheduling assumption. 8. Conclusion sGLP is GLP with a rate on a goal, and a stochastic agent is an sGLP program in place of the UI of a vGLP platform and the person behind it, holding the person’s end of each question the platform asks, typed by the dual of the question’s interactive type. The platform’s program is unchanged; a population is a mix of profiles of person, each a program; and every simulated run is a run of the platform in which every answer was given by a stochastic agent, so what a simulation shows is something the platform can do. Here we employed an exponential distribution; another distribution can be employed without changing the language (Masuda and Vestergaard, 2021). The simulations done here show that platform behaviour can be tested and studied by mixing the stochastic profiles of its people: the friendship graph that forms, and how many coins circulate. Four limitations. The simulator hosts the population in one machine, where the guard when_idle is sound (Section 4). A rate per act is a modelling assumption, and the inter-event times of people are heavier-tailed than exponential (Section 7). The profiles and their rates are written, not estimated from how people use the deployed platforms. Reading the logs and analysing the runs is software outside the language (Section 3). References Antelmi et al. (2024) A. Antelmi, P. Caramante, G. Cordasco, G. D’Ambrosio, D. De Vinco, F. Foglia, L. Postiglione, and C. Spagnuolo Reliable and efficient agent-based modeling and simulation. Journal of Artificial Societies and Social Simulation 27 (2), p. 4. External Links: Document Cited by: Appendix D, §7. Baiardi et al. (2026) M. Baiardi, S. Burattini, G. Ciatto, and D. Pianini Testing BDI-based multi-agent systems using discrete event simulation. arXiv preprint arXiv:2602.13878. External Links: Link Cited by: Appendix D, §7. Balog and Zhai (2024) K. Balog and C. Zhai User simulation for evaluating information access systems. Foundations and Trends in Information Retrieval 18 (1–2), p. 1–261. External Links: Document Cited by: Appendix D, §7. Bortolussi and Policriti (2008) L. Bortolussi and A. Policriti Modeling biological systems in stochastic concurrent constraint programming. Constraints 13 (1–2), p. 66–90. External Links: Document Cited by: Appendix D, §7. Ciocchetta and Hillston (2009) F. Ciocchetta and J. Hillston Bio-PEPA: a framework for the modelling and analysis of biochemical networks. Theoretical Computer Science 410 (33–34), p. 3065–3084. Cited by: Appendix D, §7. Currarini et al. (2009) S. Currarini, M. O. Jackson, and P. Pin An economic model of friendship: homophily, minorities, and segregation. Econometrica 77 (4), p. 1003–1045. External Links: Document Cited by: Appendix D, §7. Danos et al. (2007) V. Danos, J. Feret, W. Fontana, and J. Krivine Scalable simulation of cellular signaling networks. In Proceedings of the 5th Asian Symposium on Programming Languages and Systems (APLAS’07), p. 139–157. External Links: Document Cited by: Appendix D, §7. Fleischman et al. (2020) T. Fleischman, P. Dini, and G. Littera Liquidity-saving through obligation-clearing and mutual credit: an effective monetary innovation for SMEs in times of crisis. Journal of Risk and Financial Management 13 (12), p. 295. External Links: Document Cited by: Appendix D, §7. Gillespie (1977) D. T. Gillespie Exact stochastic simulation of coupled chemical reactions. The Journal of Physical Chemistry 81 (25), p. 2340–2361. External Links: Document Cited by: Appendix C, §1, §1, §2.2, §4, §4, §7. Golike et al. (2026) J. Golike, A. Lewis-Pye, and E. Shapiro Formalising and implementing grassroots social contracts: from legal text to grassroots platforms (full version). arXiv:2609.06231. Cited by: §1, §4, §4. Google (2024) Google Dart programming language. External Links: Link Cited by: §1. Iosifidis et al. (2018) G. Iosifidis, Y. Charette, E. Airoldi, G. Littera, L. Tassiulas, and N. Christakis Cyclic motifs in the Sardex monetary network. Nature Human Behaviour 2, p. 822–829. External Links: Document Cited by: Appendix D, §7. Köster et al. (2024) T. Köster, O. Reinhardt, M. Hinsch, J. Bijak, and A. M. Uhrmacher A fast embedded language for continuous-time agent-based simulation. Journal of Artificial Societies and Social Simulation 27 (1), p. 10. External Links: Document Cited by: Appendix D, Appendix D, Appendix D, §7, §7. Lewis-Pye and Shapiro (2026) A. Lewis-Pye and E. Shapiro Volition-guarded multiagent atomic transactions: describing people and their machines. arXiv preprint arXiv:2604.25596. External Links: Link Cited by: Definition E.1, Definition E.2, §1. Littera et al. (2017) G. Littera, L. Sartori, P. Dini, and P. Antoniadis From an idea to a scalable working model: merging economic benefits with social values in Sardex. International Journal of Community Currency Research 21, p. 6–21. External Links: Document Cited by: Appendix D, §7. Liu et al. (2026) Y. S. Liu, Q. Wen, Y. Fan, S. Huang, R. Gao, J. Hou, M. A. Mohsin, Z. Di, B. Joshi, X. Tan, Y. Lu, X. Liu, H. Liu, H. Xing, G. Min, Z. Shan, M. C. Nguyen, I. Gupta, Y. Xiao, H. Collison, J. Huang, J. Li, S. Jajee, Y. Zhao, B. Hu, S. Ng, X. Chen, B. Lu, W. Xiao, A. Mohan, B. Sun, Y. Wu, Y. Xu, Y. Shen, R. Zhang, Z. Deng, Z. Zhang, Q. Zhu, D. Wang, Y. Wang, Y. He, Y. Hao, and X. Li PersonaEval: persona-based user simulation for evaluating interactive applications. arXiv preprint arXiv:2608.15838. External Links: Link Cited by: Appendix D, §7. Masuda and Vestergaard (2021) N. Masuda and C. L. Vestergaard Gillespie algorithms for stochastic multiagent dynamics in populations and networks. Note: Elements in the Structure and Dynamics of Complex Networks, Cambridge University Press External Links: 2112.05293 Cited by: Appendix D, Appendix D, §7, §8. McPherson et al. (2001) M. McPherson, L. Smith-Lovin, and J. M. Cook Birds of a feather: homophily in social networks. Annual Review of Sociology 27, p. 415–444. External Links: Document Cited by: Appendix D, §7. Park et al. (2023) J. S. Park, J. C. O’Brien, C. J. Cai, M. R. Morris, P. Liang, and M. S. Bernstein Generative agents: interactive simulacra of human behavior. In Proceedings of the 36th Annual ACM Symposium on User Interface Software and Technology (UIST 2023), p. 1–22. External Links: Document Cited by: Appendix D, §7. Paulevé et al. (2010) L. Paulevé, S. Youssef, M. R. Lakin, and A. Phillips A generic abstract machine for stochastic process calculi. In Proceedings of the 8th International Conference on Computational Methods in Systems Biology (CMSB ’10), p. 43–54. External Links: Document Cited by: Appendix D, §7. Phillips and Cardelli (2007) A. Phillips and L. Cardelli Efficient, correct simulation of biological processes in the stochastic pi-calculus. In Computational Methods in Systems Biology (CMSB 2007), Lecture Notes in Bioinformatics, Vol. 4695, p. 184–199. External Links: Document Cited by: Appendix D, Appendix D, §7. Priami et al. (2001) C. Priami, A. Regev, E. Shapiro, and W. Silverman Application of a stochastic name-passing calculus to representation and simulation of molecular processes. Information processing letters 80 (1), p. 25–31. External Links: Document Cited by: Appendix D, §1, §4, §7. Priami (1995) C. Priami Stochastic π-calculus. The Computer Journal 38 (7), p. 578–589. Cited by: §1, §7. Regev et al. (2000) A. Regev, W. Silverman, and E. Shapiro Representation and simulation of biochemical processes using the π-calculus process algebra. In Biocomputing 2001, p. 459–470. External Links: Document Cited by: Appendix D, §1, §4, §7. Schraven (2001) J. Schraven Mutual credit systems and the commons problem: why community currency systems such as LETS need not collapse under opportunistic behaviour. International Journal of Community Currency Research 5 (4). External Links: Document Cited by: Appendix D, §7. Shapiro (1989) E. Shapiro The family of concurrent logic programming languages. ACM Computing Surveys (CSUR) 21 (3), p. 413–510. External Links: Document Cited by: Appendix D, §1, §7. Shapiro (2021) E. Shapiro Multiagent transition systems for composing fault-resilient protocol stacks. arXiv preprint arXiv:2112.13650. External Links: Link Cited by: Definition E.1, Definition E.2. Shapiro (2022) E. Shapiro Grassroots currencies: turning mutual trust into liquidity. arXiv preprint arXiv:2202.05619. External Links: Link Cited by: §1, §1, §6. Shapiro (2023a) E. Shapiro Grassroots distributed systems: concept, examples, implementation and applications (brief announcement). In 37th International Symposium on Distributed Computing (DISC 2023). (Extended version: arXiv:2301.04391), Italy, p. 47:1–47:7. External Links: Link Cited by: §1. Shapiro (2023b) E. Shapiro Grassroots social networking: serverless, permissionless protocols for twitter/linkedin/whatsapp. In OASIS ’23, External Links: ISBN 979-8-4007-0225-9/23/09, Document Cited by: §1, §1. Shapiro (2024) E. Shapiro A grassroots architecture to supplant global digital platforms by a global digital democracy. arXiv:2404.13468, Proceedings of DAWO’24. External Links: Link Cited by: §1. Shapiro (2025a) E. Shapiro Characterising global platforms: centralised, decentralised, federated, and grassroots. arXiv preprint arXiv:2511.03286. External Links: Link Cited by: §1. Shapiro (2025b) E. Shapiro GLP: a grassroots, multiagent, concurrent, logic programming language for ai (full version). arXiv preprint arXiv:2510.15747, Summary in Proc. of ICLP’26, EPTCS 450, p. 119–133. External Links: Link Cited by: Definition E.5, Appendix E, §1, §2.1, §2.2, §2, §4. Shapiro (2026a) E. Shapiro Grassroots bonds: financing by the people, for the people. Note: arXiv:2603.13671 External Links: 2603.13671, Link Cited by: §1, §1. Shapiro (2026b) E. Shapiro Implementing grassroots logic programs with multiagent transition systems and ai (full version). arXiv:2602.06934. Summary to appear in Proc. of LOPSTR+PPDP’26. External Links: Link Cited by: Definition E.2, §1, §4, §4. Shapiro (2026c) E. Shapiro Types for grassroots logic programs (full version). arXiv preprint arXiv:2601.17957. External Links: Link Cited by: Appendix A, Appendix E, §1, §2.1, §2, Definition 3.4. Shapiro (2026d) E. Shapiro Volition elicitation: operational semantics for people and their machines. Note: arXiv:2607.14138 External Links: 2607.14138, Link Cited by: item 2, item 8, Definition E.1, Definition E.10, Definition E.11, Lemma E.12, Definition E.2, Definition E.3, Definition E.4, Definition E.4, Definition E.5, Definition E.6, Definition E.7, Theorem E.8, Definition E.9, Appendix E, Appendix E, Appendix E, §1, §3, §3, §4, §6. Silverman et al. (1988) W. Silverman, M. Hirsch, A. Houri, and E. Shapiro The logix system user manual version 1.21. In Concurrent Prolog: Collected Papers, p. 46–77. Cited by: Appendix D, §1, §4, §4, §7. Yang et al. (2024) Z. Yang, Z. Zhang, Z. Zheng, Y. Jiang, Z. Gan, Z. Wang, Z. Ling, J. Chen, M. Ma, B. Dong, P. Gupta, S. Hu, Z. Yin, G. Li, X. Jia, L. Wang, B. Ghanem, H. Lu, C. Lu, W. Ouyang, Y. Qiao, P. Torr, and J. Shao OASIS: open agent social interaction simulations with one million agents. arXiv preprint arXiv:2411.11581. External Links: Link Cited by: Appendix D, §7. Zeigler et al. (2000) B. P. Zeigler, H. Praehofer, and T. G. Kim Theory of modeling and simulation: integrating discrete event and continuous complex dynamic systems. 2nd edition, Academic Press. Cited by: Appendix D, §7. Appendix A Proofs Let r be an sGLP run of the simulation program N of (M,P,π)(M,P,π) over P from its initial configuration c0c^0, π over a well-formed population, and σ the simulation mapping of r. Theorem 3.10 (Soundness, restated) 0. σ(r)σ(r) is a proper safe computation of the vmaGLP transition system over P and M from σ(c0)σ(c^0) in which every Answer and every Dismiss is the image of a Reduce of a person goal. Proof. Let r=(c1,t1,α1),(c2,t2,α2),…r=(c^1,t_1, _1),(c^2,t_2, _2),… with (c1,t1,α1)=(c0,0,∅)(c^1,t_1, _1)=(c^0,0, ). Throughout, a variable of IaI_a occurs nowhere before the transition that introduces it, by the properness of the maGLP computation c1,c2,…c^1,c^2,… (Definition 2.4), and every clause of N is SRSW (Definition E.3). Safety. We show that each transition (ci,ti,αi)→(ci+1,ti+1,αi+1)(c^i,t_i, _i)→(c^i+1,t_i+1, _i+1) of r maps under σ to a transaction of the vmaGLP transition system over P and M or to a stutter; then σ(r)σ(r) is a safe computation from σ(c0)σ(c^0) (Definitions E.1 and E.2). A Release has ci+1=cic^i+1=c^i: a stutter. A Machine transition is a Reduce, a Communicate or a Cold-call of the maGLP transition system over P and N (Definition 2.3), and we take each by what it reduces or delivers. (1) A Reduce at a of a platform goal with an asking clause of ⌈M⌉ M replaces q(S1,…,Sn,D)q(S_1,…,S_n,D) by q1(S1′,…,Sn′,X?,D′)q_1(S _1,…,S _n,X?,D ) or q1(S1′,…,Sn′,X,D′)q_1(S _1,…,S _n,X,D ), X fresh, and adds to σa _a the assignment of D to the list of the ask ask(T, t(E)) and the tail D′?D ?, E the other end of X (Definition E.10). In the image, G loses q(S1,…,Sn)q(S_1,…,S_n) and gains the asked goal; H gains E, a variable of IaI_a that now occurs in an ask in σa _a; σr _r is unchanged, D being an ask-stream variable. This is the Ask of a’s goal with interactive variable X. (2) A Reduce at a of a platform goal with a compiled clause of M: G changes as the Reduce of the source goal with the source clause does (Lemma E.12), the platform goals and clauses of N being those of ⌈M⌉ M and read back as there; σr _r gains the assignments the source reduction adds, an assignment to a variable of IaI_a at a position the program writes, whose reader a person goal holds, among them where the clause writes into a question; and H is unchanged, since the reduction touches no person goal and no ask, and a variable it introduces occurs in neither. This is the source Reduce. A Reduce of a platform goal with a merge clause the compilation adds, which moves asks between ask streams, changes nothing σ reads: a stutter. (3) A Reduce at a of a person goal that adds no assignment to a variable of IaI_a: G and σr _r are unchanged, and so is H, each variable of IaI_a in the goal reduced occurring in a goal of the clause’s body, by SRSW, the variable of an ask taken from the ask stream now in the body of the person process’s clause. A stutter. (4) A Reduce at a of a person goal that adds an assignment X?:=uX?:=u with X∈IaX∈ I_a. X is a writer at a position the person writes, since the person goals hold the person’s end of each interactive variable, of the dual type (Definitions 3.1 and 3.5), and the type checker (Shapiro, 2026c) admits a clause only where it writes the positions its side writes; the clause being single-answer (Definition 3.4), X is the one such variable the reduction assigns. If X?X? occurs nowhere in cic^i: X∈HX∈ H before, occurring in the person goal reduced, and not after, its one occurrence in the clause being in the head; σr _r does not take the assignment; G is unchanged. This is the Dismiss of X by a. Otherwise X∈HX∈ H before, the writer occurring in the person goal reduced; after, X occurs in no person goal, its one occurrence in the clause being in the head, and its reader occurs in ci+1c^i+1, so X∉H′X∉ H ; u is a term of the type of X whose variables are fresh, readers Y1?,…,Yk?Y_1?,…,Y_k? at the positions the person writes and writers W1,…,WmW_1,…,W_m at the positions the program writes, by the moded type; their pairs Y1,…,Yk,W1?,…,Wm?Y_1,…,Y_k,W_1?,…,W_m? occur in the body of the clause, by SRSW, so in person goals of a in ci+1c^i+1, and are in IaI_a; so H′=H∖X∪Y1,…,Yk,W1?,…,Wm?H =H \X\∪\Y_1,…,Y_k,W_1?,…,W_m?\, σr _r gains X?:=uX?:=u, and G is unchanged. This is the Answer of a to X with u (Definition E.4). (5) A Communicate at a delivering an ask, or a list of asks, to a person goal: the ask leaves σa _a and its variable now occurs in a person goal, so H, G and σr _r are unchanged: a stutter. A Communicate delivering an assignment X?:=uX?:=u to a person goal, X∈IaX∈ I_a a writer at a position the program writes and X?X? held by the person: X?X? leaves the person goals and the variables of u, in IaI_a, enter them; σr _r loses the assignment; G is unchanged. This is the Present of the assignment. A Communicate delivering to a platform goal an assignment added by a Reduce of a platform goal, within a or from another agent, or one added by a Reduce of a person goal to a variable of IaI_a: the source Communicate, G and σr _r changing as there and H not at all. A Communicate delivering to a person goal an assignment of a variable that is not in IaI_a: a stutter. (6) A Cold-call from a to b moves a message between the network streams, which are arguments of platform goals: the source Cold-call. Every Answer and every Dismiss is the image of a Reduce of a person goal: by the cases, each is the image of a transition of case (4) and of no other. Properness. Let a variable occur in the source goals of a in σ(ci+1)σ(c^i+1) and not in σ(ci)σ(c^i). It occurs in a platform goal of a in ci+1c^i+1. If it occurs in no goal of a in cic^i, it occurs in no goal of a earlier, by the properness of the maGLP computation, hence in no H earlier, the variables of H occurring in goals of a or in asks assigned to ask-stream variables of goals of a. Otherwise it occurs in a person goal of a in cic^i and enters the platform goal by a Communicate of case (5), as a variable of the term u of an Answer of case (4); it was fresh at that Answer, and a variable of u occurs once in the clause of that Answer, by SRSW, so the variable that enters the platform goal is the pair of the one held, and neither occurred in G or in H before the Answer. Hence σ(r)σ(r) is proper (Definition E.5). ∎ Corollary 3.11 (restated) 0. Where every gag_a is the initial goal agent(ch(_?,_),ch(_?,_)) of M, σ(r)σ(r) is a proper safe run of the vmaGLP transition system over P and M. Proof. In c0c^0 agent a holds the platform goal ga′g _a and the person goal π(a)(Ua?,sa)person_π(a)(U_a?,s_a), σa=∅ _a= , and no variable of IaI_a occurs, so σ(c0)σ(c^0) has at each a the agent state (∅,(ga,∅))( ,(\g_a\, )), which is the initial local state of the vmaGLP transition system over P and M where gag_a is agent(ch(_?,_),ch(_?,_)) (Definition E.4); so σ(c0)σ(c^0) is its initial configuration, and σ(r)σ(r), a proper safe computation from it by Theorem 3.10, is a proper safe run (Definition E.1). ∎ Appendix B Implementation Notes The decisions the implementation takes where Sections 2, 3 and 4 leave a choice open, recorded here so that a reader of the code finds them stated. The code is programs/sglp of the GLP repository: monitor.glp; transform.glp, the transformation, and transform.sh, which runs it; and a directory per example with the vGLP program (graph.vglp, coins.vglp), its canonical compilation by hand, graph.glp or coins.glp, clause for clause as the README records, its sGLP source in the term form (graph_sglp.glp, coins_sglp.glp), the two modules the transformation prints from it — profiles.glp for the profiles and population.glp for the population — its harness, its run script and its reader of the log; and the tests, test_sglp.sh and tests/. • The clock is in simulated seconds; a year is 365.25365.25 days, and the units of until and of a rate are second, minute, hour, day, week and year, singular or plural after until. The horizon is inclusive: the clock never passes it, and the monitor stops when the least activation time would, or when the queue is empty at rest, and writes clock(T) last. • The monitor’s queue is a skew heap on the pair of activation time and sequence number, so two requests with one time are released in the order queued. A delay is −lnU- U times the unit’s seconds over the rate’s number, U=K/(231−1)U=K/(2^31-1), K in 1…231−21… 2^31-2 from random, the monitor’s seed threaded through its draws. • Seeds: the monitor draws from the run’s seed; a second generator, started from the run seed’s first draw, is cut into blocks of 40964096 draws, and from agent a’s block are drawn, in order, its profile per dimension and the seed of its person process, which draws for each person goal a value in 1…231−21… 2^31-2 and hands it as the goal’s seed, continuing with its own next seed: the goal’s draws and the process’s are on different seed chains, where handing the process’s next seed itself put a goal’s second draw and the next goal’s first on one seed, GLP’s random making the value a function of the next seed. The harness reaches the next block by 40964096 draws made one after the other, not by a closed form, since GLP fixes only that the next seed is a function of the seed and not the generator. The run’s seed plus the agent’s number was not used, since consecutive agents’ first draws then step by a constant. Each run’s draw — how many agents of each profile, and which agent has which — is computed again from the seed, without the run, and written beside the log. • The agents are numbered 1,…,n1,…,n, n even; in the social graph the first half are of one sex and the rest of the other, and each agent’s lists are in increasing order. Placement is attribution: an agent’s goals are its start goal, its person process and what they spawn; the harness’s goals belong to no agent. • The person process reads the ask stream of the agent’s initial goal, in the dispatcher’s place; a person goal answers into a copy of the question, and the person process hands the program’s variable the answer once the positions the person writes are ground, the positions the program writes as fresh writers whose readers the person goal keeps, a step after the person goal’s, and asks the monitor for the clock by a request time(T), answered at once, to log it. • The monitor’s input and the log’s sink are mutual references allocated by the root’s allocate_mutual_reference/2 and written by stream_append/3; the network is the root’s mwm/2 over the agents’ output streams and a balanced tree of deliver/4 goals. The log’s sink is read by send_to_user/1 and written tab-separated by the harness. • one_of of an empty list fails, since random requires a positive range; the lists of the examples are never empty. • The log is one line per answer: the simulated time in seconds, the agent, the interactive type and the term handed over, the positions the program writes as variables, separated by tabs. • The transformation prints one term a line, operators prefix, and chooses a question’s person procedure by the functor of its term, so the interactive types of a program must have distinct functors, which it checks; each dimension’s draw is printed with the population. one_of is shared by the two programs. • Coins among friends: the messages are pay, coins, propose and decline. A wallet keeps its holdings in order, a new issuer’s at the end, and a holding that reaches zero is removed; the order decides only which holding a request draws. A pay of a friend whose coins the wallet does not hold would send zero coins and change nothing, and does not arise, since a request pays an issuer its menu shows. While a card waits for its answer the agent takes neither a message nor a request; after a yes the wallet is rebuilt before either is taken, and a request answered while a card waited is acted on after the card; after a pay the agent asks again once the wallet after the pay is known. The harness takes each agent’s friends from the friendship graph of Section 5’s run of the same seed and refuses a graph on which an agent has no friend, since one_of of an empty list fails. The circulation and the holdings of Section 6 are replayed from the log, each move at the answer the log shows for it; no move was deferred across a month’s end in the runs reported. Appendix C The Monitor: Gillespie’s Algorithm in GLP The monitor is the implementation of the core of Gillespie’s algorithm (Gillespie, 1977), in the first reaction form of Section 2, written in GLP over the guard when_idle. This is the whole module as it is in the repository, programs/sglp/monitor.glp, its comments replaced by this text; the transformation, the two examples, their harnesses and their tests are in the same directory. A request is rated(R, Tok), R a rate N/U and Tok a token the monitor binds to go at Release, or time(T), answered at once with the clock. The queue is a skew heap: a node holds an activation time, a sequence number, the token and two subheaps. TimeUnit ::= second ; minute ; hour ; day ; week ; year. Rate ::= /(Number, TimeUnit). Token ::= go. Request ::= rated(Rate, Token?) ; time(Number?). Queue ::= nil ; node(Number, Integer, Token?, Queue, Queue). Clock ::= clock(Number). The monitor goal holds its input stream, the clock in seconds, the queue, its seed, the next sequence number, the horizon in seconds and the log’s reference, and starts with the clock at zero and the queue empty. exported procedure monitor(Stream(Request)?, Integer?, Number?, MutualRef?). monitor(In, Seed, Horizon, Log) :- monitor(In?, 0, nil, Seed?, 0, Horizon?, Log?). procedure monitor(Stream(Request)?, Number?, Queue?, Integer?, Integer?, Number?, MutualRef?). monitor([rated(R, Tok?)|In], Clock, Q, Seed, Seq, Horizon, Log) :- random(Seed?, 2147483646, K, Seed1), delay(R?, K?, D), T := Clock? + D?, Seq1 := Seq? + 1, qmerge(node(T?, Seq?, Tok, nil, nil), Q?, Q1), monitor(In?, Clock?, Q1?, Seed1?, Seq1?, Horizon?, Log?). monitor([time(Clock?)|In], Clock, Q, Seed, Seq, Horizon, Log) :- monitor(In?, Clock?, Q?, Seed?, Seq?, Horizon?, Log?). monitor(In, _, node(T, _, go, L, R), Seed, Seq, Horizon, Log) :- when_idle, T? =< Horizon? | qmerge(L?, R?, Q), monitor(In?, T?, Q?, Seed?, Seq?, Horizon?, Log?). monitor(_, Clock, node(T, _, _?, _, _), _, _, Horizon, Log) :- when_idle, T? > Horizon? | stream_append(clock(Clock?), Log?, _). monitor(_, Clock, nil, _, _, _, Log) :- when_idle | stream_append(clock(Clock?), Log?, _). A rated request is assigned its activation time at once, the clock plus a delay drawn from the exponential distribution with its rate, and queued; this is the first reaction method, the time drawn when the goal is spawned. A time request is answered from the clock. The three clauses guarded by when_idle are taken only when the machine rests, so every request sent has arrived and the queue is that of the configuration: Release moves the clock to the least activation time, within the horizon, and binds that request’s token to go; the two stop clauses write the clock to the log when the least activation time is past the horizon or nothing is pending. The clauses are tried in order, so a request that has arrived is queued before the machine is found idle. procedure delay(Rate?, Integer?, Number). delay(N/U, K, D?) :- number(N?), N? > 0 | seconds(U?, S), P := K? / 2147483647, L := ln(P?), D := neg(L?) * S? / N?. procedure seconds(TimeUnit?, Integer). seconds(second, 1). seconds(minute, 60). seconds(hour, 3600). seconds(day, 86400). seconds(week, 604800). seconds(year, 31557600). The delay of a rate of N per unit U is −ln(K/(231−1))⋅S/N- (K/(2^31-1))· S/N seconds, S the seconds in U and K uniform in 1…231−21… 2^31-2 from the monitor’s seed, which is threaded through its draws; a year is 365.25365.25 days. procedure qmerge(Queue?, Queue?, Queue). qmerge(nil, Q, Q?). qmerge(node(T, S, K?, L, R), nil, node(T?, S?, K, L?, R?)). qmerge(node(T1, S1, K1?, L1, R1), node(T2, S2, K2?, L2, R2), node(T1?, S1?, K1, M?, L1?)) :- T1? < T2? | qmerge(R1?, node(T2?, S2?, K2, L2?, R2?), M). qmerge(node(T1, S1, K1?, L1, R1), node(T2, S2, K2?, L2, R2), node(T1?, S1?, K1, M?, L1?)) :- T1? =:= T2?, S1? < S2? | qmerge(R1?, node(T2?, S2?, K2, L2?, R2?), M). qmerge(node(T1, S1, K1?, L1, R1), node(T2, S2, K2?, L2, R2), node(T2?, S2?, K2, M?, L2?)) :- T2? < T1? | qmerge(R2?, node(T1?, S1?, K1, L1?, R1?), M). qmerge(node(T1, S1, K1?, L1, R1), node(T2, S2, K2?, L2, R2), node(T2?, S2?, K2, M?, L2?)) :- T2? =:= T1?, S2? < S1? | qmerge(R2?, node(T1?, S1?, K1, L1?, R1?), M). qmerge merges two skew heaps, the least pair of activation time and sequence number at the root, so that two requests with one activation time are released in the order they were queued; the token writer of each node is passed on with the node. Appendix D Related Work, Continued Section 7’s six lines of work, each expanded. Calculi and languages with rates. BioSPI implemented the biochemical stochastic pi-calculus in Flat Concurrent Prolog (Shapiro, 1989): each channel is an object carrying a base rate, processes post send, receive, dimer and withdraw requests to it, a monitor and the channel objects jointly compute the weighted rates, and the monitor draws the channel, completes one transmission, withdraws the losing offers of the two chosen processes and advances a clock (Regev et al., 2000; Priami et al., 2001; Silverman et al., 1988). Bio-PEPA (Ciocchetta and Hillston, 2009) is a process algebra for biochemical networks in the PEPA family, with stochastic simulation by Gillespie’s method among its analyses; stochastic concurrent constraint programming (Bortolussi and Policriti, 2008) attaches a rate to each action of a concurrent constraint program, with a continuous-time Markov chain semantics simulated by Gillespie’s method, which makes it the nearest language to sGLP: a concurrent constraint language with rates. The difference is where the rate sits and what is simulated: in sCCP every action is rated and the program is the model, in sGLP the platform’s program keeps vGLP’s semantics unchanged and only the person’s goals are rated. Two criticisms of BioSPI’s implementation. The stochastic pi-machine makes the cost of a simulation depend on the number of species rather than the number of molecules, by grouping identical processes and counting the copies, and reports its gene example running in ten seconds where their own previous version of SPiM took eight minutes and BioSPI twenty-one; the criticism is that the earlier simulators, BioSPI among them, describe no algorithm for keeping track of identical processes, the separate process per molecule being what they report of their previous version (Phillips and Cardelli, 2007). A later machine for stochastic process calculi carries the same point to restricted channels, and against the stochastic pi-machine itself: it stores each complex as one species, where a simulator in which every restricted channel has a globally fresh name carries one species and one reaction per copy (Paulevé et al., 2010). The second criticism is of a different kind: the stochastic pi-machine is proved reduction-equivalent to the calculus and shown to preserve apparent rates, which they report as the first correctness proof for the stochastic pi-calculus to cover optimisations of this kind; their own earlier machine was proved correct against a variant of the calculus (Phillips and Cardelli, 2007). What sGLP does about them. The first economy is not available to us, and not because of how we implement: two agents are interchangeable only while their machine states agree, and in a grassroots platform they stop agreeing as soon as they have different friends, so a population of a thousand people is a thousand states, no two with the same open questions. What carries over is the rest of the machinery — the next of M pending goals is found in O(logM)O( M) by a priority queue, where the linear scan of the direct method costs O(M)O(M) and a tree of propensities O(logM)O( M) (Masuda and Vestergaard, 2021; Köster et al., 2024) — together with one thing a vGLP program has for nothing: a reduction changes the resolvent of one agent, so an event touches the questions of that agent and of no other. Their grouping also needs every choice to carry an identifier, and where a choice has none their encoding creates an extra definition for it; a person declaration names an interactive type, so we have the identifier already (Phillips and Cardelli, 2007). They also record a restricted channel’s apparent rate as a delay, to keep the machine compositional where several machines run in parallel, on distributed or multi-core systems (Phillips and Cardelli, 2007); that is the setting of a deployed platform, one machine per agent, and not yet of our simulator, which hosts the population in one machine (Section 4). The second criticism we accept as the standard to meet, and meet it in the same form: the runs of the simulator are runs of the vmaGLP transition system of the very program being simulated, with the person’s answers drawn rather than given. Rule-based languages. Kappa’s simulator (Danos et al., 2007) keeps a superset of the events that may happen next, rejects the draws that do not correspond to a rule application, corrects the time advance so that the timings stay exact, and wakes only the rules a static activation relation names; its cost per event is independent of the number of species and of the number of agents, and logarithmic in the number of rules. In sGLP the rules are the interactive types, of which a platform has few, and the instances are the questions open at the agents, of which a population has many; the activation relation it computes statically we have from the semantics, since a reduction reaches one agent. Continuous-time agent-based simulation. In ML3 (Köster et al., 2024) agents cannot be grouped into subpopulations, so handling the transitions efficiently is what decides the cost, and the dependency graph is dynamic where a biochemical one is static. DEVS (Zeigler et al., 2000) is the formalism of discrete-event simulation — atomic models with time advances, coupled into networks — on which ML3 and the discrete-event simulators of agents rest; sGLP’s Release is a discrete event in that sense, and its machine steps between events take no time. Agent-based platforms, and testing in simulation. In NetLogo, Repast, MASON, Mesa and krABMaga (Antelmi et al., 2024), and in agent-based modelling at large, the clock is a discrete step: the choice of step size bears on the validity of the results, and an alternative that is retracted when another decision wins — a stochastic race — has no formulation (Köster et al., 2024). A platform’s agent is the whole of what is modelled, where a vGLP agent is a person and a machine, and only the person is drawn. Baiardi, Burattini, Ciatto and Pianini (Baiardi et al., 2026) argue that a multiagent system should be tested in simulation on the very specification that is deployed, with no surrogate, and map the control flow of BDI agents onto a discrete-event simulator at several granularities; the demand is ours too, and what is tested differs: their agents are the system under test and their environment is the simulator’s, where in sGLP the system under test is a vGLP program whose agents are people and machines, and the simulation replaces the people. Simulated people with profiles. Generative agents (Park et al., 2023) are simulated people whose memory, reflection and planning are done by a language model from a persona written as text, in a sandbox town; OASIS (Yang et al., 2024) scales such agents to a million on a simulated social platform, with recommendation and the platform’s actions modelled; user simulation in information retrieval (Balog and Zhai, 2024) evaluates search and recommendation systems by simulated users, and PersonaEval (Liu et al., 2026) evaluates interactive applications by persona-based simulated users driven by language models. All simulate the person by a persona and a model; none runs the deployed program, and none specifies the person’s behaviour stochastically, with a stated law. An sGLP profile is the person’s behaviour as a program with rates, typed by the dual of the question it answers, so that the simulation is a run of the deployed program (Theorem 3.10), drawn from a seed and reproducible; it lacks the persona’s richness, and the rates and the profiles are to be estimated from how people use the deployed platforms. What the examples study. McPherson, Smith-Lovin and Cook review homophily across the dimensions of social life, sex, age, race, religion, education and the rest, and find it structuring every kind of tie (McPherson et al., 2001). In Currarini, Jackson and Pin’s model agents of several types form friendships by meeting, with a preference bias for their own type, and they derive how the share of same-type friendships and the number of friends vary with a group’s relative size and its bias, which they fit to the Add Health data (Currarini et al., 2009); sGLP’s homophile and indifferent profiles are the bias, and Table 1 and Figure 2 are what the deployed platform does under it, not a model of it. On mutual credit, Iosifidis et al. analyse the cyclic motifs of the Sardex transaction network, where credit returns to its issuer around cycles (Iosifidis et al., 2018); Fleischman, Dini and Littera measure the liquidity obligation-clearing and mutual credit save on that network’s data (Fleischman et al., 2020); Littera et al. describe the system’s design and history (Littera et al., 2017); and Schraven models why a LETS need not collapse under opportunism (Schraven, 2001). None simulates the deployed program; Section 6’s runs are of coins among friends as the platform’s program executes it, with the people drawn. The exponential assumption. The non-Markovian Gillespie algorithm simulates coupled renewal processes by a first-order expansion accurate for large numbers of processes, and the Laplace Gillespie algorithm simulates exactly those whose inter-event distribution is a mixture of exponentials, which covers the fat-tailed distributions common in human interaction (Masuda and Vestergaard, 2021); a rate per act is a modelling assumption and not a fact about people. Appendix E Definitions and Results Recalled from vGLP Sections 2 and 3 and Theorem 3.10 rest on the following definitions and results of vGLP (Shapiro, 2026d), which rest in turn on GLP (Shapiro, 2025b) and its types (Shapiro, 2026c); they are recalled as stated there, each named by its title in that paper. Reduction, the writer mgu, goal identity and the transaction closure, which the vmaGLP transition system is defined over, are those of (Shapiro, 2025b; Shapiro, 2026d) and are not recalled. Definition E.1 (Transition System, Computation, Run, Safe, Live, Correct (Shapiro, 2021; Lewis-Pye and Shapiro, 2026; Shapiro, 2026d)). A transition system is a tuple TS=(C,c0,T,∼)TS=(C,c_0,T, ) where C is an arbitrary set of configurations, c0∈Cc_0∈ C a designated initial configuration, T⊆C×CT C× C a set of transitions, each a pair c→c′c→ c of non-identical configurations c≠c′∈Cc≠ c ∈ C, and ∼ a partial equivalence relation on T — an equivalence on a subset (∼)⊆Tdom( ) T; we write [t][t] for the class of t∈(∼)t ( ) under ∼ . A computation is a (nonempty, finite or infinite) sequence of configurations c1,c2,…c_1,c_2,…; it is a run if c1=c0c_1=c_0, and safe if ci→ci+1∈Tc_i→ c_i+1∈ T for every two consecutive configurations. A class [t][t] is enabled in c if c→c′∈[t]c→ c ∈[t] for some c′c . A run is live if no class [t][t], t∈(∼)t ( ), is enabled in every configuration of some suffix in which no member of [t][t] occurs, and correct if it is safe and live. Definition E.2 (Implementation (Shapiro, 2021; Shapiro, 2026b; Lewis-Pye and Shapiro, 2026; Shapiro, 2026d)). Given two transition systems TS=(C,c0,T,∼)TS=(C,c_0,T, ), the specification, and TS′=(C′,c0′,T′,∼′)TS =(C ,c _0,T , ), an implementation of TSTS by TS′TS is a function σ:C′→Cσ:C → C with σ(c0′)=c0σ(c _0)=c_0, in which case the pair (TS′,σ)(TS ,σ) is an implementation of TSTS. Given a computation r′=c1′,c2′,…r =c _1,c _2,… of TS′TS , σ(r′)σ(r ) is the computation σ(c1′),σ(c2′),…σ(c _1),σ(c _2),… with consecutive repetitions removed; a transition c′→d′c → d of TS′TS with σ(c′)=σ(d′)σ(c )=σ(d ) is a stutter, contributing no step to σ(r′)σ(r ). Definition E.3 (Guarded Clause, Volitional Procedure, Interactive Type, Interactive Term, Ordinary Clause, Procedure, vGLP Program (Shapiro, 2026d)). A guarded clause has the form H :- G | B, where H is the head, G a conjunction of guard predicates, and B the body; guard arguments are readers paired to head writers. A volitional procedure p of arity n is declared procedure (T)*p(T1,…,Tn)p(T_1,…,T_n)., where T1,…,TnT_1,…,T_n are the types of its arguments and T, in writer or reader mode as an argument type is, is its interactive type. A clause of it has the form (A)*p(S1,…,Sn)p(S_1,…,S_n) :- G | B, where the interactive term A is a term of type T, possibly a variable but not the anonymous variable, and it is the guarded clause p(S1,…,Sn,A)p(S_1,…,S_n,A) :- G | B, of arity n+1n+1, whose last argument is matched against the goal’s end of its interactive variable (Definition E.4). A clause is ordinary if it is not a clause of a volitional procedure. A vGLP program is a finite sequence of ordinary clauses and clauses of volitional procedures, each satisfying SRSW, a clause of a volitional procedure satisfying it as a guarded clause of arity n+1n+1; the clauses for the same predicate form a procedure. The set of goals ^(M) G(M) of a program M includes all goals over V and the vocabulary of M that satisfy SO, a goal of a volitional procedure of arity n being n-ary until it is asked and of arity n+1n+1 after (Definition E.4). Definition E.4 (vmaGLP Transition System (Shapiro, 2026d)). Given a vGLP program M, an asynchronous resolvent over M is a pair (G,σ)(G,σ) where G∈^(M)G∈ G(M) and σ is a readers substitution, and an agent state is a pair (Hp,(Gp,σp))(H_p,(G_p, _p)) of a finite set HpH_p of typed variables held by the agent’s person and an asynchronous resolvent. Given agents P⊂ΠP⊂ , the vmaGLP transition system over P and M is the transactions-based multiagent transition system (Definition “Transactions-Based Multiagent Transition System” of (Shapiro, 2026d)) over P, local states being agent states, initial local state (∅,(agent(ch(_?,_),ch(_?,_)),∅))( ,(\ |agent(ch(_?,_),ch(_?,_))|\, )), the following transactions, and the equivalence ∼ below: (1) Ask p: a unary transaction with participant p: A=q(S1,…,Sn)∈GpA=q(S_1,…,S_n)∈ G_p is an n-ary goal of a volitional procedure q with interactive type T, X is a writer occurring nowhere in the configuration, the interactive variable of the asked goal, of type T′T where T is T′T or T′?T ?; where T is in reader mode, Gp′=Gp∖A∪q(S1,…,Sn,X?)G _p=G_p \A\∪\q(S_1,…,S_n,X?)\ and Hp′=Hp∪XH _p=H_p∪\X\, and where it is in writer mode, Gp′=Gp∖A∪q(S1,…,Sn,X)G _p=G_p \A\∪\q(S_1,…,S_n,X)\ and Hp′=Hp∪X?H _p=H_p∪\X?\; σp′=σpσ _p= _p, and the asked goal keeps the identifier of A. (2) Reduce p: a unary transaction with participant p: there exists a unit goal A∈GpA∈ G_p that is not an n-ary goal of a volitional procedure such that C∈MC∈ M is the first clause for which the reduction of A with C (Definition “Reduction” of (Shapiro, 2026d)) succeeds with result (B,σ^)(B, σ), a clause of a volitional procedure taken as its guarded clause (Definition E.3); Gp′=(Gp∖A∪B)σ^G _p=(G_p \A\∪ B) σ, σp′=σp∘σ^?σ _p= _p σ? and Hp′=HpH _p=H_p. (3) Answer p: a unary transaction with participant p: X∈HpX∈ H_p is a writer whose reader X?X? occurs in the configuration, t is a term of the type of X whose variables, all of them occurring nowhere in the configuration, are readers Y1?,…,Yk?Y_1?,…,Y_k? at positions the person writes and writers W1,…,WmW_1,…,W_m at positions the program writes, σp′=σp∪X?:=tσ _p= _p∪\X?:=t\, Hp′=Hp∖X∪Y1,…,Yk,W1?,…,Wm?H _p=H_p \X\∪\Y_1,…,Y_k,W_1?,…,W_m?\, each with the type of its position in t, and Gp′=GpG _p=G_p. (4) Present p: a unary transaction with participant p: X?:=T∈σp\X?:=T\∈ _p with X?∈HpX?∈ H_p, σp′=σp∖X?:=Tσ _p= _p \X?:=T\, Hp′=Hp∖X?∪VH _p=H_p \X?\∪ V, where V is the set of the variables of T, each with the type of its position in T, and Gp′=GpG _p=G_p. (5) Dismiss p: a unary transaction with participant p: X∈HpX∈ H_p is a writer whose reader X?X? occurs nowhere in the configuration; Hp′=Hp∖XH _p=H_p \X\, Gp′=GpG _p=G_p and σp′=σpσ _p= _p. (6) Communicate p to q: a transaction with participants p,q∈Pp,q∈ P, possibly p=qp=q: X?:=T∈σp\X?:=T\∈ _p, X?X? occurs in GqG_q, σp′=σp∖X?:=Tσ _p= _p \X?:=T\, and Gq′=GqX?:=TG _q=G_q\X?:=T\; held variables unchanged. (7) Cold-call p to q: a binary transaction with participants p≠q∈Pp≠ q∈ P: the network output stream in (Gp,σp)(G_p, _p) has a new message msg(q,X)(q,X), (Gp′,σp′)(G _p,σ _p) is the result of advancing the network output stream, and (Gq′,σq′)(G _q,σ _q) is the result of adding msg(q,X)(q,X) to the network input stream; held variables unchanged. (8) ∼ is the partial equivalence whose domain is the Ask, Reduce, Present, Communicate, and Cold-call transactions, relating t1∼t2t_1 t_2 iff both are Ask transactions at the same agent p asking the same goal (by identity, Definition “Goal Identity” of (Shapiro, 2026d)), both are Reduce transactions at the same agent p reducing the same goal with the same clause, both are Present transactions at the same agent p presenting the same assignment, both are Communicate transactions from the same p to the same q applying the counterpart of the same writer assignment to the same goal, or both are Cold-call transactions from the same p to the same q delivering the same message. Definition E.5 (Proper Run (Shapiro, 2025b; Shapiro, 2026d)). A vmaGLP run is proper if, at each agent p, a variable that occurs in GpG_p after a transition but not before it also does not occur in GpG_p or in HpH_p at any earlier configuration. Definition E.6 (GLP, maGLP, cGLP (Shapiro, 2026d)). A GLP program is a vGLP program with no volitional procedures. Given agents P⊂ΠP⊂ and a GLP program M, the maGLP transition system over P and M is the vmaGLP transition system over P and M (Definition E.4), identifying (∅,(Gp,σp))( ,(G_p, _p)) with (Gp,σp)(G_p, _p); cGLP is its singleton case. Definition E.7 (Question, Open, Closed, Volition (Shapiro, 2026d)). In a configuration of the vmaGLP transition system, a writer X∈HpX∈ H_p is a question of p’s person: an interactive variable the person writes, introduced by an Ask, a writer presented inside the program’s output, or a variable that an Answer leaves open by answering in part; it is open if its reader X?X? occurs in the configuration, and closed otherwise. A volition of p’s person is an Answer transition of p: the person’s answer to one question. Theorem E.8 (Volitional Soundness (Shapiro, 2026d)). Let c1→c2→⋯c^1→ c^2→·s be a proper safe run of the vmaGLP transition system over P and M, p∈Pp∈ P, and X a question of p’s person in cic^i. Then the writer X occurs in cic^i among the questions of p’s person and nowhere else, and a transition ci→ci+1c^i→ c^i+1 that adds an assignment X?:=tX?:=t to a readers substitution is the Answer of p to X. The proof is in (Shapiro, 2026d). Definition E.9 (Person Channel, Person Writer, GLP with Persons, Grant (Shapiro, 2026d)). Let N be a GLP program and P⊂ΠP⊂ . A person channel of a goal G0G_0 satisfying SO is a variable pair (U,U?)(U,U?) such that U?U? occurs in G0G_0 and U does not; U is its person writer. GLP with persons over P and N, with a designated person channel of each agent’s initial resolvent, is the transition system obtained from the maGLP transition system over P and N (Definition E.6) by adding, at each agent p, grant transitions (Gp,σp)→(Gp,σp∘U?:=[c|U1?])(G_p, _p)\;→\;(G_p,\; _p \U?:=[c\,|\,U_1?]\) where c is a ground term, U the person writer of p, and U1U_1 a fresh variable, the person writer after the transition, every other agent stationary; the partial equivalence is the maGLP transaction equivalence, with grant transitions outside its domain. Definition E.10 (Canonical Compilation (Shapiro, 2026d)). The canonical compilation ⌈M⌉ M of a vGLP program M is the GLP program defined as follows. A procedure of M reaches a question if it is volitional or a clause of it calls a procedure that does; each such procedure has one more argument, last, its ask stream, which its goal writes and the dispatcher reads. In a clause of such a procedure, each call in the body of a procedure that reaches a question is given a fresh writer as its ask stream, and the head carries D?D?, where D is the clause’s ask stream, with the body’s ask streams merged into D: the call is given D itself where there is one such call, merge goals merge them where there are more, and the head carries [] in place of D?D? where there is none. Then ⌈M⌉ M consists of: every ordinary clause of M, so extended; for each volitional procedure q of M with interactive type T, its clauses as guarded clauses of arity n+1n+1 under a fresh name, q1 below, extended, and the asking clause, under the name q so that every call of q reaches it unchanged,q(S1, ..., Sn, [ask(T, t(X))|D?]) :- q1(S1’, ..., Sn’, X?, D). where Sl′S _l passes the argument on — at an input position the head carries SlS_l and Sl′S _l is its reader Sl?S_l?, and at an output position the head carries Sl?S_l? and Sl′S _l is the writer SlS_l — X and X? are exchanged where T is in writer mode, and t is the name of T in lowercase, its type arguments appended, with _w for writer mode and _r for reader mode — card_w, stream_request_r — so that the asks of M are of one type, the union over those functors; for each interactive type T of M, the construct process of T, which the dispatcher spawns on an ask with its variable and its channels to the dispatcher, and which acts as above; and the dispatcher, which reads the ask stream of the initial goal and the person channel, spawns a construct process with a fresh identifier on each ask, and routes the person’s grants to the construct processes by identifier, by the standard stream techniques, used without comment. The initial goal of ⌈M⌉ M at each agent is that of M, extended and with its calls of volitional procedures replaced likewise, and the dispatcher on the ask stream of that goal and on the person channel, which is its person side. The compilation is typed: ⌈M⌉ M carries the type definitions and procedure declarations of M, each procedure that reaches a question declared with its ask stream added, a volitional procedure’s declaration being its asking clause’s and its guarded clauses declared under their fresh name with the argument of its interactive type added in the mode of that type, the type of the asks, and the declarations of the construct processes and the dispatcher. Definition E.11 (Compilation Mapping (Shapiro, 2026d)). Given a configuration of GLP with persons over P and ⌈M⌉ M , the mapping σ yields the vmaGLP configuration over P and M with, at each agent: • G = the multiset of the agent’s goals, each read back to its source with its ask stream dropped: q(S1,…,Sn,D)q(S_1,…,S_n,D) as the n-ary goal q(S1,…,Sn)q(S_1,…,S_n), q1(S1,…,Sn,X?,D)q_1(S_1,…,S_n,X?,D) and q1(S1,…,Sn,X,D)q_1(S_1,…,S_n,X,D) as the asked goal, and any other compiled goal as itself; the construct processes, the dispatcher and the merge goals the compilation adds contributing nothing; • H = the variables held for the person, by the construct processes and by the asks the dispatcher has not yet taken, each with its type: the writers of the positions the person writes and the readers of the positions the program writes; • σr _r = the restriction of the accumulated readers substitution to the readers that occur in the source goals or are held for the person. Lemma E.12 (Compilation, per Transition (Shapiro, 2026d)). Let σ be the mapping of Definition E.11 and c→c′c→ c a transition of GLP with persons over P and ⌈M⌉ M at agent p. A grant, a reduction of the dispatcher or of a merge goal the compilation adds, a reduction of a construct process that binds nothing, and a Communicate on the person channel, on an ask stream, or between the dispatcher and the construct processes are stutters. A construct process binding a question whose reader occurs nowhere maps to the Dismiss of it by p. A reduction of the asking clause of q maps to the Ask of the source goal. A construct process binding an open question X with a term t of the type of X whose variables are new, readers of writers it holds at positions the person writes and writers whose readers it holds at positions the program writes, maps to the Answer of p to X with t. A reduction of a compiled clause of M maps to the Reduce of the source goal with the source clause. A Communicate of an assignment to a reader held for the person maps to the Present of it, any other Communicate within the agent to the source Communicate of the same assignment, and a Cold-call to the source Cold-call. The lemma is the safety case of the proof of the Compilation theorem of (Shapiro, 2026d), stated transition by transition.