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.

3.2 KiB

Deliberate: A deliberation and voting module for goblins

This module provides deliberation tools for the Guile scheme version of Goblins. 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))
;; => ("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"))