argumentation_schemes/catalog/
source.rs1use crate::catalog::SOURCE_ID_OFFSET;
6use crate::critical::CriticalQuestion;
7use crate::scheme::*;
8use crate::types::*;
9
10pub fn all() -> Vec<SchemeSpec> {
12 vec![
13 ad_hominem(),
14 ad_hominem_circumstantial(),
15 argument_from_bias(),
16 ethotic_argument(),
17 ]
18}
19
20pub fn ad_hominem() -> SchemeSpec {
24 SchemeSpec {
25 id: SchemeId(SOURCE_ID_OFFSET),
26 name: "Ad Hominem".into(),
27 category: SchemeCategory::SourceBased,
28 premises: vec![
29 PremiseSlot::new("target", "The person being attacked", SlotRole::Agent),
30 PremiseSlot::new("flaw", "The character flaw alleged", SlotRole::Property),
31 PremiseSlot::new(
32 "claim",
33 "The claim being challenged via the attack",
34 SlotRole::Proposition,
35 ),
36 ],
37 conclusion: ConclusionTemplate::negated(
38 "?claim should be rejected because ?target has ?flaw",
39 "?claim",
40 ),
41 critical_questions: vec![
42 CriticalQuestion::new(
43 1,
44 "Does ?target really have ?flaw?",
45 Challenge::PremiseTruth("flaw".into()),
46 ),
47 CriticalQuestion::new(
48 2,
49 "Does ?flaw actually bear on the credibility of ?claim?",
50 Challenge::Proportionality,
51 ),
52 CriticalQuestion::new(
53 3,
54 "Is the attack on ?target proportionate to ?flaw?",
55 Challenge::Proportionality,
56 ),
57 ],
58 metadata: SchemeMetadata {
59 citation: "Walton 2008 p.141".into(),
60 domain_tags: vec!["source".into(), "attack".into()],
61 presumptive: true,
62 strength: SchemeStrength::Weak,
63 },
64 }
65}
66
67pub fn ad_hominem_circumstantial() -> SchemeSpec {
71 SchemeSpec {
72 id: SchemeId(SOURCE_ID_OFFSET + 1),
73 name: "Ad Hominem Circumstantial".into(),
74 category: SchemeCategory::SourceBased,
75 premises: vec![
76 PremiseSlot::new(
77 "target",
78 "The person whose circumstances are cited",
79 SlotRole::Agent,
80 ),
81 PremiseSlot::new(
82 "inconsistency",
83 "How target's circumstances conflict with the claim",
84 SlotRole::Property,
85 ),
86 PremiseSlot::new("claim", "The claim being undermined", SlotRole::Proposition),
87 ],
88 conclusion: ConclusionTemplate::negated(
89 "?claim is undermined because ?target's circumstances (?inconsistency) are inconsistent with it",
90 "?claim",
91 ),
92 critical_questions: vec![
93 CriticalQuestion::new(
94 1,
95 "Does ?target actually have the alleged ?inconsistency?",
96 Challenge::PremiseTruth("inconsistency".into()),
97 ),
98 CriticalQuestion::new(
99 2,
100 "Is the inconsistency relevant to ?claim?",
101 Challenge::Proportionality,
102 ),
103 CriticalQuestion::new(
104 3,
105 "Could ?target's ?claim still be valid despite the inconsistency?",
106 Challenge::RuleValidity,
107 ),
108 ],
109 metadata: SchemeMetadata {
110 citation: "Walton 2008 p.143".into(),
111 domain_tags: vec!["source".into(), "attack".into(), "hypocrisy".into()],
112 presumptive: true,
113 strength: SchemeStrength::Weak,
114 },
115 }
116}
117
118pub fn argument_from_bias() -> SchemeSpec {
122 SchemeSpec {
123 id: SchemeId(SOURCE_ID_OFFSET + 2),
124 name: "Argument from Bias".into(),
125 category: SchemeCategory::SourceBased,
126 premises: vec![
127 PremiseSlot::new("source", "The biased source", SlotRole::Agent),
128 PremiseSlot::new("bias", "The alleged bias", SlotRole::Property),
129 PremiseSlot::new(
130 "claim",
131 "The claim made by the biased source",
132 SlotRole::Proposition,
133 ),
134 ],
135 conclusion: ConclusionTemplate::negated(
136 "?claim should be treated with suspicion because ?source has ?bias",
137 "?claim",
138 ),
139 critical_questions: vec![
140 CriticalQuestion::new(
141 1,
142 "Does ?source actually have the alleged ?bias?",
143 Challenge::PremiseTruth("bias".into()),
144 ),
145 CriticalQuestion::new(
146 2,
147 "Does ?bias actually affect ?source's assertion of ?claim?",
148 Challenge::RuleValidity,
149 ),
150 CriticalQuestion::new(
151 3,
152 "Even if ?source is biased, might ?claim still be true?",
153 Challenge::AlternativeCause,
154 ),
155 ],
156 metadata: SchemeMetadata {
157 citation: "Walton 2008 p.340".into(),
158 domain_tags: vec!["source".into(), "attack".into()],
159 presumptive: true,
160 strength: SchemeStrength::Weak,
161 },
162 }
163}
164
165pub fn ethotic_argument() -> SchemeSpec {
167 SchemeSpec {
168 id: SchemeId(SOURCE_ID_OFFSET + 3),
169 name: "Ethotic Argument".into(),
170 category: SchemeCategory::SourceBased,
171 premises: vec![
172 PremiseSlot::new(
173 "person",
174 "The person whose character is cited",
175 SlotRole::Agent,
176 ),
177 PremiseSlot::new(
178 "good_character",
179 "The positive character trait",
180 SlotRole::Property,
181 ),
182 PremiseSlot::new(
183 "claim",
184 "The claim bolstered by good character",
185 SlotRole::Proposition,
186 ),
187 ],
188 conclusion: ConclusionTemplate::positive(
189 "?claim is more plausible because ?person has ?good_character",
190 "?claim",
191 ),
192 critical_questions: vec![
193 CriticalQuestion::new(
194 1,
195 "Does ?person actually have ?good_character?",
196 Challenge::PremiseTruth("good_character".into()),
197 ),
198 CriticalQuestion::new(
199 2,
200 "Does ?good_character make ?claim more plausible?",
201 Challenge::RuleValidity,
202 ),
203 ],
204 metadata: SchemeMetadata {
205 citation: "Walton 2008 p.146".into(),
206 domain_tags: vec!["source".into(), "support".into()],
207 presumptive: true,
208 strength: SchemeStrength::Weak,
209 },
210 }
211}
212
213#[cfg(test)]
214mod tests {
215 use super::*;
216
217 #[test]
218 fn all_returns_four_source_schemes() {
219 assert_eq!(all().len(), 4);
220 }
221
222 #[test]
223 fn ad_hominem_has_negated_conclusion() {
224 assert!(
225 ad_hominem().conclusion.is_negated,
226 "ad hominem must conclude ¬claim"
227 );
228 }
229
230 #[test]
231 fn ad_hominem_circumstantial_has_negated_conclusion() {
232 assert!(ad_hominem_circumstantial().conclusion.is_negated);
233 }
234
235 #[test]
236 fn bias_has_negated_conclusion() {
237 assert!(argument_from_bias().conclusion.is_negated);
238 }
239
240 #[test]
241 fn ethotic_has_positive_conclusion() {
242 assert!(!ethotic_argument().conclusion.is_negated);
243 }
244
245 #[test]
246 fn source_ids_are_in_offset_range() {
247 for s in all() {
248 assert!(s.id.0 >= SOURCE_ID_OFFSET);
249 assert!(s.id.0 < SOURCE_ID_OFFSET + 100);
250 }
251 }
252}