## 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/). 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"))