Edward L Platt c2f20ff92d | 2 years ago | |
---|---|---|
deliberate | 2 years ago | |
tests | 2 years ago | |
.gitignore | 2 years ago | |
COPYING | 2 years ago | |
Readme.md | 2 years ago | |
deliberate.scm | 2 years ago |
Readme.md
Deliberate: A deliberation and voting module for goblins
This module provides deliberation tools for the Guile scheme version of Goblins. The module uses the standard terminology and methods of social choice theory. Currently, this module provides ranked-chioce ballots and two ranked-choice voting systems: Instant-Runoff Voting, and the 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))
;; => ("wind" "solar" "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"))