1use super::*;
2use crate::parser::{Position, RlError};
3use std::collections::HashMap;
4
5#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
6pub struct SkillId(pub usize);
7impl Id for SkillId {
8 fn index(&self) -> usize {
9 self.0
10 }
11}
12
13#[derive(Debug, Clone)]
14pub struct Skill {
15 id: SkillId,
16 name: String,
17 inputs: Vec<Variable>,
18 outputs: Vec<Variable>,
19 preconditions: Vec<Precondition>,
20 start: Vec<Effect>,
21 invariants: Vec<Invariant>,
22 progress: Option<Progress>,
23 interrupt: Option<Interrupt>,
24 successes: Vec<Success>,
25 failures: Vec<Failure>,
26 position: Option<Position>,
27}
28
29impl Skill {
30 pub fn new<S: Into<String>>(name: S, position: Option<Position>) -> Self {
31 let id = SkillId::default();
32 let name = name.into();
33 Self {
34 id,
35 name,
36 inputs: Vec::new(),
37 outputs: Vec::new(),
38 preconditions: Vec::new(),
39 start: Vec::new(),
40 invariants: Vec::new(),
41 progress: None,
42 interrupt: None,
43 successes: Vec::new(),
44 failures: Vec::new(),
45 position,
46 }
47 }
48
49 pub fn inputs(&self) -> &Vec<Variable> {
52 &self.inputs
53 }
54
55 pub fn add_input(&mut self, input: Variable) {
56 self.inputs.push(input);
57 }
58
59 pub fn outputs(&self) -> &Vec<Variable> {
62 &self.outputs
63 }
64
65 pub fn add_output(&mut self, output: Variable) {
66 self.outputs.push(output);
67 }
68
69 pub fn preconditions(&self) -> &Vec<Precondition> {
72 &self.preconditions
73 }
74
75 pub fn add_precondition(&mut self, mut precondition: Precondition) -> PreconditionId {
76 let id = PreconditionId(self.id, self.preconditions.len());
77 precondition.set_id(id);
78 self.preconditions.push(precondition);
79 id
80 }
81
82 pub fn get_precondition(&self, id: PreconditionId) -> Option<&Precondition> {
83 let PreconditionId(skill_id, n) = id;
84 if self.id != skill_id {
85 None
86 } else {
87 self.preconditions.get(n)
88 }
89 }
90
91 pub fn start(&self) -> &Vec<Effect> {
94 &self.start
95 }
96
97 pub fn set_start(&mut self, effects: Vec<Effect>) {
98 self.start = effects;
99 }
100
101 pub fn invariants(&self) -> &Vec<Invariant> {
104 &self.invariants
105 }
106
107 pub fn add_invariant(&mut self, mut invariant: Invariant) -> InvariantId {
108 let id = InvariantId(self.id, self.invariants.len());
109 invariant.set_id(id);
110 self.invariants.push(invariant);
111 id
112 }
113
114 pub fn get_invariant(&self, id: InvariantId) -> Option<&Invariant> {
115 let InvariantId(skill_id, n) = id;
116 if self.id != skill_id {
117 None
118 } else {
119 self.invariants.get(n)
120 }
121 }
122
123 pub fn progress(&self) -> &Option<Progress> {
126 &self.progress
127 }
128
129 pub fn set_progress(&mut self, progress: Progress) {
130 self.progress = Some(progress)
131 }
132
133 pub fn interrupt(&self) -> &Option<Interrupt> {
136 &self.interrupt
137 }
138
139 pub fn set_interrupt(&mut self, interrupt: Interrupt) {
140 self.interrupt = Some(interrupt);
141 }
142
143 pub fn successes(&self) -> &Vec<Success> {
146 &self.successes
147 }
148
149 pub fn add_success(&mut self, mut success: Success) -> SuccessId {
150 let id = SuccessId(self.id, self.successes.len());
151 success.set_id(id);
152 self.successes.push(success);
153 id
154 }
155
156 pub fn get_success(&self, id: SuccessId) -> Option<&Success> {
157 let SuccessId(skill_id, n) = id;
158 if self.id != skill_id {
159 None
160 } else {
161 self.successes.get(n)
162 }
163 }
164
165 pub fn failures(&self) -> &Vec<Failure> {
168 &self.failures
169 }
170
171 pub fn add_failure(&mut self, mut failure: Failure) -> FailureId {
172 let id = FailureId(self.id, self.failures.len());
173 failure.set_id(id);
174 self.failures.push(failure);
175 id
176 }
177
178 pub fn get_failure(&self, id: FailureId) -> Option<&Failure> {
179 let FailureId(skill_id, n) = id;
180 if self.id != skill_id {
181 None
182 } else {
183 self.failures.get(n)
184 }
185 }
186
187 pub fn input_naming(&self) -> Vec<Naming> {
190 self.inputs
191 .iter()
192 .map(|x| (x.name().into(), x.position()))
193 .collect()
194 }
195 pub fn output_naming(&self) -> Vec<Naming> {
196 self.outputs
197 .iter()
198 .map(|x| (x.name().into(), x.position()))
199 .collect()
200 }
201 pub fn precondition_naming(&self) -> Vec<Naming> {
202 self.preconditions.iter().map(|x| x.naming()).collect()
203 }
204 pub fn invariant_naming(&self) -> Vec<Naming> {
205 self.invariants.iter().map(|x| x.naming()).collect()
206 }
207 pub fn success_naming(&self) -> Vec<Naming> {
208 self.successes.iter().map(|x| x.naming()).collect()
209 }
210 pub fn failure_naming(&self) -> Vec<Naming> {
211 self.failures.iter().map(|x| x.naming()).collect()
212 }
213
214 pub fn duplicate(&self, skillset: &Skillset) -> Result<(), RlError> {
215 let types = skillset.type_naming();
216
217 check_duplicate(
219 types
220 .clone()
221 .into_iter()
222 .chain(self.input_naming().into_iter())
223 .collect(),
224 )?;
225 check_duplicate(
227 types
228 .clone()
229 .into_iter()
230 .chain(self.output_naming().into_iter())
231 .collect(),
232 )?;
233 check_duplicate(
235 types
236 .clone()
237 .into_iter()
238 .chain(self.precondition_naming().into_iter())
239 .collect(),
240 )?;
241 check_duplicate(
243 types
244 .clone()
245 .into_iter()
246 .chain(self.invariant_naming().into_iter())
247 .collect(),
248 )?;
249 check_duplicate(
251 types
252 .clone()
253 .into_iter()
254 .chain(self.success_naming().into_iter())
255 .collect(),
256 )?;
257 check_duplicate(
259 types
260 .clone()
261 .into_iter()
262 .chain(self.failure_naming().into_iter())
263 .collect(),
264 )?;
265
266 Ok(())
267 }
268
269 pub fn resolve_type(&mut self, map: &HashMap<String, TypeId>) -> Result<(), RlError> {
272 for x in self.inputs.iter_mut() {
274 x.resolve_type(map)?;
275 }
276 for x in self.outputs.iter_mut() {
278 x.resolve_type(map)?;
279 }
280 if let Some(progress) = &mut self.progress {
282 progress.resolve_type(map)?;
283 }
284 Ok(())
285 }
286
287 pub fn resolve_resource(&mut self, map: &HashMap<String, ResourceId>) -> Result<(), RlError> {
288 for x in self.preconditions.iter_mut() {
290 x.resolve_resource(map)?;
291 }
292 for x in self.start.iter_mut() {
294 x.resolve_resource(map)?;
295 }
296 for x in self.invariants.iter_mut() {
298 x.resolve_resource(map)?;
299 }
300 if let Some(i) = &mut self.interrupt {
302 i.resolve_resource(map)?;
303 }
304 for x in self.successes.iter_mut() {
306 x.resolve_resource(map)?;
307 }
308 for x in self.failures.iter_mut() {
310 x.resolve_resource(map)?;
311 }
312 Ok(())
313 }
314
315 pub fn resolve_state(&mut self, map: &HashMap<String, StateId>) -> Result<(), RlError> {
316 for x in self.preconditions.iter_mut() {
318 x.resolve_state(map)?;
319 }
320 for x in self.start.iter_mut() {
322 x.resolve_state(map)?;
323 }
324 for x in self.invariants.iter_mut() {
326 x.resolve_state(map)?;
327 }
328 if let Some(i) = &mut self.interrupt {
330 i.resolve_state(map)?;
331 }
332 for x in self.successes.iter_mut() {
334 x.resolve_state(map)?;
335 }
336 for x in self.failures.iter_mut() {
338 x.resolve_state(map)?;
339 }
340 Ok(())
341 }
342}
343
344impl Named<SkillId> for Skill {
345 fn id(&self) -> SkillId {
346 self.id
347 }
348 fn set_id(&mut self, id: SkillId) {
349 self.id = id;
350 for x in self.preconditions.iter_mut() {
351 let PreconditionId(_, index) = x.id();
352 x.set_id(PreconditionId(id, index));
353 }
354 for x in self.invariants.iter_mut() {
355 let InvariantId(_, index) = x.id();
356 x.set_id(InvariantId(id, index));
357 }
358 for x in self.successes.iter_mut() {
359 let SuccessId(_, index) = x.id();
360 x.set_id(SuccessId(id, index));
361 }
362 for x in self.failures.iter_mut() {
363 let FailureId(_, index) = x.id();
364 x.set_id(FailureId(id, index));
365 }
366 }
367 fn name(&self) -> &str {
368 &self.name
369 }
370 fn position(&self) -> Option<Position> {
371 self.position.clone()
372 }
373}
374
375impl GetFromId<PreconditionId, Precondition> for Skill {
376 fn get(&self, id: PreconditionId) -> Option<&Precondition> {
377 self.get_precondition(id)
378 }
379}
380impl GetFromId<InvariantId, Invariant> for Skill {
381 fn get(&self, id: InvariantId) -> Option<&Invariant> {
382 self.get_invariant(id)
383 }
384}
385impl GetFromId<SuccessId, Success> for Skill {
386 fn get(&self, id: SuccessId) -> Option<&Success> {
387 self.get_success(id)
388 }
389}
390impl GetFromId<FailureId, Failure> for Skill {
391 fn get(&self, id: FailureId) -> Option<&Failure> {
392 self.get_failure(id)
393 }
394}
395
396impl ToLang for Skill {
397 fn to_lang(&self, skillset: &Skillset) -> String {
398 let mut s = String::new();
399 s.push_str(&format!("\t\t{} {{\n", self.name));
400 if !self.inputs.is_empty() {
402 s.push_str("\t\t\tinput {\n");
403 for x in self.inputs.iter() {
404 s.push_str(&format!("\t\t\t\t{}\n", x.to_lang(skillset)))
405 }
406 s.push_str("\t\t\t}\n");
407 }
408 if !self.inputs.is_empty() {
410 s.push_str("\t\t\toutput {\n");
411 for x in self.outputs.iter() {
412 s.push_str(&format!("\t\t\t\t{}\n", x.to_lang(skillset)))
413 }
414 s.push_str("\t\t\t}\n");
415 }
416 if !self.preconditions.is_empty() {
418 s.push_str("\t\t\tprecondition {\n");
419 for x in self.preconditions.iter() {
420 s.push_str(&format!("\t\t\t\t{}\n", x.to_lang(skillset)))
421 }
422 s.push_str("\t\t\t}\n");
423 }
424 if !self.start.is_empty() {
426 s.push_str("\t\t\tstart {\n");
427 for x in self.start.iter() {
428 s.push_str(&format!("\t\t\t\t{}\n", x.to_lang(skillset)))
429 }
430 s.push_str("\t\t\t}\n");
431 }
432 if !self.invariants.is_empty() {
434 s.push_str("\t\t\tinvariant {\n");
435 for x in self.invariants.iter() {
436 s.push_str(&format!("\t\t\t\t{}", x.to_lang(skillset)))
437 }
438 s.push_str("\t\t\t}\n");
439 }
440 if let Some(progress) = &self.progress {
442 s.push_str(&progress.to_lang(skillset));
443 }
444 if let Some(i) = &self.interrupt {
446 s.push_str(&i.to_lang(skillset));
447 }
448 if !self.successes.is_empty() {
450 s.push_str("\t\t\tsuccess {\n");
451 for x in self.successes.iter() {
452 s.push_str(&format!("\t\t\t\t{}", x.to_lang(skillset)))
453 }
454 s.push_str("\t\t\t}\n");
455 }
456 if !self.failures.is_empty() {
458 s.push_str("\t\t\tfailure {\n");
459 for x in self.failures.iter() {
460 s.push_str(&format!("\t\t\t\t{}", x.to_lang(skillset)))
461 }
462 s.push_str("\t\t\t}\n");
463 }
464 s.push_str("\t\t}\n");
466 s
467 }
468}
469
470impl std::fmt::Display for Skill {
471 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
472 write!(f, "{}", self.name())
473 }
474}