diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..5a47052 --- /dev/null +++ b/Readme.md @@ -0,0 +1,106 @@ + +## 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")) \ No newline at end of file