July 10, 2026
The most prevalent distributed systems today include people and their personal machines (smartphones). In such systems, computations are driven by people’s volitions: a payment when a person wishes to pay someone, befriending when two people wish to become friends, etc. Volition-Guarded Multiagent Atomic Transactions were proposed as an abstract specification language for such systems, in which each agent consists of a person and their machine, and a transaction can be guarded by both the machine states and the personal volitions of its participating agents. Previous work presented volition-guarded specifications for the grassroots social graph, social network, and currencies, as well as their implementations via Communicating Volitional Agents. To facilitate the use of AI to derive smartphone-based grassroots platforms from such abstract specifications, Grassroots Logic Programs (GLP), a high-level, typed, multiagent, concurrent programming language, was designed and implemented. So far, AI derived GLP implementations of these platforms from (volition-free) multiagent atomic transactions, with UI design and development being an ad-hoc, “manual” process.
Here, we define the programming language volition-guarded GLP (vGLP), which extends GLP with volition-guarded clauses, and define its operational semantics as an instance of Communicating Volitional Agents. As the semantics requires the person to will a volition-guarded clause reduction, a correct implementation must elicit the person’s volitions: finding out “what’s in the person’s head” is the sole rationale for the UI, which is realised accordingly by standard constructs.
We demonstrate the approach on the grassroots social graph, social network, and currencies: each platform is a vGLP program, generated by AI from volition-guarded multiagent atomic transactions; the implementation of vGLP, also created by AI, then maps its volition-guarded clauses into the user-interface constructs, resulting in a single working app deployed on a physical smartphone.
Volition-guarded multiagent atomic transactions. The most prevalent distributed systems today include people and their personal machines (smartphones). In such systems, computations are driven by people’s volitions: a payment when a person wishes to pay someone, befriending when two people wish to become friends, etc. Volition-Guarded Multiagent Atomic Transactions [1] were proposed as an abstract specification language for such systems. In them (i) each agent consists of a person and their machine; (ii) a multiagent atomic transaction can be guarded by both the machine states and the personal volitions of its participating agents. For example, the befriending of two people is guarded by both persons and unfriending by either; a payment is guarded by the payer, a swap by both parties. An illustrative example is child-safe online befriending [2]: it is guarded by the volitions of the two children and one parent of each, and by the machines not recording the two children as friends and recording the two parents as friends.
Previous work [1] presented volition-guarded specifications for the grassroots social graph, grassroots social network [3], and grassroots currencies [4], [5], as well as their implementations via Communicating Volitional Agents, an implementation-ready restriction of the general model in which the only non-unary transactions are the binary discovery of one agent by another and the volition-free binary transfer of a message from the sender to its recipient. Volition-guarded transactions thus condition machine transitions on persons’ volitions. Formally, such a transition can occur only if the will for it is part of the volitional state of the person, namely is in the person’s head. Given today’s technologies, the only way for a machine to know what’s in a person’s head is for the person to express it; this is the fundamental reason for a UI. The goal of this paper is to rationalise the design of a UI that can elicit volitions from the person’s head, when needed.
Existing programming languages treat the person as a source of input — a stream of clicks [6]–[9], an event [10]–[13], the environment [14]–[16] — so input drives computation, but no step of any semantics awaits a person’s will (Section 8).
Communicating Volitional Agents. Implementing a multiagent atomic transactions-based specification must go through unary transactions, carried out by each agent. In the case of such volition-guarded transactions, the corresponding implementation-ready model is called Communicating Volitional Agents (CVA) [1]. Mathematically, CVA is but a restriction of the general model: It has unary volition-guarded transactions, in which a machine carries out a transaction — offering friendship or accepting a friendship offer, sending a payment — when, and only when, its person is willing. Unary transactions may also be unguarded, for example accepting a received valid payment. The machine state of an agent includes an inbox and an outbox, and an agent placing in its outbox a message addressed to another agent is a unary transaction. A message in the outbox of the sender is transferred to the inbox of the addressee by a binary atomic transaction unguarded by volitions. The other CVA binary transaction is discovery, by which one agent gets to know of another. When realising CVA on a smartphone, the basic requirement from the smartphone UI is one: to elicit, from the person operating the smartphone, the volitions the transactions require.
Grassroots platforms. Abstractly, a distributed system is grassroots [17]–[19] if it can have multiple instances that (1) can operate independently of each other and of any global resource other than the net, and (2) may interoperate and coalesce into ever-larger instances. Practically, a grassroots platform is a smartphone app with these two properties (while making some concessions in order to communicate through NATs and firewalls). Grassroots platforms are envisioned as an egalitarian/democratic alternative to the dominant centralised/autocratic (Facebook) and decentralised/plutocratic (Bitcoin) global platforms [20], [21].
Example: Volition-guarded atomic child-safe befriending [2]. Child-safe befriending extends the grassroots social graph [3], the foundational grassroots platform on which all other grassroots platforms are built. The machine state of each agent \(a\) is a set of friends \(c_a\subseteq \Pi\); \(c'_a\) is the machine state of \(a\) after the transaction is carried out; \(r\), \(s\) are children with respective parents \(p\), \(q\), where \(r,s,p,q\) are four distinct agents with the stated precondition.
Child befriend: \(c'_r := c_r \cup \{s\}\), \(c'_s := c_s \cup \{r\}\), provided \(q \in c_p\) and \(s \notin c_r\). Guarded by \(\{r, s, p, q\}\).
Child unfriend: \(c'_r := c_r \setminus \{s\}\), \(c'_s := c_s \setminus \{r\}\), provided \(s \in c_r\). Guarded by any one of \(\{r, s, p, q\}\).
The preconditions \(q\in c_p\) and \(s\notin c_r\) state that the parents are friends and the children are not. Child befriending requires all four—both children and both parents—to be willing; child unfriending can be initiated by any one of the four.
Grassroots Logic Programs (GLP) and AI. For AI to derive smartphone-based grassroots platforms from such abstract specifications, Grassroots Logic Programs (GLP) [22]–[24], a high-level, typed, multiagent, concurrent programming language, was designed and implemented by AI in Dart/Flutter, which is deployable on most smartphones (iPhone/Android). So far, AI derived GLP implementations of these platforms from (volition-free) multiagent atomic transactions [18]. However, specifying the role of people in such platforms is out-of-reach for this formalism, and hence the key step of designing and implementing the app’s UI was an ad hoc, “manual” process.
To rectify that, we need formal foundations for the implementation of unary volition-guarded transactions, not only for attaining mathematical elegance and completeness, but, more pragmatically, for AI to methodically develop the volition-eliciting UI for abstractly-specified grassroots platforms. Moreover, we wish for a single smartphone app, running the GLP engine, to support multiple, dynamically-loaded grassroots platforms written in GLP, and for that we cannot have an ad-hoc UI for each new platform.
Volition-guarded GLP. In this paper, we aim to achieve all that: We define the programming language volition-guarded GLP (vGLP), which extends GLP with volition-guarded clauses. A volition guard has the form *(\(X_1{=}T_1,\ldots,X_i{=}T_i,\,Y_1?,\ldots,Y_j?\)), declaring the question \(X_1,\ldots,X_i\), with \(T_1,\ldots,T_i\) constraining the
answers for which this clause is applicable, and the context \(Y_1?,\ldots,Y_j?\), the values of which define the context in which the question is asked.
Three clauses of the deployed coins-among-friends agent (Section 6) preview the language. The first, tail-recursive, lets the person mint their own coins at any time, the person supplying K; the second
and third are the accept and decline clauses of a responder goal, spawned per arriving friend offer, by which the person answers it:
*(K)
agent(Id, UserIn, NetIn, Outs, Holdings) :-
ground(Id?), integer(K?) |
add_coin(Id?, K?, Holdings?, Holdings1),
after_change(Id?, Holdings1?, UserIn?, NetIn?, Outs?).
*(Answer=yes, From?)
respond_coldcall(offer(From), Resp?,
[decision(Answer?, From?, response(Resp))]) :-
ground(From?) | true.
*(Answer=no, From?)
respond_coldcall(offer(From), Resp?,
[decision(Answer?, From?, response(Resp))]) :-
ground(From?) | true.
The first clause is reducible whenever the person wills a mint, the willed volition supplying K — a question expecting any answer; fulfilled by the reduction, it re-arises with the tail-recursive call, so the interface renders it as a
persistent compose form. The accept and decline clauses are reducible only while the offer awaits its answer, each by its own answer, yes or no, binding Answer, the context reader From? identifying the
offer — rendered as one inbox card, its buttons those two answers.
Volition-guarded GLP as an instance of Communicating Volitional Agents. We then define the operational semantics of vGLP as an instance of CVA: each agent pairs the person’s volitional state with the machine’s resolvent; a volition-guarded clause is reducible only if the person wills the reduction; the willed volition is fulfilled once the reduction is taken; and the person’s change-volition transitions are their own, carrying no liveness obligation. We prove that on programs with no volition-guarded clauses the semantics coincides with GLP’s (conservativity), and that every volition-guarded reduction fulfils a volition its person expressed (volitional soundness).
Since a volition-guarded reduction requires the person’s will, a correct implementation must elicit the person’s volitions; this is the reason for the UI. We derive the UI from the semantics: a pending reduction determines the question posed, the answers awaited, and the sibling clauses among which the person chooses. The manifest of a program assigns each volition-guarded clause a user-interface construct: its content the context, its fields the question, its buttons the siblings. We prove that the constructs offer exactly the pending volitions (elicitation completeness). A clause posing the empty question yields a compose form, persistent when tail-recursive; a clause posing an arrived offer yields an inbox card, answered by its buttons. The implementation compiles vGLP onto GLP: the vGLP agent is compiled into a GLP agent and a mediator that escrows the pending reductions, and the UI constructs perform the person’s grants. We prove that the compilation correctly implements vcGLP. We also prove that every CVA platform (Section 2.5) can be realised by a vGLP program.
We demonstrate the approach on the grassroots social graph, grassroots social network, and grassroots currencies: each platform is a vGLP program, generated by AI from volition-guarded multiagent atomic transactions. The implementation of vGLP, also created by AI, then maps its volition-guarded clauses into the user-interface constructs, resulting in a single working app deployed on a physical smartphone (Section 7).
Paper outline. Section 2 recalls volition-guarded multiagent atomic transactions, transition systems, implementations, grassroots protocols, and CVA. Section 3 recalls GLP and its multiagent operational semantics maGLP. Section 4 defines vGLP and its operational semantics vmaGLP, with conservativity, volitional soundness, liveness of simple programs, and realisation. Section 5 derives the interaction primitives, proves elicitation completeness, defines the manifest and the compilation of vGLP onto GLP, and proves that the compilation correctly implements vcGLP. Section 6 presents the three platforms as volition-guarded transactions, communicating volitional agents, and vGLP programs, with the before and after of each compilation. Section 7 demonstrates the approach. Section 8 reviews related work, and Section 9 concludes.
This section recalls the mathematical foundations on which the paper is based [1], [25]. Each agent consists of a person and a machine (e.g., smartphone) operated by the person. A machine transaction specifies what machines do; a volition guard specifies which persons must be willing for the transaction to occur.
We assume a potentially infinite set of agents \(\Pi\), but consider only finite subsets of it, so we assume any particular set of agents \(P \subset \Pi\) to be nonempty and finite. We use \(\subset\) to denote the strict subset relation and \(\subseteq\) when equality is also possible. As standard, we use \(S^P\) to denote the set of all total functions from \(P\) to \(S\), and if \(c\in S^P\) we use \(c_p\) to denote the value of \(c\) at \(p\in P\).
Definition 1 (Machine State, Configuration, Transaction, Volition-Guarded Multiagent Atomic Transaction). Given an arbitrary set \(S\) of machine states, with a designated initial state* \(s_0 \in S\), and agents \(Q \subset \Pi\), a machine configuration over \(Q\) is a member of \(S^Q\), and a machine transaction over participants \(Q\) is a pair \(c\rightarrow c' \in (S^Q)^2\) such that \(c\ne c'\). Given such a machine transaction \(t\), a volition-guarded multiagent atomic transaction over \(t\) — henceforth, volition-guarded transaction — is a pair \((t,Q')\) where \(Q'\subseteq Q\) are its guards.*
Machine transactions are atomic and asynchronous [25]—they can be carried out by their participants at any time, regardless of the states of non-participants. Participants include both active agents (whose state changes) and stationary agents (whose state is a precondition but does not change). Volition-guarded transactions are machine transactions that can be carried out only if their guards \(Q'\subseteq Q\) are willing. When we say a transaction is “guarded by \(\{p,q\}\),” both must be willing; when we say it is “guarded by either \(p\) or \(q\),” we mean there are two volition-guarded transactions over the same machine transaction, \((t,\{p\})\) and \((t,\{q\})\), so that either person’s volition suffices. Distinct machine transactions can represent “the same action” in different configurations, captured by an equivalence relation on machine transactions.
Definition 2 (Transaction Equivalence). Given a set of machine transactions \(R\), a transaction equivalence* is an equivalence relation \(\sim\) on \(R\) such that \(t \sim t'\) implies \(t\) and \(t'\) have the same participants. We write \([t]\) for the equivalence class of \(t\) under \(\sim\).*
A person’s volitional state is a set of equivalence classes of machine transactions they are willing their machine to participate in.
Definition 3 (Agent State and Configuration). Given agents \(P\), states \(S\) with initial state \(s_0\), a set of machine transactions \(T\) each over its own participants \(Q\subseteq P\) and \(S\), and equivalence \(\sim\) on \(T\), an agent state* is a pair \((V,m)\in \mathcal{A}= (2^{T/\sim} \times S)\) where \(V\) is its volitional state and \(m \in S\) its machine state. The initial agent state is \((\emptyset,s_0)\). An agent configuration \(c\) over \(P\), \(S\), \(T\), and \(\sim\) is a member \(c\in \mathcal{A}^P\) in which \(c^v_p \subseteq (T/{\sim})_p\) for every \(p\in P\), where \((T/{\sim})_p\) denotes the classes in \(T/{\sim}\) in which \(p\) is a participant; we write \(c^v_p\) for the volitional state and \(c^m_p\) for the machine state of agent \(p\) in \(c\).*
Definition 4 (Enabled). A volition-guarded transaction \((t,Q')\) with \(t=d\rightarrow d'\) over participants \(Q\) is enabled* in an agent configuration \(c\) if \(c^m_p=d_p\) for every participant \(p\in Q\) and \([t]\in c^v_q\) for every guard \(q\in Q'\). An equivalence class is enabled when some representative is.*
A volition-guarded transaction with an empty guard (\(Q' = \emptyset\)) — an unguarded transaction — requires no volitions and is enabled whenever its machine precondition is met.
Definition 5 (Volitional Multiagent Atomic Transaction). Given agents \(P\), states \(S\), machine transactions \(T\) over \(P\) and \(S\), and equivalence \(\sim\) on \(T\):
A change-volition transaction of agent \(p\in P\)* is a pair \(c\rightarrow c'\) of agent configurations over \(\{p\}\), \(S\), \(T\), and \(\sim\) such that \(c^v_p \ne c'{^v_p}\) and \(c^m_p = c'{^m_p}\).*
A volitional machine transaction* induced by a volition-guarded machine transaction \((t,Q')\), for some \(t= (d\rightarrow d')\in T\) over \(Q\subseteq P\) and \(Q'\subseteq Q\), is a pair \(c\rightarrow c'\) where \(c\ne c'\) are agent configurations over \(P\), \(S\), \(T\), and \(\sim\) such that \((t,Q')\) is enabled in \(c\) (Definition 4); \(c'{^m_p} = d'_p\) for every \(p\in Q\); \(c^m_p = c'{^m_p}\) for every \(p\in P\setminus Q\); and \(c'{^v_p} = c^v_p \setminus \{[t]\}\) for every \(p\in P\).*
A volitional multiagent atomic transaction* is a change-volition transaction or a volitional machine transaction.*
When a volitional machine transaction induced by \((t,Q')\) is taken, the class \([t]\) is removed from every agent’s volitional state: the will is fulfilled by any equivalent transaction. A person may independently change their volitional state via change-volition transactions, which may add or remove classes; beyond these, the framework removes a class from \(c^v_p\) only upon fulfilment.
Definition 6 (Transition System, Computation, Run, Safe, Live, Correct [1], [25]). A transition system* is a tuple \(TS = (C, c_0, T, {\sim})\) where \(C\) is an arbitrary set of configurations, \(c_0 \in C\) a designated initial configuration, \(T \subseteq C \times C\) a set of transitions, each a pair \(c \rightarrow c'\) of non-identical configurations \(c \ne c' \in C\), and \({\sim}\) a partial equivalence relation on \(T\) — an equivalence on a subset \(\mathit{dom}({\sim}) \subseteq T\); we write \([t]\) for the class of \(t \in \mathit{dom}({\sim})\) under \({\sim}\).*
A computation* is a (nonempty, finite or infinite) sequence of configurations \(c_1, c_2, \ldots\); it is a run if \(c_1 = c_0\), and safe if \(c_i \rightarrow c_{i+1} \in T\) for every two consecutive configurations. We write \(c \xrightarrow{*} c'\) for the existence of a safe computation from \(c\) to \(c'\) (empty if \(c = c'\)). A class \([t]\) is enabled in \(c\) if \(c \rightarrow c' \in [t]\) for some \(c'\). A run is live if no class \([t]\), \(t \in \mathit{dom}({\sim})\), is enabled in every configuration of some suffix in which no member of \([t]\) occurs, and correct if it is safe and live.*
A partial equivalence, rather than a total one, is used so that some transitions may carry no liveness requirement: only transitions in the domain of \({\sim}\) form classes and thereby incur a liveness obligation, while transitions outside the domain — belonging to no class — may occur in a correct run but are never required to.
Definition 7 (Multiagent Transition System [25]). Given agents \(P \subset \Pi\) and an arbitrary set \(S\) of local states* with a designated initial local state \(s_0\in S\), a multiagent transition system over \(P\) and \(S\) is a transition system \(TS= (C,c_0,T,{\sim})\) with configurations \(C:= S^P\), initial configuration \(c_0:= \{s_0\}^P\), transitions \(T\subseteq C^2\) a set of transactions over \(P\) and \(S\), and \({\sim}\) a partial equivalence on \(T\).*
Rather than specifying a multiagent transition system directly, we specify it via transactions, each over its own participants; the closure operator induces from them transitions over a fixed \(P\), in which non-participants are stationary.
Definition 8 (Transaction Closure [1]). Let \(P\subset \Pi\), \(S\) a set of local states, and \(C:=S^P\). For any transition or transaction \(t = c\rightarrow c'\), we write \(t_q := c_q\rightarrow c'_q\) and say \(p\) is stationary* in \(t\) if \(c_p = c'_p\). For a transaction \(t=(c\rightarrow c')\) over \(S\) with participants \(Q\), the \(P\)-closure of \(t\), \(t{\uparrow}P\), is the set of transitions over \(P\) and \(S\) defined by: \[t{\uparrow}P := \begin{cases} \{ t' \in C^2 : \forall q\in Q.(t_q = t'_q) \wedge \forall p\in P\setminus Q.(p\text{ is stationary in }t')\} & \text{if } Q\subseteq P \\ \emptyset & \text{otherwise} \end{cases}\] If \(R\) is a set of transactions, each \(t\in R\) over some \(Q\) and \(S\), then the \(P\)-closure of \(R\) is \(R{\uparrow}P := \bigcup_{t\in R} t{\uparrow}P\). Given a relation \({\sim}\) on \(R\), its \(P\)-closure \({\sim}{\uparrow}P\) is the relation on \(R{\uparrow}P\) with \(\hat{t} \mathrel{({\sim}{\uparrow}P)} \hat{t}'\) iff \(\hat{t} \in t{\uparrow}P\) and \(\hat{t}' \in t'{\uparrow}P\) for some \(t \sim t'\).*
If distinct transactions in \(R\) have disjoint \(P\)-closures — as when every participant of every transaction in \(R\) changes state — then each transition in \(R{\uparrow}P\) has a unique inducing transaction, \({\sim}{\uparrow}P\) relates two transitions exactly when their inducing transactions are related, and \({\sim}{\uparrow}P\) is a partial equivalence whenever \({\sim}\) is.
Definition 9 (Transactions-Based Multiagent Transition System, adapted from [1], [25]). Given agents \(P \subset \Pi\), local states \(S\) with initial local state \(s_0\in S\), a set of transactions \(R\), each \(t\in R\) over some \(Q\subseteq P\) and \(S\), in which distinct transactions have disjoint \(P\)-closures, and a partial equivalence \({\sim}\) on \(R\), the transactions-based multiagent transition system* over \(P\), \(S\), \(R\), and \({\sim}\) is the multiagent transition system \(TS= (S^P,\{s_0\}^P,R{\uparrow}P,{\sim}{\uparrow}P)\).*
A set of volition-guarded transactions with an equivalence on their underlying machine transactions likewise induces a multiagent transition system, over agent states:
Definition 10 (Volitional Multiagent Transition System [1]). Given agents \(P\subset \Pi\), machine states \(S\) with initial state \(s_0\), a set \(R\) of volition-guarded transactions such that every \((t,Q')\in R\) has the participants of \(t\) contained in \(P\) and distinct underlying machine transactions have disjoint \(P\)-closures, and an equivalence \(\sim\) on the set \(T_R := \{t : (t,Q')\in R\text{ for some }Q'\}\) of underlying machine transactions, the volitional multiagent transition system induced by \((S,R,{\sim})\) over \(P\)* is the multiagent transition system \((\mathcal{A}^P,c_0,T_V,{\sim_V})\) where:*
\(\mathcal{A}:= 2^{T_R/\sim} \times S\) is the agent state space;
\(c_0 \in \mathcal{A}^P\) is the initial agent configuration, with \(c_0{^v_p}=\emptyset\) and \(c_0{^m_p}=s_0\) for every \(p\in P\);
\(T_V\) consists of the \(P\)-closures of the change-volition transactions of each agent \(p\in P\), together with the volitional machine transactions over \(P\) induced by the members of \(R\) (Definition 5);
\(\sim_V\) is the restriction of \({\sim}{\uparrow}P\) (Definition 8) to the volitional machine transactions, relating two of them whenever their inducing machine transactions are \(\sim\)-equivalent; every change-volition transition lies outside its domain and belongs to no class.
A class of volitional machine transactions is enabled at a configuration in the sense of Definition 6 exactly when some volition-guarded transaction inducing it is enabled in the sense of Definition 4; this determines which runs are live and correct. Unguarded transactions carry the liveness obligation with no volitional prerequisite: once the machine precondition holds, some class representative must eventually be taken. Change-volition transitions impose no liveness obligation; personal choices remain free.
A protocol is a family of multiagent transition systems, one for each finite \(P \subset \Pi\), over a common local-states function assigning to each \(P\) a set of local states containing the initial state [1], [17]. A set of volition-guarded transactions with a transaction equivalence over a local-states function thus defines a protocol: it assigns to each \(P\) the volitional multiagent transition system it induces over \(P\).
An implementation relates a specification transition system to one that implements it, via a mapping of configurations.
Definition 11 (Implementation [23], [25]). Given two transition systems \(TS = (C, c_0, T, {\sim})\) (the specification) and \(TS' = (C', c'_0, T', {\sim'})\), an implementation of \(TS\) by \(TS'\)* is a function \(\sigma : C' \rightarrow C\) where \(\sigma(c'_0) = c_0\), in which case the pair \((TS', \sigma)\) is referred to as an implementation of \(TS\).*
Given a computation \(r' = c'_1 \rightarrow c'_2 \rightarrow \ldots\) of \(TS'\), \(\sigma(r')\) is the (possibly empty) computation \(\sigma(c'_1) \rightarrow \sigma(c'_2) \rightarrow \ldots\) obtained from the sequence by removing consecutively repetitive elements so that \(\sigma(r')\) has no stutter transitions* of the form \(c \rightarrow c\).*
Definition 12 (Correct and Complete Implementation [23], [25]). The implementation \((TS', \sigma)\) of \(TS\) is correct* if \(\sigma\) maps every correct run of \(TS'\) to a correct run of \(TS\), and complete if every correct run \(r\) of \(TS\) is \(\sigma(r')\) for some correct run \(r'\) of \(TS'\).*
We are particularly interested in grassroots protocols [1], [17], [18], defined informally as follows. Runs of two disjoint sets can be interleaved into a run of their union. A protocol is oblivious if every interleaving of two correct runs of disjoint sets of agents is a correct run of the union, and interactive if some correct run of the union is not an interleaving of any two such independent runs, because it includes a step whose participants span both sets; it is grassroots if both [1], capturing formally the informal idea that grassroots platforms (specified by grassroots protocols) can have multiple instances that can form and operate independently, yet may coalesce into ever-larger instances, possibly (but not necessarily) into a single global platform.
The framework of Section 2 abstracts over how a volition-guarded multiagent atomic transaction is carried out: a \(k\)-ary transaction simultaneously updates the machine states of all its participants, with no notion of how participating machines come to act in concert. An implementation on networked smartphones has no such simultaneity: every exchange between two agents is a separate asynchronous message-passing event, and a \(k\)-ary transaction must be realised by a protocol composed of such events.
To achieve that we recall communicating volitional agents (CVA) [1], an implementation-ready restriction of volition-guarded transactions. CVA volition-guarded machine transactions are drawn from four syntactic forms only: binary discover transactions by which an agent comes to know of another; binary communicate transactions that copy a message from one agent’s outbox to another’s inbox; a unary advance-date transaction by which an agent advances its own local clock; and unary platform transactions. Thus, a CVA platform need only specify its platform transactions. Moreover a CVA protocol is grassroots by construction [1].
Local states. A CVA agent’s local state packages five components: a set of known peers with whom the agent can communicate, an outbox of messages awaiting delivery, an inbox of messages received, a platform state in which each platform specifies whatever data it requires (friend sets, groups, bonds, feeds, and so on), and a local date—a logical clock the agent advances on its own, giving a substrate notion of local time without reference to any global clock. A message is a triple of sender, recipient, and cargo; outboxes and inboxes are sets of messages. The cargo space \(C\) and the platform state space \(A\) are parameters of the CVA platform.
Definition 13 (CVA Local States and Configurations). Given a set \(C\) of cargoes* and a platform state space \(A\) with initial state \(a_0\in A\), the set of messages over \(P\subset \Pi\) is \[M(P) \;:=\; \{\mathsf{message}(s,r,c) \mid s\ne r\in P,\; c\in C\},\] with \(\mathsf{message}(s,r,c)\) a message of sender \(s\), recipient \(r\), and cargo \(c\). A CVA local state over \(P\) is a tuple \[(\mathit{known},\, o,\, i,\, a,\, t) \;\in\; S(P) \;:=\; 2^{P} \times 2^{M(P)} \times 2^{M(P)} \times A \times \mathbb{N},\] where \(\mathit{known}\subseteq P\) is a set of known peers, \(o\subseteq M(P)\) is an outbox, \(i\subseteq M(P)\) is an inbox, \(a\in A\) is a platform state, and \(t\in\mathbb{N}\) is a local date; the initial local state is \((\emptyset,\emptyset,\emptyset,a_0,0)\). A CVA configuration over \(P\) is a member \(c\in S(P)^P\); for \(p\in P\) we write \(c_p = (\mathit{known}_p,\, o_p,\, i_p,\, a_p,\, t_p)\) for the local state of \(p\) in \(c\). The initial configuration over \(P\), denoted \(c0(P)\), assigns the initial local state to every \(p\in P\).*
The local-states function \(S\) satisfies \(P\subseteq P' \implies S(P)\subseteq S(P')\), as required of a transactions-based protocol; the added \(\mathbb{N}\) factor is independent of \(P\) and does not affect this.
Volition-guarded transactions. A CVA protocol consists of three “built in” transactions—the binary discover and communicate and the unary advance-date—and platform-specific unary transactions, specified below:
Definition 14 (CVA Protocol). A CVA protocol* consists of every binary transaction \(c\rightarrow c'\) over \(\{p,q\}\) for every \(p\ne q\in \Pi\) such that \(c'=c\) except that:*
Discover: guarded by \(\{p\}\), \(\mathit{known}'_p := \mathit{known}_p \cup \{q\}\).
Communicate: unguarded, \(i'_q := i_q \cup M\), \(o'_p := o_p \setminus M\), provided \(M=\{\mathsf{message}(p,q,c)\} \subseteq o_p\).
together with, for each \(p\in \Pi\), the unary built-in transaction:
In addition it has for each \(p\in \Pi\) volition-guarded unary platform transactions:
Advance-date is unguarded and always enabled. The local date \(t_p\) is CVA’s only notion of time; timeouts and periodic behaviour are preconditions on it [1]. Being always enabled, Advance-date is excluded from quiescence [1], which would otherwise be unreachable. A platform transaction is reactive if it is unguarded and its precondition requires an arrived message: the machine carries it out on receipt. A reactive transaction reads the inbox but does not consume from it; its precondition is written to fail once the transaction has fired, so a retained message cannot enable it twice. Inboxes only grow; bounding them is left to the implementation.
Definition 15 (CVA Platform). A CVA platform* is a tuple \((C, A, a_0, T, {\sim})\): cargoes \(C\), a platform state space \(A\) with initial state \(a_0 \in A\), platform transactions \(T\), and a transaction equivalence \({\sim}\) on \(T\), extended to the built-in transactions by relating two Discover transactions with the same \(p\) and \(q\), two Communicate transactions with the same \(p\), \(q\), and message, and two Advance-date transactions of the same agent.*
Distinct CVA transactions have disjoint \(P\)-closures: Communicate changes the state of both its participants, every other form of one, and Discover, Advance-date, and the platform transactions change disjoint components of that state. A CVA platform thus induces over each \(P\subset\Pi\) the volitional multiagent transition system of its transactions (Definition 10), and thereby a protocol (Section 2); its correct runs are those of Definition 6, and the correctness statements of Sections 4 and 5 are over them.
This section recalls the GLP language and its multiagent operational semantics maGLP [22]; its single-agent case, concurrent GLP (cGLP), is the singleton instance. vGLP (Section 4) extends the language with volition-guarded clauses and maGLP with the volitional layer. While GLP need not be typed, it was augmented with a parameterised moded type system [24], which proved indispensable for AI-based programming.
GLP extends logic programs by adding a paired reader \(X?\) to every “ordinary” logic variable \(X\), now called a writer.
Definition 16 (GLP Variables [22]). Let \(\mathcal{V}\) denote the set of LP variables (identifiers beginning with uppercase), henceforth called writers. Define \(\mathcal{V}? = \{X? \mid X \in \mathcal{V}\}\), called readers. The set of all GLP variables is \(\hat{\mathcal{V}}= \mathcal{V}\cup \mathcal{V}?\). A writer \(X\) and its reader \(X?\) form a variable pair.
GLP terms, unit goals, goals, and clauses are as in LP but defined over the variables in \(\hat{\mathcal{V}}\).
Definition 17 (Single-Occurrence (SO) Invariant, GLP Program, Goal [22]). A term, goal, or clause satisfies the single-occurrence (SO) invariant if every variable occurs in it at most once. A clause \(C\) satisfies the single-reader/single-writer (SRSW) restriction* if it satisfies SO and a variable occurs in \(C\) iff its paired variable also occurs in \(C\). A GLP program is a finite sequence of clauses satisfying SRSW; clauses for the same predicate form a procedure. The set of GLP goals \(\hat{\mathcal{G}}(P)\) includes all goals over \(\hat{\mathcal{V}}\) and the vocabulary of \(P\) that satisfy SO.*
Example 1 (Fair Merge [22]). The quintessential concurrent logic program for fairly merging two streams, written in GLP:1
Stream(X) ::= [] ; [X|Stream(X)].
procedure merge(Stream(X)?, Stream(X)?, Stream(X)).
merge([X|Xs], Ys, [X?|Zs?]) :- merge(Ys?, Xs?, Zs).
merge(Xs, [Y|Ys], [Y?|Zs?]) :- merge(Xs?, Ys?, Zs).
merge([], Ys, Ys?).
merge(Xs, [], Xs?).
The goal merge([1,2,3|Xs?],[a,b|Ys?],Zs) satisfies SO; each clause satisfies SRSW. The first clause swaps inputs in the recursive call, ensuring fairness when both streams are available.
Definition 18 (Substitutions and Assignments [22]). A GLP writer assignment* is a term of the form \(X := T\), \(X\in\mathcal{V}\), \(T\notin\mathcal{V}\), satisfying SO. Similarly, a GLP reader assignment is a term of the form \(X? := T\), \(X?\in\mathcal{V}?\), \(T\notin\mathcal{V}\), satisfying SO. A writers (readers) substitution \(\sigma\) is the substitution implied by a set of writer (reader) assignments that jointly satisfy SO. Given a writers assignment \(X := T\), its readers counterpart is \(X? := T\), and given a writers substitution \(\sigma\), its readers counterpart \(\sigma?\) is the readers substitution defined by \(X?\sigma? = X\sigma\). Given a reader assignment \(X? := T\), its writers counterpart is \(X := T\), and given a readers substitution \(\tau\), its writers counterpart \(\tau!\) is the writers substitution defined by \(X\tau! = X?\tau\). The pair completion of a readers substitution \(\sigma\) is \(\sigma^\star = \sigma \cup \sigma!\), applied to a fixed point.*
Definition 19 (GLP Renaming, Renaming Apart, Writer MGU [22]). A GLP renaming* is an injective substitution \(\rho: \hat{\mathcal{V}}\to \hat{\mathcal{V}}\) such that for each \(X \in \mathcal{V}\): \(X\rho \in \mathcal{V}\) and \(X?\rho = (X\rho)?\). Two GLP terms have a variable in common if for some writer \(X \in \mathcal{V}\), either \(X\) or \(X?\) occurs in both. A GLP renaming \(\sigma\) renames \(T'\) apart from \(T\) if \(T'\sigma\) and \(T\) have no variable in common. Given two GLP unit goals \(A\) and \(H\), a writer mgu is a writers substitution \(\sigma\) such that \(A\sigma = H\sigma\) and \(\sigma\) is most general among such substitutions.*
Definition 20 (GLP Goal/Clause Reduction [22]). Given GLP unit goal \(A\) and clause
\(C\), with \(H\) :- \(B\) being the result of the GLP renaming of \(C\) apart from \(A\), the GLP reduction* of \(A\) with \(C\) succeeds with result \((B,\sigma)\) if \(A\) and \(H\) have a writer mgu.*
Definition 21 (Guarded Clause [22]). A guarded clause* has the form \(H\)
:- \(G\) | \(B\), where \(H\) is the head, \(G\) is a conjunction of guard predicates, and \(B\) is the body. The guard separator “|” is interpreted logically as a conjunction. Guard arguments are readers paired to head writers.*
Guards have three-valued semantics [22]. Each guard predicate explicitly defines its success condition. A guard suspends if it does not succeed but some instance of it under a readers substitution would succeed. A guard fails if no such instance exists. A guard conjunction succeeds if all members succeed; it suspends if any member suspends and none fail; it fails if any member fails. Definition 20 is augmented to succeed if the guard also succeeds. Guard occurrences count toward SRSW satisfaction, and a guard whose success implies that \(X?\) is ground licenses multiple occurrences of \(X\) and \(X?\) in the clause [22].
Each agent’s initial resolvent is the atomic goal agent(ch(_?,_),ch(_?,_)), providing two bidirectional channels: the first to the person operating the machine, the second to the network [22]. Anonymous variables make the initial local states syntactically identical yet semantically unshared; variable pairs whose writer and reader are held by different agents are the communication
channels, and Cold-call bootstraps shared variables between previously-disconnected agents through the network streams [22].
Definition 22 (Goal Identity [22]). Each unit goal in a computation carries a unique identifier* assigned at spawn time: goals in an initial goal receive distinct initial identifiers, and goals spawned by a Reduce transition receive fresh identifiers. Communicate transitions preserve identifiers: the goal containing \(X?\) retains its identity after instantiation.*
Definition 23 (Multiagent GLP [22]). Given a GLP program \(M\), an asynchronous resolvent* over \(M\) is a pair \((G, \sigma)\) where \(G \in \hat{\mathcal{G}}(M)\) and \(\sigma\) is a readers substitution. Given agents \(P\subset \Pi\), the maGLP transition system over \(P\) and \(M\) is the transactions-based multiagent transition system (Definition 9) over \(P\), local states being asynchronous resolvents \((G_p, \sigma_p)\) over \(M\), initial local state \((\{\verb|agent(ch(_?,_),ch(_?,_))|\}, \emptyset)\), the following transactions, and the equivalence \({\sim}\) below:*
Reduce \(p\): a unary transaction with participant \(p\): there exists a unit goal \(A \in G_p\) such that \(C \in M\) is the first clause for which the GLP reduction of \(A\) with \(C\) succeeds with result \((B, \hat{\sigma})\); \(G'_p = (G_p \setminus \{A\} \cup B)\hat{\sigma}\) and \(\sigma'_p = \sigma_p \circ \hat{\sigma}?\).
Communicate \(p\) to \(q\): a transaction with participants \(p,q \in P\), possibly \(p = q\): \(\{X? := T\} \in \sigma_p\), \(X?\) occurs in \(G_q\), \(\sigma'_p = \sigma_p \setminus \{X? := T\}\), and \(G'_q = G_q\{X? := T\}\).
Cold-call \(p\) to \(q\): a binary transaction with participants \(p\ne q \in P\): the network output stream in \((G_p, \sigma_p)\) has a new message msg\((q,X)\), \((G'_p, \sigma'_p)\) is the result of advancing the network output stream, and \((G'_q, \sigma'_q)\) is the result of adding msg\((q,X)\) to the network input stream.
\({\sim}\), the maGLP transaction equivalence, relates \(t_1 \sim t_2\) iff both are Reduce transactions at the same agent \(p\) reducing the same goal (by identity, Definition 22) with the same clause, 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.
Reduce differs from LP in the use of a writer mgu instead of a regular mgu, and in the choice of the first applicable clause instead of any clause; Communicate communicates an assignment from its writer to its paired reader — within one agent, or across the two agents holding the pair’s two sides; Cold-call transfers a term with its variables through the network streams, creating paired variables between previously-disconnected agents [22]. Distinct maGLP transactions have disjoint \(P\)-closures — every participant of each changes state — so \({\sim}{\uparrow}P\) is an equivalence (Definition 8). The transition equivalence is total, so every transition carries a liveness obligation; in vGLP (Section 4), the person’s Change-Volition transitions lie outside the domain of the equivalence. Implementation-wise, if a GLP goal \(A\) cannot be reduced now, but there is a readers substitution under which it can, the goal suspends on these readers and is rescheduled once any of them is assigned.
Definition 24 (Proper Run [22]). A maGLP run is proper* if, at each agent \(p\), a variable that occurs in \(G_p\) after a transition but not before it also does not occur in \(G_p\) at any earlier configuration.*
In any proper cGLP run, if unit goal \(A\) can reduce with clause \(C\) at step \(i\), then either an instance of \(A\) has been reduced by step \(j > i\), or an instance of \(A\) can still reduce with \(C\) at step \(j\).
Here we define volition-guarded GLP (vGLP). Syntactically, it extends GLP clauses with an optional volition guard. Semantically, it assumes volitional agents and thus we define its operational semantics as an instance of CVA.
Definition 25 (Volition-Guarded Clause, Volition Guard, Question, Answer, Context, Ordinary Clause, vGLP Program). A volition-guarded clause* is a GLP clause \(C\) preceded by a volition
guard of the form: \(\verb|*|(X_1{=}T_1,\ldots,X_i{=}T_i,\,Y_1?,\ldots,Y_j?),\;i,j \ge 0,\) where each \(X_l\) is a writer whose paired reader \(X_l?\)
occurs in \(C\) and each \(T_l\) is either a ground term or an anonymous variable, in which case \(X_l{=}\)_ can be abbreviated as \(X_l\), \(1\le l \le i\). Each \(Y_l?\) is a reader for which the guard ground(\(Y_l?\)) occurs in
\(C\), \(1\le l \le j\). The writers of the volition guard are referred to as \(C\)’s question, the readers as its context; a substitution
\(\theta\) over the writers for which \(X_l\theta\) is an instance of \(T_l\), \(1\le l \le i\), as an answer. The
ordinary clause corresponding to \(C\) is the result of removing the volition guard from \(C\), which is ordinary if its volition guard is empty to begin with. A vGLP
program is a sequence of volition-guarded clauses.*
Here are vGLP code fragments used in this paper:
*(Friend, Coin, Amt)
agent(Id, UserIn, NetIn, Outs, Holdings) :-
ground(Friend?), ground(Coin?), integer(Amt?) |
sub_coin(Coin?, Amt?, Holdings?, Status, Holdings1),
do_pay(Status?, Id?, Friend?, Coin?, Amt?, Holdings1?,
UserIn?, NetIn?, Outs?).
agent(Id, UserIn, [msg(Id1, intro(From, Resp?))|NetIn],
Outs, Holdings) :-
Id? =?= Id1? |
respond_coldcall(offer(From?), Resp, Ans),
merge(Ans?, UserIn?, UserIn1),
agent(Id?, UserIn1?, NetIn?, Outs?, Holdings?).
*(Answer=yes, From?)
respond_coldcall(offer(From), Resp?,
[decision(Answer?, From?, response(Resp))]) :-
ground(From?) | true.
Here we define vmaGLP, the operational semantics of vGLP, which both extends maGLP (Section 3), the multiagent operational semantics of GLP, and is an instance of CVA (Section 2.5).
Definition 26 (Volition). Given a vGLP program \(M\), a volition over \(M\) is a triple \((C, \theta, \theta')\): a volition-guarded clause \(C \in M\), an answer \(\theta\) for \(C\), and a ground substitution \(\theta'\) over the context of \(C\).
Definition 27 (Volition-Guarded Reduction, Fulfilled Volition). Given a unit goal \(A\), a volition-guarded clause \(C\), and an answer \(\theta\) for \(C\), the outcome of the volition-guarded reduction* of \(A\) with \(C\) under \(\theta\) is the outcome of the GLP reduction of \(A\) with \(C'\theta?\), where \(C'\) is the ordinary clause corresponding to \(C\) and \(\theta?\) the readers counterpart of \(\theta\). If the reduction succeeds with mgu \(\sigma\), its fulfilled volition is \((C, \theta, \theta')\), with \(\theta'\) being \(\sigma?\) restricted to the context of \(C\).*
Definition 28 (vmaGLP Transition System). Given agents \(P \subset \Pi\) and a vGLP program \(M\), the vmaGLP transition system over \(P\) and \(M\) extends the maGLP transition system over \(P\) and \(M\) (Definition 23) as follows:
local states are agent states* \((V_p, (G_p, \sigma_p))\): a volitional state \(V_p\), a finite set of volitions over \(M\), and an asynchronous resolvent \((G_p, \sigma_p)\) over \(M\); the initial local state is \((\emptyset, (\{\verb|agent(ch(_?,_),ch(_?,_))|\}, \emptyset))\);*
Reduce \(p\) is as in maGLP, where the reduction of \(A\) with a volition-guarded clause \(C\) succeeds if, for some answer \(\theta\), the volition-guarded reduction of \(A\) with \(C\) under \(\theta\) succeeds (Definition 27) with fulfilled volition \(v \in V_p\); \(V'_p = V_p \setminus \{v\}\) if the selected clause is volition-guarded, \(V'_p = V_p\) otherwise;
Communicate \(p\) to \(q\) and Cold-call \(p\) to \(q\) are as in maGLP; volitional states unchanged;
Change-Volition \(p\): a unary transaction with participant \(p\) in which \(V'_p \ne V_p\) is a finite set of volitions over \(M\) and \((G_p, \sigma_p)\) is unchanged;
\({\sim}\) is the partial equivalence whose domain is the Reduce, Communicate, and Cold-call transactions, on which it is the maGLP transaction equivalence.
Reduce alone reads the volitional state and, when the selected clause is volition-guarded, fulfils a volition. Definition 24 applies to vmaGLP runs verbatim, Change-Volition leaving the resolvent unchanged.
Change-Volition transactions are the person’s own: the program reads \(V_p\) only through volition-guarded reductions, and the person performs every change to it. Lying outside the domain of the equivalence, they carry
no liveness obligation: the machine cannot compel the person. A volition is fulfilled by the reduction it authorises and is retractable by Change-Volition until fulfilled, as in volitional multiagent atomic transactions (Section 2). The willed volition names its clause, so sibling volition-guarded clauses of the same goal — accept and decline — are the person’s choice: the unwilled sibling suspends, blocking a later otherwise, while
a later ordinary clause that succeeds may fire.
Definition 29 (vcGLP). Given a vGLP program \(M\), vcGLP\((M)\)* is the vmaGLP transition system over a singleton set of agents and \(M\).*
Cold-call requires two agents, so vcGLP has Reduce, Communicate, and Change-Volition only; it adds the volitional layer to the single-agent case of maGLP, and is the specification the compilation of Section 5 implements.
Definition 30 (Pending Volition, Pending). Given an agent state \((V_p, (G_p, \sigma_p))\), a unit goal \(A \in G_p\), and a volition-guarded clause \(C\), the pending volitions* of \(C\) on \(A\) are the fulfilled volitions of the volition-guarded reductions of \(A\) with \(C\) that are not in \(V_p\); \(C\) is pending on \(A\) if it has one, and a volition is pending at \(p\) if it is a pending volition of some clause on some unit goal in \(G_p\).*
A pending clause is a question the machine puts to its person: do you will this reduction? The person answers by a Change-Volition adding a pending volition — its \(\theta\) the person inputs they supply. How questions reach the screen and answers return is the interface’s task (Section 5).
Remark 1 (The Question Stands). By Monotonicity (Proposition [prop:glp-monotonicity]), in a proper run, once the volition-guarded reduction of \(A\) with \(C\) under \(\theta\) succeeds, it succeeds for every future instance of \(A\) until one is reduced, with the same fulfilled volition; and a goal reading the same values — the recursive agent goal — yields the same fulfilled volition. A volition therefore covers reductions of present and future goals alike, and a pending question, once posed, stands until answered or posed by no goal.
Let \(M\) be a vGLP program with no volition-guarded clauses and \(P \subset \Pi\). Identifying \((\emptyset, (G_p, \sigma_p))\) with \((G_p, \sigma_p)\), the vmaGLP transition system over \(P\) and \(M\) is the maGLP transition system over \(P\) and \(M\) (Definition 23).
Proof. A volition over \(M\) names a volition-guarded clause of \(M\) (Definition 26), so \(M\) has no volitions: every volitional state is \(\emptyset\) and Change-Volition, requiring \(V'_p \ne V_p\), has no instances. Every clause being ordinary, Reduce, Communicate, and Cold-call are those of maGLP with the volitional component \(\emptyset\) unchanged, and \({\sim}\) is the maGLP transaction equivalence on all of them. ◻
Definition 31 (Add, Remove, Fulfil). Let \(c^1 \rightarrow c^2 \rightarrow \cdots\) be a safe run of the vmaGLP transition system over \(P\) and \(M\), with \((V^i_p, (G^i_p, \sigma^i_p))\) the agent state of \(p \in P\) in \(c^i\), and let \(v\) be a volition over \(M\). The transition \(c^i \rightarrow c^{i+1}\) adds* \(v\) at \(p\) if \(v \in V^{i+1}_p \setminus V^i_p\), removes \(v\) at \(p\) if \(v \in V^i_p \setminus V^{i+1}_p\), and fulfils \(v\) at \(p\) if it is a Reduce at \(p\) with fulfilled volition \(v\) (Definition 28).*
theoremrestateVolitionalSoundness Let \(c^1 \rightarrow c^2 \rightarrow \cdots\) be a safe run of the vmaGLP transition system over \(P\) and \(M\), \(p \in P\), and \(v\) a volition over \(M\).
If \(c^i \rightarrow c^{i+1}\) fulfils \(v\) at \(p\), then for some \(j < i\), \(c^j \rightarrow c^{j+1}\) is a Change-Volition of \(p\) adding \(v\), and \(v \in V^k_p\) for every \(j < k \le i\).
If \(c^k \rightarrow c^{k+1}\) and \(c^{k'} \rightarrow c^{k'+1}\), \(k < k'\), both fulfil \(v\) at \(p\), then some \(c^j \rightarrow c^{j+1}\), \(k < j < k'\), is a Change-Volition of \(p\) adding \(v\).
The proof is in Appendix C of the supplementary material.
A willed reduction is not, in general, eventually taken: the first clause whose reduction succeeds is selected, so textually earlier clauses can preempt a willed clause indefinitely. In the following syntactic class, only preceding unit clauses and willed siblings can.
Definition 32 (Simple Procedure, Simple Program). A vGLP procedure is simple* if no two of its volition-guarded clauses have a common answer and every clause preceding a volition-guarded clause is a unit clause or volition-guarded. A vGLP program is simple if every procedure of it is.*
theoremrestateSimpleLiveness Let \(M\) be a simple vGLP program, \(c^1 \rightarrow c^2 \rightarrow \cdots\) a proper correct run of the vmaGLP transition system over \(P\) and \(M\), \(p \in P\), \(A\) a unit goal in \(G^i_p\), and \((C, \theta, \theta')\) a volition over \(M\). If, for every \(k \ge i\) at which an instance of \(A\) is in \(G^k_p\), \((C, \theta, \theta') \in V^k_p\), no volition of a clause preceding \(C\) is in \(V^k_p\), and the volition-guarded reduction of that instance with \(C\) under \(\theta\) succeeds with fulfilled volition \((C, \theta, \theta')\), then for some \(k \ge i\) the transition \(c^k \rightarrow c^{k+1}\) reduces an instance of \(A\), with \(C\) or with a unit clause preceding \(C\).
The proof is in Appendix C of the supplementary material.
A volition-guarded specification (Section 2) is decomposed by CVA (Section 2.5) into its built-in transactions — Discover, Communicate, Advance-date — and unary platform transactions, each guarded by \(\emptyset\) or by the acting agent’s person. Each maps to a clause of the agent’s vGLP program: a transaction with guard \(\emptyset\) to an ordinary clause; one with guard \(\{p\}\) to a volition-guarded clause — its parameters the person inputs; its context readers none when its precondition reads the local state, and the arrived message’s variables when it requires one; and Communicate to the transfer of a message from its sender to its recipient. The correctness statement uses the implementation framework of Section 2.
Definition 33 (Correct, Realised). An implementation \(\sigma\) (Definition 11) by the vmaGLP transition system over \(P\) and a vGLP program \(M\) is correct* if it maps every proper correct run onto a correct run. Given a CVA platform as the specification, a volition-guarded platform transaction \(t\) is realised by a volition-guarded clause \(C \in M\) if, for every proper correct run \(\rho\), the occurrences of \([t]\) in \(\sigma(\rho)\) are exactly the images of the volition-guarded reductions with \(C\).*
theoremrestateRealisation Every CVA platform has, for every \(P \subset \Pi\), a correct implementation by the vmaGLP transition system over \(P\) and a simple vGLP program, every volition-guarded platform transaction realised by a volition-guarded clause.
The construction — one simple procedure per platform transaction, so that Theorem [thm:simple-liveness] carries CVA’s liveness obligation — and the proof are in Appendix C of the supplementary material.
Formally, the person’s volitions are in \(V_p\), which the machine cannot read. Implementation therefore requires elicitation: offering the person the means to express volitions the machine needs to know in order to fulfil them. Here we describe how this can be done, methodically.
Definition 34 (Manifest). The manifest* of a vGLP program \(M\) assigns each volition-guarded clause \(C \in M\) its user-interface construct, presented per unit goal \(A\) on which \(C\) is pending:*
**content: the contexts of the pending volitions of \(C\) on \(A\);
**fields: the writers \(X_l\) of \(C\)’s volition guard with \(T_l\) anonymous (Definition 25);
**buttons: one per volition-guarded clause \(C'\) pending on \(A\), labelled by the ground \(T_l\) of its volition guard;
**tap* of the button of \(C'\): the Change-Volition adding the pending volition of \(C'\) on \(A\) whose answer maps each \(X_l\) of \(C'\) to \(T_l\) if ground and to its field’s value otherwise;*
**cancel: the Change-Volition removing the added volition.
Definition 35 (Offered). A volition \(v\) over \(M\) is offered at \(p\)* in an agent state if the tap of a button of a construct presented at \(p\) (Definition 34) adds \(v\).*
Two extremes of the construct are the interface’s stock elements, and we name the clauses after them, informally. A request clause poses the empty question and expects any answer: its construct is all fields and one button — a compose form — and the volition originates with the person, who supplies the transaction’s parameters — mint, pay, post, offer friendship. A respond clause poses an arrived offer: its construct carries the offer as content and the siblings’ answers — accept and decline — as buttons — an inbox card — and the person answers. In the platforms every volition-guarded clause is one of the two: a clause of the agent procedure, perpetually pending — its guards range over the person inputs and the groundness of the goal’s own arguments, so every quiescent agent state satisfies them, with state dispatch in the body — or a clause of a responder, spawned per arriving offer (Section 4), pending exactly while the offer awaits its answer.
theoremrestateCompleteness In every configuration of a safe run of the vmaGLP transition system over \(P\) and \(M\) and every \(p \in P\), a volition over \(M\) is offered at \(p\) iff it is pending at \(p\) (Definition 30).
The proof is in Appendix C of the supplementary material.
GLP’s semantics gives the person channel (Section 3) no interpretation; vGLP supplies it: the volition-guarded clauses are where the person enters the language. An implementation must therefore map the volition-guarded clauses into concrete user-interface constructs. Pragmatically, the constructs are rather standard [10], [11]:
a pending reduction of a respond clause — an inbox card carrying the offer, its buttons the siblings’ answers;
a request clause, perpetually pending — a compose form collecting the person inputs, through its fields or through the selection that opens it;
a Change-Volition adding a volition — the person’s tap; removing one — cancel;
the fulfilment of a volition by its reduction — the card’s removal;
outcomes and state — ordinary output streams to the screen, the classic stream I/O of concurrent logic programming, a chat list or balance kept live as a stream read.
How a construct is laid out is pragmatics; its semantic content is the Change-Volition it performs.
Remark 2 (Persistence from Tail Recursion). A request clause of the platforms is tail-recursive over the agent goal, so its ask re-arises with the recursive goal after every fulfilment (Remark 1): its form is persistent, remaining on screen and querying the person for their next transaction — the interface’s command-line box. A respond clause’s ask arises with its responder and is fulfilled with it: its card is transient, removed on fulfilment. The grassroots app’s chat input (Section 7) is the persistent form of the tail-recursive send clause.
vGLP needs no new machine. GLP already connects the program to the person: each agent’s first channel is to the person operating it; messages flowing toward the person are rendered by the runtime, and the person’s responses flow back as GLP messages [22], [23]. The volitional layer is implemented on that channel by compilation: a vGLP program becomes a GLP program — the agent, its volition-guarded clauses compiled to ordinary clauses receiving commands, and the mediator, escrowing pending reductions — and the person acts through the manifest’s constructs, each performing one grant. We first make the person’s side formal.
Definition 36 (Person Channel, Person Writer, GLP with a Person, Grant). Let \(N\) be a GLP program and \(G_0\) a goal satisfying SO. A person channel* of \(G_0\) is a variable pair \((U, U?)\) such that \(U?\) occurs in \(G_0\) and \(U\) does not; \(U\) is its person writer. GLP with a person over \(N\), \(G_0\), and a designated person channel is the transition system obtained from the maGLP transition system over a singleton set of agents and \(N\) (Definition 23), with initial resolvent \((G_0, \emptyset)\), by adding grant transitions \[(G, \sigma) \;\rightarrow\; (G,\; \sigma \circ \{U? := [c\,|\,U_1?]\})\] where \(c\) is a ground term, \(U\) the person writer, and \(U_1\) a fresh variable, the person writer after the transition; the partial equivalence is the maGLP transaction equivalence, with grant transitions outside its domain.*
A grant is the person’s act: a construct’s tap or submission grants the command term it carries. Grants lie outside the domain of the equivalence. Cancel is local to a construct, so removing Change-Volitions have no image in the implementation, and need none: they carry no liveness obligation. Definitions 24 (proper run) and 33 (correct) apply to GLP with a person verbatim, grants leaving the resolvent unchanged. Each pending volition-guarded clause (Definition 30) is an ask; the asks are rendered per the manifest (Definition 34) — a respond clause’s ask as a card, its offer escrowed under a request identifier, a request clause’s as a form — and the construct’s grant carries the answer or the command; the pending table is in the mediator, not in the program.
theoremrestateCompilation For the simple vGLP program \(M\) realising a CVA platform (Theorem [thm:realisation]), vcGLP\((M)\) has a correct implementation by GLP with a person, the constructs of the manifest of \(M\) performing the grants.
The construction — the canonical compilation and its mapping — and the proof are in Appendix C of the supplementary material; the mapping takes a construct’s grant to the Change-Volition adding the willed volition, and the reduction consuming a granted command to the volition-guarded reduction fulfilling its volition.
The multiagent lift. The volitional layer and the compilation are per-agent: no cross-agent transaction reads a volitional state, and the person channel is local to its agent. The compilation therefore applies per agent to the vmaGLP transition system over \(P\) and \(M\), its Communicate and Cold-call transactions carried unchanged by the multiagent GLP runtime [22], [23].
The current implementation. The standard GLP implementation, extended with the two user-interface constructs, realises the compilation today, per platform, with no engine changes and no compiler — each vGLP program is compiled “manually” (by AI) into a GLP agent plus a per-platform mediator: pending reductions escrowed in a pending table under request identifiers, rendered as inbox cards; the person’s answers returned through command constructors routing the escrowed writer back to the agent; volitions fulfilled by construction. The composite — engine, mediator, and the Dart bridge rendering the constructs — is the platform’s implementation of vGLP. The source and its “manual” compilation into an agent and mediator (tested and deployed) exhibit it clause for clause, and Section 6 shows the before and after per platform.
We claim, informally, that the composite realises the compilation. A tap or submission on a construct is a grant: the granted command adds the volition, and cancel withholds it. An ask is an entry in the pending table: the mediator escrows each pending volition-guarded reduction under a request identifier that carries its question. A volition-guarded Reduce is the consumption of the escrowed answer: the command routes the escrowed writer back to the agent, and the clause the person chose reduces. An entry can be consumed only once, since its writer has a single reader.
This section specifies three grassroots platforms — the grassroots social graph, grassroots social network, and grassroots coins — each as volition-guarded transactions, as communicating volitional agents (Section 2.5), and as a vGLP program with its compilation to the deployed GLP implementation.
Appendix B of the supplementary material exhibits the “manual” compilation, verbatim, on the pay transaction and the swap offer; the full sources will be released in a public repository once the paper is deanonymised.
In a grassroots social network [3], the social graph is stored distributively under the control of the people themselves, with each person storing the local neighbourhood pertaining to them, and no third-party having access unless explicitly granted. Each agent \(p\) maintains, as its local state, a finite set \(c_p\subseteq P\) recording the friends of \(p\); initially \(c_p = \emptyset\). Befriending adds \(q\) to \(c_p\) and \(p\) to \(c_q\); unfriending removes them.
For agents \(P \subset \Pi\) with local-states function \(S(P) := 2^P\) and initial state \(c_p := \emptyset\) for all \(p \in P\), the social graph volition-guarded transactions are:
Definition 37 (Grassroots Social Graph Volition-Guarded Transactions).
Befriend\((p,q)\): \(c'_p := c_p \cup \{q\}\), \(c'_q := c_q \cup \{p\}\), provided \(q \notin c_p\). Guarded by \(\{p,q\}\).
Unfriend\((p,q)\): \(c'_p := c_p \setminus \{q\}\), \(c'_q := c_q \setminus \{p\}\), provided \(q \in c_p\). Guarded by either \(p\) or \(q\).
Introduce\((p,q,r)\): \(c'_q := c_q \cup \{r\}\), \(c'_r := c_r \cup \{q\}\), provided \(q,r \in c_p\), \(q \ne r\), and \(r \notin c_q\). Guarded by \(\{q,r\}\).
Befriending requires both persons to be willing; unfriending can be initiated by either; an introduction, offered by a common friend \(p\), forms the friendship \(\mathrm{Befriend}(q,r)\) once both \(q\) and \(r\) are willing. The grassroots social graph and social network are introduced and analysed in [1], [3].
CVA realisation. As a CVA platform (Section 2.5), the social graph keeps the friend set \(c_p\) as its platform state and realises Befriend and Unfriend as unary platform transactions over CVA messages. Befriend, guarded in the specification by \(\{p,q\}\), decomposes into an offer by \(p\) and an accept by \(q\); Unfriend, guarded by either, is a single unilateral transaction; an introduction decomposes into an offer by the common friend \(p\) and an acceptance by each of \(q\) and \(r\). Five transactions are volitional — guarded by the acting person, and the volitions the UI elicits — and three are reactive:
Definition 38 (Social Graph CVA Platform Transactions).
Offer friend. (guarded by \(p\)) For \(q\in\mathit{known}_p\) with \(q\notin c_p\): add \(\mathsf{message}(p,q,\mathsf{friend\_request})\) to \(o_p\).
Accept friend. (guarded by \(q\)) Provided \(\mathsf{message}(p,q,\mathsf{friend\_request})\in i_q\) and \(p\notin c_q\): set \(c_q := c_q\cup\{p\}\) and add \(\mathsf{message}(q,p,\mathsf{accept})\) to \(o_q\).
End friend. (guarded by \(p\)) For \(q\in c_p\): set \(c_p := c_p\setminus\{q\}\) and add \(\mathsf{message}(p,q,\mathsf{unfriend})\) to \(o_p\).
Offer introduction. (guarded by \(p\)) For \(q,r\in c_p\) with \(q\ne r\) and \(r\notin c_q\): mint a fresh channel pair and add \(\mathsf{message}(p,q,\mathsf{intro}(r,\mathit{ch}_q))\) and \(\mathsf{message}(p,r,\mathsf{intro}(q,\mathit{ch}_r))\) to \(o_p\), one half of the pair to each.
Accept introduction. (guarded by \(q\)) Provided \(\mathsf{message}(p,q,\mathsf{intro}(r,\mathit{ch}_q))\in i_q\) and \(r\notin c_q\): acknowledge on \(\mathit{ch}_q\).
Integrate accept. (reactive) Provided \(\mathsf{message}(q,p,\mathsf{accept})\in i_p\) and \(q\notin c_p\): set \(c_p := c_p\cup\{q\}\).
Integrate unfriend. (reactive) Provided \(\mathsf{message}(p,q,\mathsf{unfriend})\in i_q\) and \(p\in c_q\): set \(c_q := c_q\setminus\{p\}\).
Integrate introduction. (reactive) Provided \(q\) has acknowledged \(\mathsf{intro}(r,\mathit{ch}_q)\) and a matching acknowledgement from \(r\) is in \(i_q\): set \(c_q := c_q\cup\{r\}\).
The GLP implementation is an agent realising these platform transactions — the introduction’s channel-passing handshake among them (introduce, befriend_intro, accept_intro, reject_intro) — and a
mediator, the UI that elicits the volitions. The epoch-encoded friendship lifecycle is given in [1].
vGLP realisation. The correspondence of Theorem [thm:realisation], transaction by transaction: Offer friend is the request clause
*(Target); Accept friend the responder pair spawned on the arrived cold call, accept and decline binding the response; End friend the one-way *(Target) — guarded by either party, so no sibling and no decline; Offer introduction
the clause *(P,Q); Accept introduction the responder pair spawned on the arrived intro; and the two Integrate transactions ordinary clauses. The vGLP source, “manually” compiled into an agent and mediator (tested and deployed),
renders the four request clauses as the compose commands connect, unfriend, send, introduce, and the two responders as inbox cards escrowed under req(N). The introduction, the platform’s
richest transaction, is exhibited in Appendix B of the supplementary material.
Groups extend the social network beyond bilateral communication. A group is a set of agents who can all communicate with each other; any agent may create a group. Adding a member requires both the creator and the member to be willing; removing a member or leaving a group can be initiated by either.
Group communication proceeds in two steps: a member posts a message to the group (a unary transaction, guarded by the member), and the message is then delivered to all members (an unguarded transaction).
We extend the grassroots social graph (Definition 37) with group memberships and group communication. Let \(N\) be a set of group names and \(X\) a set of message contents. A group identifier is a pair \(g = (a, n)\) where \(a \in P\) is the creator and \(n \in N\) is the name; we write \(\mathit{cr}(g) = a\) and let \(\mathcal{G}\) denote the set of all group identifiers.
The local state of each agent \(p\) is extended with a finite set \(\mu_p \subseteq \mathcal{G}\) of group memberships, with \(p\) being a member of \(g\) when \(g \in \mu_p\). For each \(g \in \mathcal{G}\), \(p\) also maintains a member output stream \(o_p^g \in (P \times X)^*\), a chat stream \(s_p^g \in (P \times X)^*\), and a delivery index \(\delta_p^g \in \mathbb{N}\). Initially \(\mu_p = \emptyset\), \(\delta_p^g = 0\), and \(o_p^g = s_p^g = \varepsilon\). The friend sets of Definition 37 are unchanged by the transactions below.
The grassroots social network transactions include all social graph transactions of Definition 37, together with the following:
Definition 39 (Grassroots Social Network Volition-Guarded Transactions).
Create group\((g)\): A unary transaction by agent \(a := \mathit{cr}(g)\), guarded by \(a\), with participants \(\{a\}\), provided \(g \notin \mu_a\): \(\mu'_a := \mu_a \cup \{g\}\).
Join group\((g, q)\): A binary transaction with participants \(\{a, q\} \subseteq P\), \(a := \mathit{cr}(g) \ne q\), guarded by \(\{a, q\}\), provided \(g \notin \mu_q\): \(\mu'_q := \mu_q \cup \{g\}\).
Leave group\((g, q)\): A binary transaction with participants \(\{a, q\} \subseteq P\), \(a := \mathit{cr}(g) \ne q\), guarded by either \(a\) or \(q\), provided \(g \in \mu_q\): \(\mu'_q := \mu_q \setminus \{g\}\).
Post to group\((g, p, x)\): A unary transaction by agent \(p\), guarded by \(p\), with \(g \in \mu_p\): \(o'^{g}_p := o_p^g \cdot (p, x)\).
Deliver to group\((g)\): An unguarded transaction with participants \(\{q \in P : g \in \mu_q\}\); provided some participant \(p\) has \(\delta_p^g < |o_p^g|\), let \((p, x) := o_p^g[\delta_p^g]\), the effect is \(\delta'^{g}_p := \delta_p^g + 1\) and, for every participant \(q\), \(s'^{g}_q := s_q^g \cdot (p, x)\).
In each transaction, all components not explicitly updated are preserved.
Deliver-to-group is an abstraction of an atomic-broadcast primitive in the sense of [26]: a posted message is appended, by a single unguarded transaction, to the chat stream of every current member of the group.
A public feed created by agent \(a\) is defined to be a group \(g\) with \(\mathit{cr}(g) = a\) in which the post-to-group transaction is restricted to \(p = a\); all other members are followers.
A direct message channel between friends \(p\) and \(q\) is realised by \(p\) creating a group \(g\) with \(\mathit{cr}(g) = p\) and \(q\) joining it; once those transactions have been carried out, the members of \(g\) are \(\{p, q\}\). The guards of the join-group transaction (\(\{p, q\}\)) coincide with the befriend guards.
CVA realisation. The social network adds groups, hosted by their creator and realised as CVA platform transactions. Membership, like befriending, is an offer/accept pair; posting is a unary transaction whose delivery to members is reactive.
Definition 40 (Social Network CVA Platform Transactions).
Create group. (guarded by \(a\)) For a fresh name, create the group \(g\) with \(\mathit{cr}(g)=a\) and initialise its hub: \(\mu_a := \mu_a\cup\{g\}\).
Offer membership. (guarded by \(a=\mathit{cr}(g)\)) For \(q\in c_a\): add \(\mathsf{message}(a,q,\mathsf{group\_invite}(g))\) to \(o_a\).
Accept membership. (guarded by \(q\)) Provided \(\mathsf{message}(a,q,\mathsf{group\_invite}(g))\in i_q\) and \(g\notin\mu_q\): set \(\mu_q := \mu_q\cup\{g\}\) and add \(\mathsf{message}(q,a,\mathsf{group\_join}(g))\) to \(o_q\).
Post to group. (guarded by \(p\)) For \(g\in\mu_p\) and content \(x\): add \(\mathsf{message}(p,\mathit{cr}(g),\mathsf{group\_msg}(g,p,x))\) to \(o_p\).
Leave group. (guarded by \(p\)) For \(g\in\mu_p\) with \(p\ne\mathit{cr}(g)\): set \(\mu_p := \mu_p\setminus\{g\}\) and add \(\mathsf{message}(p,\mathit{cr}(g),\mathsf{group\_leave}(g))\) to \(o_p\).
Remove member. (guarded by \(a=\mathit{cr}(g)\)) For a member \(q\): add \(\mathsf{message}(a,q,\mathsf{group\_removed}(g))\) to \(o_a\) and drop \(q\) from the hub.
Distribute. (reactive, \(a=\mathit{cr}(g)\)) On \(\mathsf{message}(p,a,\mathsf{group\_msg}(g,p,x))\in i_a\): add \(\mathsf{message}(a,r,\mathsf{group\_msg}(g,p,x))\) to \(o_a\) for every member \(r\).
Integrate. (reactive) Membership grants, group messages, leaves, and removals are integrated on receipt, updating \(\mu\) and the local chat stream.
A public feed is a group in which only the creator posts, and a direct message channel a two-member group, so both reuse these transactions unchanged. The GLP implementation comprises an agent, the mediator, and the child agent, per the child-safe network [2].
vGLP realisation. The same correspondence carries over: Create group, Offer membership, Post, Leave, and Remove are request clauses *(...); Accept membership is a responder pair spawned on the arrived invite; Distribute and
the Integrations are ordinary clauses. The vGLP source’s one-to-one messaging is verified clause for clause against the deployed agent; groups are specified, not yet deployed (Section 7).
Grassroots coins [4], [27] are units of debt that can be issued and traded digitally by any person. Each person’s coins are backed by the goods and services they offer, priced in their own currency, with liquidity arising from mutual credit via coin exchange among persons that know and trust each other. Grassroots bonds [5] extend grassroots coins with a maturity date, reframing grassroots coins—cash—as mature grassroots bonds. Coin-for-bond redemption generalises coin-for-coin redemption, allowing the lending of liquid coins in exchange for interest-bearing future-maturity bonds. Digital social contracts—voluntary agreements among persons, specified, fulfilled, and enforced digitally—can express the full gamut of financial instruments as the voluntary swap of grassroots bonds, including credit lines, loans, sale of debt, forward contracts, options, and escrow-based instruments [5].
Definition 41 (Grassroots Bonds). A \(p\)-bond with maturity date \(d\), denoted \(_{p,d}\), is a unit of debt issued by \(p \in \Pi\) maturing at date \(d\in \mathbb{N}\). We let \(\mathcal{B}(P) =\{\) \(_{p,d} : p\in P, d\in \mathbb{N}\}\) denote the set of all grassroots bonds by agents \(P\subset\Pi\). Each agent \(p\) maintains as its local state a pair \((c_p, d_p^*)\) where \(c_p\) is a multiset of members of \(\mathcal{B}(P)\) (initially \(\emptyset\)) and \(d_p^*\in \mathbb{N}\) is the local current date (initially \(0\)); \(p\) considers a bond \(_{q,d}\) to be mature, and refers to it as a \(q\)-coin* (denoted \(_q\)), iff \(d\le d_p^*\). There is no global date; agents may disagree on which bonds are mature.*
The grassroots bonds volition-guarded atomic transactions are:
Mint: \(c'_p := c_p \cup \text{\textcent}^k_{p,d}\), \(k>0\), \(d\in\mathbb{N}\); \(d_p^*\) unchanged. Guarded by \(p\).
Advance-date: \({d_p^*}' > d_p^*\); \(c_p\) unchanged. Unguarded.
Voluntary swap: \(c'_p := (c_p\cup y)\setminus x\), \(c'_q := (c_q\cup x)\setminus y\), provided \(x\subseteq c_p\), \(y\subseteq c_q\); \(d_p^*\) and \(d_q^*\) unchanged. Guarded by \(\{p,q\}\).
Pay: \(c'_p := c_p\setminus x\), \(c'_q := c_q\cup x\), where \(x\subseteq c_p\) is a set of \(q\)-coins (that is, bonds \(_{q,d}\) with \(d\le d_p^*\)); \(d_p^*\) and \(d_q^*\) unchanged. Guarded by \(p\).
Redeem: \(c'_p := (c_p\cup y)\setminus x\), \(c'_q := (c_q\cup x)\setminus y\), where \(x = \{\text{\textcent}_{q,d'}\}\subseteq c_p\) with \(d'\le d_p^*\), \(y = \{\text{\textcent}_{r,d}\}\subseteq c_q\), \(r\in P\), \(d\in\mathbb{N}\); \(d_p^*\) and \(d_q^*\) unchanged. Guarded by \(p\).
Minting, paying, and redeeming are guarded by the initiator; voluntary swap requires both parties to be willing; Advance-date is unguarded, since local time advances mechanically. In redemption, the redeemer chooses any bond held by the coin’s issuer—regardless of who issued the bond—generalising coin-for-coin redemption [4] to coin-for-bond redemption [5].
Definition 42 (Grassroots Coins and Bonds). The grassroots coins and bonds* \(\mathit{GCB}\) is the protocol over the volition-guarded transactions above with local-states function mapping each \(P\subset\Pi\) to the set of pairs \((c,d)\) where \(c\) is a multiset of members of \(\mathcal{B}(P)\) and \(d\in\mathbb{N}\), and equivalence \(\sim\) identifying Mint transactions by the same agent \(p\) with the same \(k\) and \(d\), Advance-date transactions of the same agent, and Swap transactions between the same pair exchanging the same multisets, per the protocol construction of Section 2.*
Grassroots coins and bonds are introduced and analysed in [4], [5].
CVA realisation. As a CVA platform (Section 2.5), each agent keeps its bond multiset \(c_p\) and local date \(d_p^*\) as platform state. Minting, paying, and redeeming are unilateral transactions guarded by the initiator; a voluntary swap is an offer/accept pair; advancing the local date is unguarded.
Definition 43 (Coins and Bonds CVA Platform Transactions).
Mint. (guarded by \(p\)) For \(k>0\) and maturity \(d\): add \(k\) fresh bonds \(_{p,d}\) to \(c_p\).
Propose swap. (guarded by \(p\)) Offering \(x\subseteq c_p\) and seeking a specification \(y\): remove \(x\) from \(c_p\) and add \(\mathsf{message}(p,q,\mathsf{trade\_propose}(y,x))\) to \(o_p\).
Accept swap. (guarded by \(q\)) Provided a \(\mathsf{trade\_propose}(y,x)\) from \(p\) in \(i_q\) and \(y\subseteq c_q\): set \(c_q := (c_q\cup x)\setminus y\) and return \(\mathsf{trade\_accept}(y)\) to \(p\).
Decline swap. (guarded by \(q\)) Provided a \(\mathsf{trade\_propose}(y,x)\) from \(p\) in \(i_q\): return \(\mathsf{trade\_decline}(x)\) to \(p\).
Pay. (guarded by \(p\)) A swap offering coins \(x\) and seeking nothing; the recipient integrates without a decision.
Redeem. (guarded by \(p\)) A swap offering \(q\)-coins and seeking any bond of issuer \(q\); the issuer fills automatically when able.
Deposit / Cancel escrow. (guarded by \(p\)) Place bonds in a time-locked escrow for a beneficiary, or cancel before release — the building block for digital social contracts.
Integrate. (reactive) Accepted swaps, declined swaps — refunding the give-coins to the proposer — payments, redemption fills, escrow releases, and local-date advances are integrated on receipt.
The GLP implementation comprises an agent, a mediator, and actors, with a secure variant. The full secure development is given in [1].
vGLP realisation. Mint, Pay, Redeem, and Propose swap are the request clauses *(K), *(Friend,Coin,Amt) (the worked example of Section 4), *(Friend,Amount), and
*(Friend,GiveCoin,GiveAmt,WantCoin,WantAmt); Accept and Decline swap are the responder pair spawned on the arrived swap_propose, its accept declining itself when the want-coins are not held; fills, deliveries, and balances are
ordinary clauses. The vGLP source of the coins agent, and its “manual” compilation into an agent and mediator — the worked before-and-after of Sections 4 and 5; its minimal request
clause, Mint, is the opening exhibit of Section 1. Both sources place the request clauses last in the agent procedure, after the catch-alls.
The grassroots app is the working smartphone app the approach yields: the grassroots social graph, social network, and coins, each a vGLP program “manually” compiled to its agent and mediator (Section 6), rendered by one Dart interpreter as three panels of one app — Friends, Chats, and Coins — each reached by a bottom-bar icon badged with the panel’s pending asks (Figure 1). Every element of every panel is one of the manifest’s constructs (Definition 34): the cards of the platform’s respond clauses, the forms of its request clauses, and the screen (See Appendix B). The deployed build implements the social graph, one-to-one conversations, and coins among friends (Appendix A); groups and bonds, specified in Section 6, add no new constructs and will be implemented shortly.
Friends. The social graph. Its forms are the four request clauses — offer friendship, unfriend, message a friend, introduce two friends; its cards the two sibling pairs — a friend offer and an introduction, each accepted or declined;
its screen the friends list, kept by connected, unfriended, and rejected.
Chats. The social network — one-to-one and group messaging, element for element the messaging app people already know (Table 1). The open conversation’s input is the persistent form of the tail-recursive send clause (Remark 2); the chat list and threads are the screen; the panel’s card is a group invitation, accepted before the group joins the chat list. A grassroots machine carries a message only to an established friend, so first contact is gated in Friends: what a commercial messenger lets land unbidden — a stranger’s first message, being added to a group — grassroots holds as a card until the person accepts.
| WhatsApp element | Realisation |
|---|---|
| Chat list, open conversation | the screen: threads extended by delivery |
| Sending a message | the persistent form of the send clause; the delivery ticks the screen |
| New chat or group, add or remove a member, leave | the forms of the group request clauses |
| Connect request, group invitation | cards: a friend offer or an invitation, accepted or declined before contact begins |
Coins. Grassroots coins among friends (See Appendix A). Its forms are mint, pay, redeem, and propose a swap; its card the proposed swap, accepted or declined; its screen the balances, organised by friend — mutual credit is confined to the social graph, so the wallet lists the person’s friends, each drilling down to the coins they hold.
One interpreter. The manifest is declared in GLP: the compiled form of Definition 34 is the platform’s UserCmd type — one constructor per
request clause, and per sibling pair the answers routing its req(N) — and its UserNotify type, the cards and the screen vocabulary. One Dart interpreter renders any manifest: everything crossing to Dart is a ground term or a
request identifier; response writers and channels stay escrowed on the GLP side. A new platform declares its two types and gains a panel, an icon, and its alerts, with no platform-specific Dart; the balances view, keyed by holder and coin, is the one
generic view coins added, reusable by any balance-bearing platform. The same interpreter, carrying only the platforms’ GLP sources, builds and runs unchanged on the desktop, the iPhone simulator, and the phone: the grassroots app is deployed as a native
app on a physical smartphone.
vGLP makes two independent contributions: it conditions a machine step on a person’s volition, and it derives the interface from the program’s semantics. The first relates to formal approaches to user interface semantics, in which the person is a source of input, an environment, a chooser, an editor, or a signer; we review these first, by the person’s role. The second relates to work that derives the interface automatically, but from an application’s data, object model, or tasks rather than from a semantics whose steps a person guards; and a further tradition predicts or verifies a given interface. In none does a person’s will guard a transaction, and in none is the interface derived from transaction semantics. Underlying these differences is what a human input is: in the languages that present a program to its user it is a command driving an otherwise-inert tool; in those that generate an interface from data or tasks it is a value completing a task; in vGLP it is a volition authorising an otherwise-ready machine transaction — a guard, not a command or a value.
Formal approaches to user interface semantics. Functional reactive programming gave interaction a denotational semantics with Fran [6]; Fudgets composed graphical interfaces from stream processors in a lazy functional language [7]; Elm gave a GUI language an operational semantics [8]; and Krishnaswami and Benton gave GUIs a denotational model in which the arbitrariness of user input is captured by a nondeterminism monad [9]. Task-oriented programming executes typed editors the person fills: iTasks [10], [28], and its formal core TopHat, whose labelled transitions consume user inputs [11]. iTasks derives those editors generically from the task’s data types, so an interface is derived — but from the data, where the inputs drive the workflow. Game semantics models a program against an Opponent whose strategy is the environment’s [14]; interaction trees represent impure programs whose events the environment answers [15]; interactive computation makes the environment part of the computational model [16]. Formal human-computer interaction modelled interactive systems directly: the PIE model [29], interactors [30], Petri-net interactive cooperative objects [31], statecharts [12], and the synchronous languages [13]. These works give the interface a semantics after it is designed. The concurrent logic languages connected keyboard and screen as stream-processing agents [32]; a message to the person could carry an unbound variable that the person’s response assigns. Ceptre’s interactive stages let the player select which enabled linear-logic rule fires [33]: the person resolves nondeterminism. Hazelnut gives an operational semantics to the person’s edit actions on programs [34]. Smart-contract semantics fire a transition only on a transaction signed by a key [35]. Beliefs, desires, and intentions in agent programming [36] are the software agent’s own, not a person’s, and the human-approval steps of contemporary AI-agent frameworks are architectural practice without semantics.
The interface derived from the program. Deriving the interface from the program, rather than authoring it separately, is an established idea, on bases distinct from ours. Naked objects presents a system’s domain objects directly and creates the interface entirely automatically from their definitions by reflection [37], [38], in a noun-verb style: the person views objects and invokes their methods, with no hand-written presentation layer. Model-based user-interface development derives interfaces from separate task and domain models — the CAMELEON reference framework [39], ConcurTaskTrees and model-based design [40], and description languages such as UIML [41] and UsiXML [42], surveyed in [43]; task-oriented programming (above) derives its editors generically from data types; and structure editors derive an editing interface from a grammar [44]. In each the interface follows from a description of the application’s data, objects, or tasks.
Command, value, or guard. A naked-objects application is a tool: nothing happens without the operator, so the input is the control flow. A task-oriented input is a datum the workflow consumes. vGLP’s reductions proceed on their own; a volition-guarded reduction is ready but withheld: its legitimacy requires the willingness of the party it binds — a transfer the payer’s, a friendship both parties’. Prior work derives the interface so the person can operate the program or supply values to it; vGLP derives it so the person can will its steps.
Predicting and verifying a given interface. Interface design is often treated as a craft outside formal computer science, yet two lines formalise it. Predictive engineering models estimate a design’s performance from the person’s elementary actions — the keystroke-level model and the GOMS family [45]–[47]. Formal methods for interactive systems specify and verify interfaces — from grammars for user interfaces [48] through the collected work of the field [49], [50], of which the dialogue models above are part.
To the best of our knowledge, vGLP is the first programming language whose operational semantics conditions transactions on a person’s volition — elicited, pending until willed, retractable, and fulfilled — with the interface derived from that semantics rather than from the application’s data or tasks.
We incorporated people in the operational semantics of a programming language: vGLP’s volition-guarded clauses are reducible only at their person’s will, the person’s change-volition transitions are their own, and a willed volition is fulfilled once its reduction is taken. The interface is derived from the semantics rather than designed: a program’s questions are its pending volition-guarded reductions, and the manifest reads each clause’s construct off its volition guard — its content the context, its fields the person inputs, its buttons the siblings — a card, a form, the persistent command-line box of a tail-recursive clause. The realisation proceeds from volition-guarded multiagent atomic transactions through communicating volitional agents to vGLP, and by compilation onto GLP with the user-interface constructs to the running grassroots app, deployed on a physical smartphone.
Future work: native support for the volitional runtime in the GLP engine, retiring the per-platform mediator; a vGLP-to-GLP compiler, replacing “manual” (AI) compilation; typed person inputs, subsuming the ground guards on the person’s data; and standing volitions — a person willing a class of goals rather than one reduction.
This appendix gives the restricted model realised by the coins app of Section 7. It is the grassroots coins and bonds protocol \(\mathit{GCB}\) (Definition 42) under two simplifications: (i) drop maturity — there are no bonds, only coins, so the local date and Advance-date play no role; and (ii) confine holdings and transactions to the social graph (Section 6.1) — a person holds and trades only their friends’ coins. The full model, with bonds, maturity, and escrow-based instruments, is in Section 6.3 and [4], [5].
Dropping maturity simplifies Definition 41: every bond is mature, so a \(p\)-bond is simply a \(p\)-coin, denoted \(_p\), a unit of debt issued by \(p\). We let \(\mathcal{C}(P)=\{\text{\textcent}_q : q\in P\}\) be the coins of agents \(P\subset\Pi\). The friends restriction ties the holding graph to the social graph: mutual credit presupposes that the parties know and trust each other [4], and in a grassroots social network that relation is friendship. So the same connection that gates contact (Section 7) gates coin-holding: a person holds and transacts only their friends’ coins, and their own.
Definition 44 (Coins Among Friends). Let \(F_p\subseteq P\) be the friends of \(p\) in the grassroots social graph (Section 6.1). Each agent \(p\) maintains as its local state a multiset \(c_p\) of coins drawn from \(\{\text{\textcent}_q : q\in F_p\cup\{p\}\}\), initially \(\emptyset\). The coins among friends* protocol is \(\mathit{GCB}\) (Definition 42) restricted to these states, with every bilateral transaction requiring its counterparties to be friends.*
The guarded transactions of Section 6.3, restricted to coins among friends:
Mint: \(c'_p := c_p \cup \text{\textcent}^k_{p}\), \(k>0\). Guarded by \(p\).
Pay: \(c'_p := c_p\setminus x\), \(c'_q := c_q\cup x\), where \(q\in F_p\) and \(x\subseteq c_p\). Guarded by \(p\).
Redeem: \(c'_p := (c_p\cup y)\setminus x\), \(c'_q := (c_q\cup x)\setminus y\), where \(q\in F_p\), \(x\subseteq c_p\) are \(q\)-coins, and \(y\subseteq c_q\). Guarded by \(p\).
Voluntary swap: \(c'_p := (c_p\cup y)\setminus x\), \(c'_q := (c_q\cup x)\setminus y\), where \(q\in F_p\), \(x\subseteq c_p\), \(y\subseteq c_q\). Guarded by \(\{p,q\}\).
On redeem, the issuer \(q\) fills automatically [4]. The bond machinery of Section 6.3 — maturity, the local date, and Advance-date — is absent.
These volitions are elicited by the constructs of Section 7 exactly as the other platforms are. Mint, Pay, and Redeem are self-guarded request clauses; a swap is a request on the proposer’s side
(Propose) and a respond on the counterparty’s (Accept). Balances are read by a standing request — the bare * balance-report clause of the agent — and rendered as the wallet’s values. The coins app is therefore
another instance of the one interface (Section 7): its UserCmd/UserNotify types, declared in its mediator, yield a manifest the same interpreter renders — the test being whether a
balance-bearing platform needs only a manifest, or a new generic view.
This appendix exhibits the vGLP source of the social graph’s introduction, and the manual compilation of Section 5 on two fragments of the deployed sources of the grassroots app, verbatim: the pay transaction — a request clause, elicited by a form — and the swap offer — a respond pair, elicited by a card. Long clause heads are wrapped for the page; the sources are otherwise unchanged. The code appendices are included to preserve anonymity; the final paper will include a pointer to the public repository.
The introduction, a request clause and a respond pair. The social graph’s richest transaction (Section 6.1): the offer clause *(P,Q), the responder spawned on the arrived
intro, and its accept and reject siblings:
*(P, Q)
agent(Id, UserIn, NetIn, Outs) :-
ground(Id?), ground(P?), ground(Q?), ~(P? =?= Q?),
new_channel(PQCh, QPCh) |
send_friend(P?, msg(Id?, P?, intro(Q?, QPCh?)), Outs?, Outs1),
send_friend(Q?, msg(Id?, Q?, intro(P?, PQCh?)), Outs1?, Outs2),
agent(Id?, UserIn?, NetIn?, Outs2?).
agent(Id, UserIn, [msg(_From, Id1, intro(Other, Ch))|NetIn],
Outs) :-
Id? =?= Id1? |
respond_intro(Id?, offer(Other?), Ch?, Ans),
merge(Ans?, UserIn?, UserIn1),
agent(Id?, UserIn1?, NetIn?, Outs?).
*(Answer=yes, Other?)
respond_intro(Id, offer(Other), Ch, Ans?) :-
ground(Id?), ground(Other?),
send(ack(Id?), Ch?, Ch1) |
intro_await_peer(Other?, Ch1?, Result),
inject_intro_result(Result?, [], Ans).
*(Answer=no, Other?)
respond_intro(_, offer(Other), ch(_ChIn, [nack|[]]), []) :-
ground(Other?) | true.
Pay, a request clause. The vGLP pay clause is the worked example of Section 4. Its manual compilation: the command constructor pay(Constant, Constant, Integer) of the mediator’s
UserCmd type, the mediator pass-through, and the agent clause matching the granted command:
ui_mediator(Id, AgentCh, UserCh, Ps, N) :-
receive(pay(Friend, Coin, Amount), UserCh?, UserCh1),
ground(Id?), ground(Friend?), ground(Coin?),
integer(Amount?) |
send(msg('_user', Id?, pay(Friend?, Coin?, Amount?)),
AgentCh?, AgentCh1),
ui_mediator(Id?, AgentCh1?, UserCh1?, Ps?, N?).
agent(Id, [msg('_user', Id1, pay(Friend, Coin, Amt))|UserIn],
NetIn, Outs, Holdings) :-
Id? =?= Id1?, ground(Friend?), ground(Coin?), integer(Amt?) |
sub_coin(Coin?, Amt?, Holdings?, Status, Holdings1),
do_pay(Status?, Id?, Friend?, Coin?, Amt?, Holdings1?,
UserIn?, NetIn?, Outs?).
The swap offer, a respond pair. The arriving proposal spawns a responder carrying the offer and the response writer; the accept sibling injects its answer through the merge, and an ordinary agent clause carries it out on the agent’s
current holdings; the decline sibling injects decline_swap:
agent(Id, UserIn,
[msg(From, Id1, swap_propose(GiveCoin, GiveAmt,
WantCoin, WantAmt, SwapResp?))|NetIn],
Outs, Holdings) :-
Id? =?= Id1?, ground(From?), ground(GiveCoin?),
integer(GiveAmt?), ground(WantCoin?), integer(WantAmt?) |
respond_swap(offer(From?, GiveCoin?, GiveAmt?,
WantCoin?, WantAmt?), SwapResp, Ans),
merge(Ans?, UserIn?, UserIn1),
agent(Id?, UserIn1?, NetIn?, Outs?, Holdings?).
*(Answer=yes, From?, GiveCoin?, GiveAmt?, WantCoin?, WantAmt?)
respond_swap(offer(From, GiveCoin, GiveAmt,
WantCoin, WantAmt), SwapResp?,
[accept_swap(From?, GiveCoin?, GiveAmt?,
WantCoin?, WantAmt?, SwapResp)]) :-
ground(From?), ground(GiveCoin?), integer(GiveAmt?),
ground(WantCoin?), integer(WantAmt?) | true.
agent(Id, [accept_swap(From, GiveCoin, GiveAmt, WantCoin,
WantAmt, SwapResp?)|UserIn],
NetIn, Outs, Holdings) :-
ground(From?), ground(GiveCoin?), integer(GiveAmt?),
ground(WantCoin?), integer(WantAmt?) |
sub_coin(WantCoin?, WantAmt?, Holdings?, Status, Holdings1),
do_accept_swap(Status?, Id?, From?, GiveCoin?, GiveAmt?,
Holdings1?, SwapResp, UserIn?, NetIn?, Outs?).
Its manual compilation: the agent forwards the arrived proposal, response writer included, to the mediator; the mediator escrows the writer in the pending table under a fresh req(N) — the card — and the person’s answer routes it back to the
agent:
agent(Id, UserIn,
[msg(From, Id1, swap_propose(GiveCoin, GiveAmt,
WantCoin, WantAmt, SwapResp?))|NetIn],
Outs, Holdings) :-
Id? =?= Id1?, ground(From?), ground(GiveCoin?),
integer(GiveAmt?), ground(WantCoin?), integer(WantAmt?) |
lookup_send('_user',
msg(agent, '_user', swap_offer(From?, GiveCoin?, GiveAmt?,
WantCoin?, WantAmt?, SwapResp)),
Outs?, Outs1),
agent(Id?, UserIn?, NetIn?, Outs1?, Holdings?).
ui_mediator(Id, AgentCh, UserCh, Ps, N) :-
receive(msg(agent, '_user',
swap_offer(From, GC, GA, WC, WA, Resp?)),
AgentCh?, AgentCh1),
ground(From?), ground(GC?), ground(GA?), ground(WC?),
ground(WA?) |
send(swap_offer(From?, GC?, GA?, WC?, WA?, req(N?)),
UserCh?, UserCh1),
N1 := N? + 1,
ui_mediator(Id?, AgentCh1?, UserCh1?,
[pending(req(N?), swap_pending(Resp, GC?, GA?, WC?, WA?))
| Ps?], N1?).
ui_mediator(Id, AgentCh, UserCh, Ps, N) :-
receive(accept_swap(From, ReqId), UserCh?, UserCh1),
ground(Id?), ground(From?), ground(ReqId?) |
lookup_pending(ReqId?, Pv, Ps?, Ps1),
send(msg('_user', Id?, accept_swap(From?, Pv?)),
AgentCh?, AgentCh1),
ui_mediator(Id?, AgentCh1?, UserCh1?, Ps1?, N?).
This appendix proves the theorems of Sections 4 and 5, and gives the canonical realisation and the canonical compilation with their mappings.
Proof. By Definition 28, a transition fulfilling \(v\) at \(p\) requires \(v\) in the volitional state of \(p\) before it and removes exactly \(v\); a Change-Volition of \(p\) may add and remove volitions; and no other transition changes \(V_p\): Reduce with an ordinary clause, Communicate, and Cold-call leave volitional states unchanged, and transitions of other agents leave \(p\) stationary. Hence only a Change-Volition of \(p\) adds.
(i) \(c^i \rightarrow c^{i+1}\) fulfils \(v\), so \(v \in V^i_p\); since \(V^1_p = \emptyset\), there is a maximal \(j < i\) with \(v \notin V^j_p\): \(c^j \rightarrow c^{j+1}\) adds \(v\), so it is a Change-Volition of \(p\), and by the maximality of \(j\), \(v \in V^k_p\) for every \(j < k \le i\).
(ii) \(c^k \rightarrow c^{k+1}\) fulfils \(v\), so \(v \notin V^{k+1}_p\); \(c^{k'} \rightarrow c^{k'+1}\) fulfils \(v\), so \(v \in V^{k'}_p\); hence some \(c^j \rightarrow c^{j+1}\), \(k < j < k'\), adds \(v\): a Change-Volition of \(p\). ◻
Proof. While an instance of \(A\) is in \(G^k_p\), its reduction with \(C\) succeeds — the volition-guarded reduction under \(\theta\) succeeds with fulfilled volition \((C, \theta, \theta')\), held in \(V^k_p\) (Definition 28), and its reduction with a volition-guarded clause preceding \(C\) does not, no volition of it held; so the first clause whose reduction of the instance succeeds is \(C\) or a unit clause preceding \(C\) — \(M\) being simple, no other clause precedes \(C\) — and any Reduce of the instance is with such a clause. By Monotonicity (Proposition [prop:glp-monotonicity]), a clause whose reduction of the instance succeeds continues to succeed until an instance of \(A\) is reduced, so the first succeeding clause moves only earlier in the procedure and is eventually a fixed clause \(D\); from that point the Reduce class of \(A\) with \(D\) is enabled in every configuration, so by liveness a member is taken, reducing an instance of \(A\) with \(D\). ◻
Proof. If a volition \((C, \theta, \theta')\) is pending at \(p\), it is a pending volition of \(C\) on some unit goal \(A \in G_p\) (Definition 30), so the construct of \(C\) at \(A\) is presented at \(p\) and carries the button of \(C\), whose tap, its fields collecting the values of \(\theta\), adds the pending volition of \(C\) on \(A\) with answer \(\theta\) (Definition 34) — the volition itself: it is offered at \(p\) (Definition 35). Conversely, a tap adds only a pending volition of a clause on a unit goal in \(G_p\) (Definition 34), so a volition offered at \(p\) is pending at \(p\). ◻
Fix a CVA platform (Section 2.5). For a platform transaction \(t\) with parameters \(X_1,\ldots,X_k\), write t(X1,...,Xk) for its term,
pre_t for the guard testing its precondition, pre'_t for the restriction of that guard to the message and the state, and eff_t for the body kernel performing its effect — updating the state and appending its messages,
each addressed by name, to the output stream. The state term s(Known,In,A,T) carries the known peers, the recorded messages, the platform state, and the local date; record(M) is the bookkeeping transaction adding M to
In, with precondition true. All goals reach the state server on one merged channel and responder goals read its state stream, each through its own branch; split branches a channel or stream (a merge on the server side, a
distributor on the state side, the standard stream techniques [22]), and drain closes a terminating goal’s remaining streams.
Definition 45 (Canonical Realisation). The canonical realisation of a CVA platform is the simple vGLP program consisting of the following procedures.
The state server: per platform transaction \(t\), and for record, the clause
state([apply(t(X1,...,Xk))|Rs], S, Outs, Ss) :-
pre_t(X1?,...,Xk?, S?) |
eff_t(X1?,...,Xk?, S?, S1, Outs?, Outs1),
send(S1?, Ss?, Ss1),
state(Rs?, S1?, Outs1?, Ss1?).
followed, last, by
state([apply(_)|Rs], S, Outs, Ss) :-
otherwise |
state(Rs?, S?, Outs?, Ss?).Per volitional platform transaction \(t\) whose precondition reads the local state, the request procedure**
*(X1, ..., Xk)
t(Us) :-
ground(X1?), ..., ground(Xk?) |
send(apply(t(X1?,...,Xk?)), Us?, Us1),
t(Us1?).The router: per volitional platform transaction \(t\) whose precondition requires the arrived message m_t(Y1,...,Ym), the clause
route([m_t(Y1,...,Ym)|In], Us, Ss) :-
ground(Y1?), ..., ground(Ym?) |
send(apply(record(m_t(Y1?,...,Ym?))), Us?, Us1),
split(Us1?, Us2, Us3),
split(Ss?, Ss1, Ss2),
respond_t(m_t(Y1?,...,Ym?), Ss1?, Us2?),
route(In?, Us3?, Ss2?).
per reactive platform transaction \(t\) triggered by m_t(Y1,...,Ym), the clause
route([m_t(Y1,...,Ym)|In], Us, Ss) :-
ground(Y1?), ..., ground(Ym?) |
send(apply(record(m_t(Y1?,...,Ym?))), Us?, Us1),
send(apply(t(Y1?,...,Ym?)), Us1?, Us2),
route(In?, Us2?, Ss?).
and, last, the clause recording every remaining message likewise.
Per volitional platform transaction \(t\) whose precondition requires the arrived message m_t(Y1,...,Ym), with remaining parameters \(X_1,\ldots,X_k\), the
responder procedure**
*(X1, ..., Xk, Y1?, ..., Ym?)
respond_t(m_t(Y1,...,Ym), [S|Ss], Us) :-
ground(X1?), ..., ground(Xk?),
pre_t(Y1?,...,Ym?, X1?,...,Xk?, S?) |
send(apply(t(Y1?,...,Ym?, X1?,...,Xk?)), Us?, Us1),
drain(Ss?, Us1?).
respond_t(m_t(Y1,...,Ym), [S|Ss], Us) :-
~pre'_t(Y1?,...,Ym?, S?) |
respond_t(m_t(Y1?,...,Ym?), Ss?, Us?).Per unguarded platform transaction \(t\) whose precondition reads the local state, and for Advance-date, the ordinary procedure
t(Us) :-
send(apply(t), Us?, Us1),
t(Us1?).
and for Discover, the request procedure whose eff adds its person input to Known.
The initial goal is the state server on s([],[],a0,0) and the empty streams, one goal per request procedure, the router on the network input stream, and the split goals wiring the server channel and the state
stream.
Every procedure is simple: a request or responder procedure has one volition-guarded clause, first, and every other procedure is ordinary. Every message on Outs is delivered by Cold-call.
An apply is in flight from the Reduce that sends it until the server Reduce that consumes it; the applies in flight at \(p\) are linearly ordered by their position on the merged server channel. The
effective state of \(p\) is the state and output stream obtained from the server’s by serving the applies in flight, in order, per the server clauses.
Definition 46 (Realisation Mapping). Given a configuration of the vmaGLP transition system over \(P\) and the canonical realisation, the mapping \(\sigma\) yields the CVA configuration over \(P\) with, at each \(p\), where \(s(\mathit{Known},\mathit{In},A,T)\) and \(\mathit{Outs}\) are the effective state of \(p\):
\(\mathit{known}_p = \mathit{Known}\), \(a_p = A\), \(t_p = T\);
\(o_p\) = the set of messages on \(\mathit{Outs}\);
\(i_p = \mathit{In} \,\cup\,\) the set of messages on the network input stream of \(p\);
the volitional state of \(p\) is \(\{[t(C, \theta, \theta')] : (C, \theta, \theta') \in V_p\}\), with \(t(C, \theta, \theta')\) the platform-transaction instance of the clause \(C\) with parameters \(\theta\) — on the message carrying \(\theta'\) when \(C\) is a responder clause — and \([\cdot]\) the platform’s transaction equivalence.
Proof. \(\sigma\) maps the initial configuration to the initial CVA configuration with empty volitional states.
Safety, per transition. A Change-Volition of \(p\) maps to a change-volition of \(p\), its classes those of the added and removed volitions. A Reduce with the volition-guarded clause of a
request or responder procedure of transaction \(t\) fulfils its volition \((C,\theta,\theta')\) and appends apply(\(t(\bar
v)\)) to the server channel, \(\bar v\) the person inputs and message values: if pre_t holds on the effective state, the effective state advances by eff_t and the transition
maps to the platform transaction \(t(\bar v)\), whose class \([t(C,\theta,\theta')]\) is removed; otherwise the effective state is unchanged and the transition maps to the
change-volition removing that class. A Reduce of a router clause appending a reactive apply(\(t(\bar v)\)) maps to the reactive transaction \(t(\bar v)\) if
pre_t holds on the effective state, and to a stutter otherwise; its record apply leaves \(i_p\) unchanged — the message moves from the input stream into \(\mathit{In}\) — as does the router’s consumption of the message, so the remainder of the clause is a stutter. A Reduce of an ordinary perpetual procedure (\(t\) unguarded, Advance-date) maps to
its transaction or to a stutter, likewise by pre_t on the effective state. A Reduce of the state server consumes the first apply in flight and leaves the effective state unchanged: a stutter. A Reduce of a split,
drain, or state-advancing clause changes no component \(\sigma\) reads: a stutter. A Cold-call delivering a message maps to Communicate; a Communicate, an assignment on a channel, maps to a stutter. A responder
consumes its message from no inbox: \(\sigma\) retains every recorded message in \(i_p\), and CVA platform transactions do not remove messages from the inbox.
Correctness: let \(\rho\) be a proper correct run and suppose a CVA class in the domain of the equivalence is enabled in every configuration of a suffix of \(\sigma(\rho)\) with no member
taken. If the class is Communicate, the message stays on the output stream, the Cold-call class is enabled throughout, and the liveness of \(\rho\) takes it. If it is an unguarded platform transaction or Advance-date, its
precondition persists on the effective state, its perpetual goal’s Reduce class is enabled throughout, and the liveness of \(\rho\) takes a Reduce mapping to a member. If it is a volitional platform transaction, its
precondition and its willed class persist, so from some configuration on the corresponding request or responder goal holds a volition of the class: a request goal’s guard, requiring only its person inputs ground, succeeds on the willed inputs; a responder
goal’s guard reads the message and the state-stream head, and the state stream advancing whenever pre'_t fails yields a head on which it holds. Either way the volition-guarded reduction of the goal with its single volition-guarded clause
succeeds under the willed answer and, by Monotonicity (Proposition [prop:glp-monotonicity]), continues to succeed until the goal is reduced; the procedure
being simple, its volition-guarded clause single and first, Theorem [thm:simple-liveness] takes a Reduce fulfilling a willed volition, and pre_t
holding on the effective state, it maps to a member of the class. In every case a member is taken, against the hypothesis; hence \(\sigma(\rho)\) is correct.
The volition correspondence is the construction’s request and responder procedures (cases 2 and 4): every volitional platform transaction \(t\) is realised by the single volition-guarded clause of its own procedure — posing the empty question when its precondition reads the local state, posing the arrived message when it requires one — and, safety’s per-transition cases carrying no occurrence of \([t(\cdot)]\) on any other transition, the occurrences of its class in \(\sigma(\rho)\) are exactly the images of that clause’s volition-guarded reductions. ◻
The compilation replaces each volition-guarded clause of the canonical realisation \(M\) by ordinary clauses receiving the person’s granted terms, and adds the mediator. Per request procedure \(t\) its command is c_t(X1,...,Xk); per responder procedure \(t\) its answer is a_t(X1,...,Xk), granted by the person as
a_t(X1,...,Xk,ReqId); an offer offer(Q,R) pairs a responder’s question with a fresh answer writer, and a card card(Q,req(N)) carries the question to the person under a request identifier.
lookup consumes the pending entry of a request identifier (the deployed lookup_pending, Appendix B), and the body assignment := binds the escrowed writer.
Definition 47 (Canonical Compilation). Given the canonical realisation \(M\) of a CVA platform (Definition 45), its canonical compilation \(\lceil M\rceil\) is the GLP program consisting of the procedures of \(M\), with each volition-guarded clause compiled and all else unchanged, and the mediator:
Per request procedure \(t\) of \(M\), the compiled procedure
t([c_t(X1,...,Xk)|Cs], Us) :-
ground(X1?), ..., ground(Xk?) |
send(apply(t(X1?,...,Xk?)), Us?, Us1),
t(Cs?, Us1?).Per responder procedure \(t\) of \(M\), the compiled procedures — the forward clause, then the await procedure, its answer clause first and the state-advancing clause of \(M\) retained, last:
respond_t(m_t(Y1,...,Ym), Ss, Us, Med) :-
ground(Y1?), ..., ground(Ym?) |
send(offer(m_t(Y1?,...,Ym?), R), Med?, Med1),
await_t(m_t(Y1?,...,Ym?), R?, Ss?, Us?, Med1?).
await_t(m_t(Y1,...,Ym), a_t(X1,...,Xk), [S|Ss], Us, Med) :-
ground(X1?), ..., ground(Xk?),
pre_t(Y1?,...,Ym?, X1?,...,Xk?, S?) |
send(apply(t(Y1?,...,Ym?, X1?,...,Xk?)), Us?, Us1),
drain(Ss?, Us1?, Med?).
await_t(m_t(Y1,...,Ym), R, [S|Ss], Us, Med) :-
~pre'_t(Y1?,...,Ym?, S?) |
await_t(m_t(Y1?,...,Ym?), R?, Ss?, Us?, Med?).The mediator, between the person channel and the agent — the escrow clause, a routing clause per answer a_t, and a pass-through clause per command c_t:
med(UserCh, AgentCh, Ps, N) :-
receive(offer(Q, R?), AgentCh?, AgentCh1),
ground(Q?) |
send(card(Q?, req(N?)), UserCh?, UserCh1),
N1 := N? + 1,
med(UserCh1?, AgentCh1?,
[pending(req(N?), R)|Ps?], N1?).
med(UserCh, AgentCh, Ps, N) :-
receive(a_t(X1,...,Xk,ReqId), UserCh?, UserCh1),
ground(X1?), ..., ground(Xk?), ground(ReqId?) |
lookup(ReqId?, R, Ps?, Ps1),
R := a_t(X1?,...,Xk?),
med(UserCh1?, AgentCh?, Ps1?, N?).
med(UserCh, AgentCh, Ps, N) :-
receive(c_t(X1,...,Xk), UserCh?, UserCh1),
ground(X1?), ..., ground(Xk?) |
send(c_t(X1?,...,Xk?), AgentCh?, AgentCh1),
med(UserCh1?, AgentCh1?, Ps?, N?).The constructs: the manifest of \(M\) (Definition 34), its acts grants (Definition 36): the form of a request procedure \(t\) grants c_t(v1,...,vk) with the collected values; the card of an escrowed offer grants, per button, the
answer a_t(v1,...,vk,ReqId) of the chosen clause with the card’s identifier; cancel grants nothing.
The initial goal of \(\lceil M\rceil\) is that of \(M\) with each command routed to its procedure’s stream, each responder given its mediator channel, and the med goal,
on the empty pending table and counter \(0\), spliced between the person channel and the agent; the mediator’s person side is the designated person channel.
Definition 48 (Compilation Mapping). Given a configuration of GLP with a person over \(\lceil M\rceil\), the mapping \(\sigma\) yields the vcGLP\((M)\) configuration \((V, (G, \sigma_r))\) with:
\(G\) = the multiset of the agent’s goals, each read back to its source: a compiled request goal t(Cs,Us) as the source goal t(Us); a respond_t or await_t goal
as the source responder goal; the med, split, and drain goals contributing nothing;
\(V\) = \(\{(C, \theta, \theta')\}\) per command c_C(v1,...,vk) granted and not yet consumed by its request clause’s Reduce, with \(\theta\) the granted values and \(\theta'\) empty, together with \(\{(C, \theta, \theta')\}\) per answer granted on the card of an escrowed offer and not
yet consumed by its answer clause’s Reduce, with \(C\) the chosen responder clause, \(\theta\) the granted person inputs, and \(\theta'\) the context
read from the offer;
\(\sigma_r\) = the restriction of the accumulated readers substitution to the variables of the source goals.
Proof. \(\sigma\) maps the initial configuration to \((\emptyset, (G_0, \emptyset))\), the initial vcGLP\((M)\) configuration.
Safety, per transition of GLP with a person over \(\lceil M\rceil\): a grant of a command c_C(v1,...,vk) maps to the Change-Volition adding \((C, \theta, \theta')\); a
grant of an answer on the card of an escrowed offer maps to the Change-Volition adding \((C, \theta, \theta')\) of the chosen responder clause; both leave \(G\) and \(\sigma_r\) unchanged. A Reduce of a compiled request clause consuming a granted command maps to the vcGLP Reduce of the source request goal with \(C\): the compiled guard is the source guard on
the same values, the bodies coincide, and the consumed command’s volition, held in \(V\) by \(\sigma\), is fulfilled. A Reduce of an answer clause consuming a granted answer likewise maps to
the vcGLP Reduce of the source responder goal with \(C\), fulfilling its volition. A Reduce of a forward clause, of a mediator clause — escrow, routing, or pass-through — and a Communicate on the person or mediator channels
change no component \(\sigma\) reads: the source responder goal is read back unchanged whether its offer is unsent, escrowed, or displayed, and a granted command remains granted and unconsumed while it moves through the
mediator; each is a stutter. A Reduce of any other clause is a Reduce of \(M\)’s own ordinary clause and maps to itself; a Communicate within the agent maps to the vcGLP Communicate of the same assignment, or to a stutter
when the assigned reader occurs in no source goal.
Correctness: let \(\rho\) be a proper correct run of GLP with a person over \(\lceil M\rceil\) and suppose a vcGLP class in the domain of the equivalence is enabled in every configuration of a suffix of \(\sigma(\rho)\) with no member taken. A Communicate class, or a Reduce class of an ordinary clause, is enabled in the corresponding suffix of \(\rho\), whose liveness takes it, and its image is a member of the class. For a Reduce class of a source goal \(A\) with volition-guarded clause \(C\): enabledness throughout the suffix gives a volition \((C, \theta, \theta') \in V\) and the volition-guarded reduction under \(\theta\) succeeding throughout, so by \(\sigma\) some command or answer of \(C\) is granted and unconsumed throughout; the mediator’s pass-through or routing clause and the connecting Communicate transitions, taken in stream order by the liveness of \(\rho\), deliver the granted command or bind the escrowed answer writer, after which the Reduce class of the compiled goal with the compiled clause of \(C\) is enabled until taken — the compiled request procedure has one clause, the answer clause stands first in its await procedure, and the state-advancing clause’s guard, complementary to the precondition, fails while the precondition holds — and the liveness of \(\rho\) takes it. The taken Reduce maps to a member of the class. Hence \(\sigma(\rho)\) is correct. ◻