1use crate::catalog::PRACTICAL_ID_OFFSET;
6use crate::critical::CriticalQuestion;
7use crate::scheme::*;
8use crate::types::*;
9
10pub fn all() -> Vec<SchemeSpec> {
12 vec![
13 argument_from_positive_consequences(),
14 argument_from_negative_consequences(),
15 argument_from_values(),
16 argument_from_threat(),
17 argument_from_fear_appeal(),
18 argument_from_waste(),
19 argument_from_sunk_cost(),
20 ]
21}
22
23pub fn argument_from_positive_consequences() -> SchemeSpec {
28 SchemeSpec {
29 id: SchemeId(PRACTICAL_ID_OFFSET),
30 name: "Argument from Positive Consequences".into(),
31 category: SchemeCategory::Practical,
32 premises: vec![
33 PremiseSlot::new("action", "The action being proposed", SlotRole::Action),
34 PremiseSlot::new(
35 "good_consequence",
36 "The beneficial outcome",
37 SlotRole::Consequence,
38 ),
39 ],
40 conclusion: ConclusionTemplate::positive(
41 "?action should be brought about because ?good_consequence will result",
42 "do_?action",
43 ),
44 critical_questions: vec![
45 CriticalQuestion::new(
46 1,
47 "Will ?action actually lead to ?good_consequence?",
48 Challenge::RuleValidity,
49 ),
50 CriticalQuestion::new(
51 2,
52 "Is ?good_consequence actually good on balance?",
53 Challenge::PremiseTruth("good_consequence".into()),
54 ),
55 CriticalQuestion::new(
56 3,
57 "Are there negative consequences that offset ?good_consequence?",
58 Challenge::UnseenConsequences,
59 ),
60 ],
61 metadata: SchemeMetadata {
62 citation: "Walton 2008 p.332".into(),
63 domain_tags: vec!["practical".into(), "consequences".into()],
64 presumptive: true,
65 strength: SchemeStrength::Moderate,
66 },
67 }
68}
69
70pub fn argument_from_negative_consequences() -> SchemeSpec {
74 SchemeSpec {
75 id: SchemeId(PRACTICAL_ID_OFFSET + 1),
76 name: "Argument from Negative Consequences".into(),
77 category: SchemeCategory::Practical,
78 premises: vec![
79 PremiseSlot::new(
80 "action",
81 "The action being warned against",
82 SlotRole::Action,
83 ),
84 PremiseSlot::new(
85 "bad_consequence",
86 "The harmful outcome",
87 SlotRole::Consequence,
88 ),
89 ],
90 conclusion: ConclusionTemplate::negated(
91 "?action should not be brought about because ?bad_consequence will result",
92 "do_?action",
93 ),
94 critical_questions: vec![
95 CriticalQuestion::new(
96 1,
97 "Will ?action actually lead to ?bad_consequence?",
98 Challenge::RuleValidity,
99 ),
100 CriticalQuestion::new(
101 2,
102 "Is ?bad_consequence actually bad on balance?",
103 Challenge::PremiseTruth("bad_consequence".into()),
104 ),
105 CriticalQuestion::new(
106 3,
107 "Are there positive consequences that offset ?bad_consequence?",
108 Challenge::UnseenConsequences,
109 ),
110 ],
111 metadata: SchemeMetadata {
112 citation: "Walton 2008 p.333".into(),
113 domain_tags: vec!["practical".into(), "consequences".into()],
114 presumptive: true,
115 strength: SchemeStrength::Moderate,
116 },
117 }
118}
119
120pub fn argument_from_values() -> SchemeSpec {
122 SchemeSpec {
123 id: SchemeId(PRACTICAL_ID_OFFSET + 2),
124 name: "Argument from Values".into(),
125 category: SchemeCategory::Practical,
126 premises: vec![
127 PremiseSlot::new("action", "The action being evaluated", SlotRole::Action),
128 PremiseSlot::new("value", "The value being promoted", SlotRole::Property),
129 PremiseSlot::new(
130 "agent",
131 "The agent whose values are at stake",
132 SlotRole::Agent,
133 ),
134 ],
135 conclusion: ConclusionTemplate::positive(
136 "?action should be carried out because it promotes ?value for ?agent",
137 "do_?action",
138 ),
139 critical_questions: vec![
140 CriticalQuestion::new(
141 1,
142 "Does ?action really promote ?value?",
143 Challenge::RuleValidity,
144 ),
145 CriticalQuestion::new(
146 2,
147 "Is ?value relevant to the current context?",
148 Challenge::PremiseTruth("value".into()),
149 ),
150 CriticalQuestion::new(
151 3,
152 "Are there competing values that take precedence over ?value?",
153 Challenge::UnseenConsequences,
154 ),
155 ],
156 metadata: SchemeMetadata {
157 citation: "Walton 2008 p.321".into(),
158 domain_tags: vec!["practical".into(), "values".into()],
159 presumptive: true,
160 strength: SchemeStrength::Moderate,
161 },
162 }
163}
164
165pub fn argument_from_threat() -> SchemeSpec {
171 SchemeSpec {
172 id: SchemeId(PRACTICAL_ID_OFFSET + 3),
173 name: "Argument from Threat".into(),
174 category: SchemeCategory::Practical,
175 premises: vec![
176 PremiseSlot::new(
177 "threatener",
178 "The person making the threat",
179 SlotRole::Agent,
180 ),
181 PremiseSlot::new(
182 "threat",
183 "The bad thing that will happen",
184 SlotRole::Consequence,
185 ),
186 PremiseSlot::new("demand", "The action being demanded", SlotRole::Action),
187 ],
188 conclusion: ConclusionTemplate::positive(
189 "?demand should be complied with to avoid ?threat",
190 "comply_?demand",
191 ),
192 critical_questions: vec![
193 CriticalQuestion::new(
194 1,
195 "Does ?threatener have the ability to carry out ?threat?",
196 Challenge::PremiseTruth("threatener".into()),
197 ),
198 CriticalQuestion::new(
199 2,
200 "Is ?threat proportionate to ?demand?",
201 Challenge::Proportionality,
202 ),
203 CriticalQuestion::new(
204 3,
205 "Is there an alternative to complying with ?demand?",
206 Challenge::AlternativeCause,
207 ),
208 ],
209 metadata: SchemeMetadata {
210 citation: "Walton 2008 p.335".into(),
211 domain_tags: vec!["practical".into(), "coercion".into()],
212 presumptive: true,
213 strength: SchemeStrength::Weak,
214 },
215 }
216}
217
218pub fn argument_from_fear_appeal() -> SchemeSpec {
220 SchemeSpec {
221 id: SchemeId(PRACTICAL_ID_OFFSET + 4),
222 name: "Argument from Fear Appeal".into(),
223 category: SchemeCategory::Practical,
224 premises: vec![
225 PremiseSlot::new("action", "The recommended action", SlotRole::Action),
226 PremiseSlot::new(
227 "fearful_outcome",
228 "The feared consequence of inaction",
229 SlotRole::Consequence,
230 ),
231 ],
232 conclusion: ConclusionTemplate::positive(
233 "?action should be taken to avoid ?fearful_outcome",
234 "do_?action",
235 ),
236 critical_questions: vec![
237 CriticalQuestion::new(
238 1,
239 "Is ?fearful_outcome truly likely if ?action is not taken?",
240 Challenge::RuleValidity,
241 ),
242 CriticalQuestion::new(
243 2,
244 "Is the fear of ?fearful_outcome proportionate to the actual risk?",
245 Challenge::Proportionality,
246 ),
247 CriticalQuestion::new(
248 3,
249 "Is ?action the only way to avoid ?fearful_outcome?",
250 Challenge::AlternativeCause,
251 ),
252 ],
253 metadata: SchemeMetadata {
254 citation: "Walton 2008 p.336".into(),
255 domain_tags: vec!["practical".into(), "emotion".into()],
256 presumptive: true,
257 strength: SchemeStrength::Weak,
258 },
259 }
260}
261
262pub fn argument_from_waste() -> SchemeSpec {
264 SchemeSpec {
265 id: SchemeId(PRACTICAL_ID_OFFSET + 5),
266 name: "Argument from Waste".into(),
267 category: SchemeCategory::Practical,
268 premises: vec![
269 PremiseSlot::new("action", "The action already started", SlotRole::Action),
270 PremiseSlot::new(
271 "investment",
272 "What has been invested so far",
273 SlotRole::Property,
274 ),
275 ],
276 conclusion: ConclusionTemplate::positive(
277 "?action should be continued to avoid wasting ?investment",
278 "continue_?action",
279 ),
280 critical_questions: vec![
281 CriticalQuestion::new(
282 1,
283 "How much has actually been invested in ?action?",
284 Challenge::PremiseTruth("investment".into()),
285 ),
286 CriticalQuestion::new(
287 2,
288 "Would continuing ?action actually recoup ?investment?",
289 Challenge::RuleValidity,
290 ),
291 ],
292 metadata: SchemeMetadata {
293 citation: "Walton 2008 p.339".into(),
294 domain_tags: vec!["practical".into(), "sunk_cost".into()],
295 presumptive: true,
296 strength: SchemeStrength::Weak,
297 },
298 }
299}
300
301pub fn argument_from_sunk_cost() -> SchemeSpec {
304 SchemeSpec {
305 id: SchemeId(PRACTICAL_ID_OFFSET + 6),
306 name: "Argument from Sunk Cost".into(),
307 category: SchemeCategory::Practical,
308 premises: vec![
309 PremiseSlot::new("action", "The committed action", SlotRole::Action),
310 PremiseSlot::new(
311 "commitment",
312 "The prior commitment that locks the agent in",
313 SlotRole::Property,
314 ),
315 ],
316 conclusion: ConclusionTemplate::positive(
317 "?action should be continued to honour ?commitment",
318 "continue_?action",
319 ),
320 critical_questions: vec![
321 CriticalQuestion::new(
322 1,
323 "Is ?commitment still binding given current circumstances?",
324 Challenge::PremiseTruth("commitment".into()),
325 ),
326 CriticalQuestion::new(
327 2,
328 "Does honouring ?commitment actually require continuing ?action?",
329 Challenge::RuleValidity,
330 ),
331 ],
332 metadata: SchemeMetadata {
333 citation: "Walton 2008 p.340".into(),
334 domain_tags: vec!["practical".into(), "sunk_cost".into()],
335 presumptive: true,
336 strength: SchemeStrength::Weak,
337 },
338 }
339}
340
341#[cfg(test)]
342mod tests {
343 use super::*;
344
345 #[test]
346 fn all_returns_seven_practical_schemes() {
347 let schemes = all();
348 assert_eq!(schemes.len(), 7);
349 assert!(
350 schemes
351 .iter()
352 .all(|s| s.category == SchemeCategory::Practical)
353 );
354 }
355
356 #[test]
357 fn negative_consequences_has_negated_conclusion() {
358 assert!(argument_from_negative_consequences().conclusion.is_negated);
359 }
360
361 #[test]
362 fn positive_consequences_has_non_negated_conclusion() {
363 assert!(!argument_from_positive_consequences().conclusion.is_negated);
364 }
365
366 #[test]
367 fn threat_scheme_has_three_premises() {
368 assert_eq!(argument_from_threat().premises.len(), 3);
369 }
370
371 #[test]
372 fn practical_ids_are_in_offset_range() {
373 for s in all() {
374 assert!(s.id.0 >= PRACTICAL_ID_OFFSET);
375 assert!(s.id.0 < PRACTICAL_ID_OFFSET + 100);
376 }
377 }
378}