|
|
|
|
|
|
|
## Deliberate: A deliberation and voting module for goblins
|
|
|
|
|
|
|
|
This module provides deliberation tools for the
|
|
|
|
[Guile](https://www.gnu.org/software/guile/) scheme version of
|
|
|
|
[Goblins](https://spritely.institute/goblins/).
|
|
|
|
The module uses the standard terminology and methods of
|
|
|
|
[social choice theory](https://en.wikipedia.org/wiki/Social_choice_theory).
|
|
|
|
Currently, this module provides ranked-chioce ballots and two ranked-choice
|
|
|
|
voting systems:
|
|
|
|
[Instant-Runoff Voting](https://en.wikipedia.org/wiki/Instant-runoff_voting),
|
|
|
|
and the
|
|
|
|
[Borda count](https://en.wikipedia.org/wiki/Borda_count) method.
|
|
|
|
These features should be considered experimental.
|
|
|
|
|
|
|
|
## Using Deliberate
|
|
|
|
First, download the repository to a location in the Guile load path,
|
|
|
|
then the module may be imported as usual:
|
|
|
|
|
|
|
|
(use-modules (deliberate))
|
|
|
|
|
|
|
|
Note that code must be run in a goblins vat:
|
|
|
|
|
|
|
|
(use-modules (goblins)
|
|
|
|
(goblins vrun))
|
|
|
|
|
|
|
|
(define a-vat (spawn-vat))
|
|
|
|
(define-vat-run a-run a-vat)
|
|
|
|
|
|
|
|
### Creating a deliberation
|
|
|
|
A deliberation provides discussion and voting related to a particular topic.
|
|
|
|
To create a deliberation, spawn a `^deliberation` object and pass it the topic:
|
|
|
|
|
|
|
|
(define deliberation (a-run
|
|
|
|
(spawn ^deliberation "Power Generator"))
|
|
|
|
|
|
|
|
The topic can be read and set using the `topic` and `set-topic` message:
|
|
|
|
|
|
|
|
(a-run ($ deliberation 'topic))
|
|
|
|
;; => "Power Generator
|
|
|
|
|
|
|
|
(a-run ($ deliberation 'set-topic "Infrastructure"))
|
|
|
|
(a-run ($ deliberation 'topic))
|
|
|
|
;; => "Infrastructure
|
|
|
|
|
|
|
|
### Adding a vote
|
|
|
|
Each deliberation object may contain multiple votes. Votes are added with the
|
|
|
|
`add-vote` message with a question to be voted on:
|
|
|
|
|
|
|
|
(define vote (a-run
|
|
|
|
($ deliberation 'add-vote "What type of power should we use?"))
|
|
|
|
|
|
|
|
For it to be useful, the vote also needs a number of alternatives that can be
|
|
|
|
voted on:
|
|
|
|
|
|
|
|
(a-run
|
|
|
|
($ vote 'add-alternative "solar")
|
|
|
|
($ vote 'add-alternative "wind")
|
|
|
|
($ vote 'add-alternative "hydro"))
|
|
|
|
|
|
|
|
The list of votes can be fetched with the `votes` message.
|
|
|
|
|
|
|
|
### Creating ballots
|
|
|
|
Once a vote object has been created, ballot objects can be created and
|
|
|
|
distributed:
|
|
|
|
|
|
|
|
(define alice-ballot (a-run ($ vote 'add-ballot)))
|
|
|
|
|
|
|
|
### Using a ballot to vote
|
|
|
|
The question and alternatives can be fetched using the `question` and
|
|
|
|
`alternatives` messages:
|
|
|
|
|
|
|
|
(a-run ($ alice-ballot 'question))
|
|
|
|
;; "What type of power should we use?
|
|
|
|
|
|
|
|
(a-run ($ alice-ballot 'alternatives))
|
|
|
|
;; ("hydro" "wind" "solar")
|
|
|
|
|
|
|
|
Votes are cast by passing a function that maps alternatives to their rank
|
|
|
|
(with 1 being the highest):
|
|
|
|
|
|
|
|
(define (cast-vote alts)
|
|
|
|
(map (lambda (alt)
|
|
|
|
(cond
|
|
|
|
((string=? "wind" alt) 1)
|
|
|
|
((string=? "solar" alt) 2)
|
|
|
|
((string=? "hydro" alt) 3)))
|
|
|
|
alts))
|
|
|
|
(a-run ($ alice-ballot 'update-vote cast-vote))
|
|
|
|
|
|
|
|
While this interface may seem cumbersome, it ensures consistency between the
|
|
|
|
available alternatives and those being voted on. Votes can be checked using
|
|
|
|
the `ranking` message:
|
|
|
|
|
|
|
|
(a-run ($ alice-ballot 'ranking))
|
|
|
|
;; => ("solar" "wind" "hydro")
|
|
|
|
|
|
|
|
### Calculating winners
|
|
|
|
Vote winners can be calculated using `irv-winner` or `borda-winner`:
|
|
|
|
|
|
|
|
(a-run ($ vote 'irv-winner))
|
|
|
|
;; => ("wind")
|
|
|
|
|
|
|
|
Note that these messages return a list which may include multiple alternatives
|
|
|
|
in the case of a tie.
|
|
|
|
|
|
|
|
An overall social preference ranking can also be calculated using
|
|
|
|
`irv-preference` and `borda-preference`:
|
|
|
|
|
|
|
|
(a-run ($ vote 'borda-preference))
|
|
|
|
;; => (("wind") ("solar") ("hydro"))
|