Deliberation and voting system built in guile scheme with spritely goblins.
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.
Edward L Platt c2f20ff92d Formatting and output fixes. 2 years ago
deliberate Add method to ^ranked-preference to return list of alternatives. 2 years ago
tests Change deliberation title method to topic. 2 years ago
.gitignore Add test logs to gitignore. 2 years ago
COPYING Initial commit. 2 years ago Formatting and output fixes. 2 years ago
deliberate.scm Change deliberation title method to topic. 2 years ago

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:

    ($ 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)
            ((string=? "wind" alt) 1)
            ((string=? "solar" alt) 2)
            ((string=? "hydro" alt) 3)))
(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"))