You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.5 KiB
Markdown

2 years ago
## 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).
2 years ago
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.
2 years ago
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"))