From ba3db2626300a9d7ddc5d93d94621526bb63c9f1 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Sun, 27 Jun 2021 22:24:25 +1000 Subject: [PATCH] Describe use of constraints in lead-in text --- html/index.js | 1 + src/constraints.rs | 4 ++-- src/main.rs | 1 + src/stv/mod.rs | 25 ++++++++++++++++++++++++- src/stv/wasm.rs | 2 ++ tests/aec.rs | 1 + tests/csm.rs | 1 + tests/ers97.rs | 1 + tests/meek.rs | 3 +++ tests/prsa.rs | 1 + tests/scotland.rs | 2 ++ 11 files changed, 39 insertions(+), 3 deletions(-) diff --git a/html/index.js b/html/index.js index 33129fd..d36c505 100644 --- a/html/index.js +++ b/html/index.js @@ -130,6 +130,7 @@ async function clickCount() { document.getElementById('chkBulkExclusion').checked, document.getElementById('chkDeferSurpluses').checked, document.getElementById('chkMeekImmediateElect').checked, + conPath, "guard_doom", parseInt(document.getElementById('txtPPDP').value), ]; diff --git a/src/constraints.rs b/src/constraints.rs index 93f48aa..49e7432 100644 --- a/src/constraints.rs +++ b/src/constraints.rs @@ -201,7 +201,7 @@ impl ConstraintMatrix { // NB: Bounds on min, max, etc. will be further refined in initial step() calls } - /// Update cands/elected in innermost cells based on the provided [CountState::candidates] + /// Update cands/elected in innermost cells based on the provided [CountState::candidates](crate::election::CountState::candidates) pub fn update_from_state(&mut self, election: &Election, candidates: &HashMap<&Candidate, CountCard>) { let constraints = election.constraints.as_ref().unwrap(); @@ -239,7 +239,7 @@ impl ConstraintMatrix { } } - /// Recompute [self::cands] and [self::elected] for totals cells based on the innermost cells + /// Recompute [cands](ConstraintMatrixCell::cands) and [elected](ConstraintMatrixCell::elected) for totals cells based on the innermost cells pub fn recount_cands(&mut self) { let shape = Vec::from(self.0.shape()); diff --git a/src/main.rs b/src/main.rs index 6cabb3c..89242c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -256,6 +256,7 @@ where cmd_opts.bulk_exclude, cmd_opts.defer_surpluses, cmd_opts.meek_immediate_elect, + cmd_opts.constraints.as_deref(), &cmd_opts.constraint_mode, cmd_opts.pp_decimals, ); diff --git a/src/stv/mod.rs b/src/stv/mod.rs index 0a5f2fe..1971f6b 100644 --- a/src/stv/mod.rs +++ b/src/stv/mod.rs @@ -52,7 +52,7 @@ pub struct STVOptions { pub sum_surplus_transfers: SumSurplusTransfersMode, /// (Meek STV) Limit for stopping iteration of surplus distribution pub meek_surplus_tolerance: String, - /// Convert ballots with value >1 to multiple ballots of value 1 + /// Convert ballots with value >1 to multiple ballots of value 1 (used only for [STVOptions::describe]) pub normalise_ballots: bool, /// Quota type pub quota: QuotaType, @@ -80,6 +80,8 @@ pub struct STVOptions { pub defer_surpluses: bool, /// (Meek STV) Immediately elect candidates even if keep values have not converged pub meek_immediate_elect: bool, + /// Path to constraints file (used only for [STVOptions::describe]) + pub constraints_path: Option, /// Mode of handling constraints pub constraint_mode: ConstraintMode, /// Print votes to specified decimal places in results report @@ -110,6 +112,7 @@ impl STVOptions { bulk_exclude: bool, defer_surpluses: bool, meek_immediate_elect: bool, + constraints_path: Option<&str>, constraint_mode: &str, pp_decimals: usize, ) -> Self { @@ -175,6 +178,10 @@ impl STVOptions { bulk_exclude, defer_surpluses, meek_immediate_elect, + constraints_path: match constraints_path { + Some(p) => Some(p.to_string()), + None => None, + }, constraint_mode: match constraint_mode { "guard_doom" => ConstraintMode::GuardDoom, "rollback" => ConstraintMode::Rollback, @@ -210,6 +217,10 @@ impl STVOptions { if self.bulk_exclude { flags.push("--bulk-exclude".to_string()); } if self.defer_surpluses { flags.push("--defer-surpluses".to_string()); } if self.surplus == SurplusMethod::Meek && self.meek_immediate_elect { flags.push("--meek-immediate-elect".to_string()); } + if let Some(path) = &self.constraints_path { + flags.push(format!("--constraints {}", path)); + if self.constraint_mode != ConstraintMode::GuardDoom { flags.push(self.constraint_mode.describe()); } + } if self.pp_decimals != 2 { flags.push(format!("--pp-decimals {}", self.pp_decimals)); } return flags.join(" "); } @@ -392,6 +403,8 @@ impl ExclusionMethod { } /// Enum of options for [STVOptions::constraint_mode] +#[derive(Clone, Copy)] +#[derive(PartialEq)] pub enum ConstraintMode { /// Guard or doom candidates as soon as required to secure a conformant result GuardDoom, @@ -399,6 +412,16 @@ pub enum ConstraintMode { Rollback, } +impl ConstraintMode { + /// Convert to CLI argument representation + fn describe(self) -> String { + match self { + ConstraintMode::GuardDoom => "--constraint-mode guard_doom", + ConstraintMode::Rollback => "--constraint-mode rollback", + }.to_string() + } +} + /// An error during the STV count #[wasm_bindgen] #[derive(Debug)] diff --git a/src/stv/wasm.rs b/src/stv/wasm.rs index a7ef5d4..859beb8 100644 --- a/src/stv/wasm.rs +++ b/src/stv/wasm.rs @@ -212,6 +212,7 @@ impl STVOptions { bulk_exclude: bool, defer_surpluses: bool, meek_immediate_elect: bool, + constraints_path: Option, constraint_mode: &str, pp_decimals: usize, ) -> Self { @@ -237,6 +238,7 @@ impl STVOptions { bulk_exclude, defer_surpluses, meek_immediate_elect, + constraints_path.as_deref(), constraint_mode, pp_decimals, )) diff --git a/tests/aec.rs b/tests/aec.rs index 12f7c96..dade895 100644 --- a/tests/aec.rs +++ b/tests/aec.rs @@ -75,6 +75,7 @@ fn aec_tas19_rational() { bulk_exclude: true, defer_surpluses: false, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; diff --git a/tests/csm.rs b/tests/csm.rs index 1cafde9..cbe0143 100644 --- a/tests/csm.rs +++ b/tests/csm.rs @@ -43,6 +43,7 @@ fn csm15_float64() { bulk_exclude: true, defer_surpluses: false, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; diff --git a/tests/ers97.rs b/tests/ers97.rs index 1f10cc7..e5c6913 100644 --- a/tests/ers97.rs +++ b/tests/ers97.rs @@ -43,6 +43,7 @@ fn ers97_rational() { bulk_exclude: true, defer_surpluses: true, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; diff --git a/tests/meek.rs b/tests/meek.rs index aeca4be..083db3a 100644 --- a/tests/meek.rs +++ b/tests/meek.rs @@ -48,6 +48,7 @@ fn meek87_ers97_float64() { bulk_exclude: false, defer_surpluses: false, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; @@ -78,6 +79,7 @@ fn meek06_ers97_fixed12() { bulk_exclude: false, defer_surpluses: true, meek_immediate_elect: true, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; @@ -153,6 +155,7 @@ fn meeknz_ers97_fixed12() { bulk_exclude: false, defer_surpluses: true, meek_immediate_elect: true, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; diff --git a/tests/prsa.rs b/tests/prsa.rs index 868a684..e9a861b 100644 --- a/tests/prsa.rs +++ b/tests/prsa.rs @@ -43,6 +43,7 @@ fn prsa1_rational() { bulk_exclude: false, defer_surpluses: false, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 2, }; diff --git a/tests/scotland.rs b/tests/scotland.rs index bb10703..1542c56 100644 --- a/tests/scotland.rs +++ b/tests/scotland.rs @@ -50,6 +50,7 @@ fn scotland_linn07_fixed5() { bulk_exclude: false, defer_surpluses: false, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 5, }; @@ -80,6 +81,7 @@ fn scotland_linn07_gfixed5() { bulk_exclude: false, defer_surpluses: false, meek_immediate_elect: false, + constraints_path: None, constraint_mode: stv::ConstraintMode::GuardDoom, pp_decimals: 5, };