rl_model/model/
terminate.rs

1use super::*;
2use crate::parser::{Position, RlError};
3use std::collections::HashMap;
4
5pub trait TerminateId: Id {}
6
7#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
8pub struct SuccessId(pub SkillId, pub usize);
9impl Id for SuccessId {
10    fn index(&self) -> usize {
11        self.1
12    }
13}
14impl SuccessId {
15    pub fn skill(&self) -> SkillId {
16        self.0
17    }
18}
19impl TerminateId for SuccessId {}
20
21#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
22pub struct FailureId(pub SkillId, pub usize);
23impl Id for FailureId {
24    fn index(&self) -> usize {
25        self.1
26    }
27}
28impl FailureId {
29    pub fn skill(&self) -> SkillId {
30        self.0
31    }
32}
33impl TerminateId for FailureId {}
34
35pub type Success = Terminate<SuccessId>;
36pub type Failure = Terminate<FailureId>;
37
38#[derive(Debug, Clone)]
39pub struct Terminate<I: TerminateId> {
40    id: I,
41    name: String,
42    postconditions: Vec<Postcondition>,
43    effects: Vec<Effect>,
44    position: Option<Position>,
45}
46
47impl<I: TerminateId> Terminate<I> {
48    pub fn new<S: Into<String>>(
49        name: S,
50        postconditions: Vec<Postcondition>,
51        effects: Vec<Effect>,
52        position: Option<Position>,
53    ) -> Self {
54        let id = I::default();
55        let name = name.into();
56        Self {
57            id,
58            name,
59            effects,
60            postconditions,
61            position,
62        }
63    }
64
65    pub fn postconditions(&self) -> &Vec<Postcondition> {
66        &self.postconditions
67    }
68
69    pub fn effects(&self) -> &Vec<Effect> {
70        &self.effects
71    }
72
73    //---------- Resolve ----------
74
75    pub fn resolve_resource(&mut self, map: &HashMap<String, ResourceId>) -> Result<(), RlError> {
76        for x in self.effects.iter_mut() {
77            x.resolve_resource(map)?;
78        }
79        for x in self.postconditions.iter_mut() {
80            x.resolve_resource(map)?;
81        }
82        Ok(())
83    }
84
85    pub fn resolve_state(&mut self, map: &HashMap<String, StateId>) -> Result<(), RlError> {
86        for x in self.effects.iter_mut() {
87            x.resolve_state(map)?;
88        }
89        for x in self.postconditions.iter_mut() {
90            x.resolve_state(map)?;
91        }
92        Ok(())
93    }
94}
95
96impl Named<SuccessId> for Success {
97    fn id(&self) -> SuccessId {
98        self.id
99    }
100    fn set_id(&mut self, id: SuccessId) {
101        self.id = id;
102    }
103    fn name(&self) -> &str {
104        &self.name
105    }
106    fn position(&self) -> Option<Position> {
107        self.position.clone()
108    }
109}
110impl Named<FailureId> for Failure {
111    fn id(&self) -> FailureId {
112        self.id
113    }
114    fn set_id(&mut self, id: FailureId) {
115        self.id = id;
116    }
117    fn name(&self) -> &str {
118        &self.name
119    }
120    fn position(&self) -> Option<Position> {
121        self.position.clone()
122    }
123}
124impl<I: TerminateId> ToLang for Terminate<I> {
125    fn to_lang(&self, skillset: &Skillset) -> String {
126        let mut s = format!("{} {{\n", self.name);
127        // Postcondition
128        if !self.postconditions.is_empty() {
129            s.push_str("\t\t\t\t\teffect {\n");
130            for x in self.postconditions.iter() {
131                s.push_str(&format!("\t\t\t\t\t\t{}\n", x.to_lang(skillset)))
132            }
133            s.push_str("\t\t\t\t\t}\n");
134        }
135        // Effects
136        if !self.effects.is_empty() {
137            s.push_str("\t\t\t\t\teffect {\n");
138            for x in self.effects.iter() {
139                s.push_str(&format!("\t\t\t\t\t\t{}\n", x.to_lang(skillset)))
140            }
141            s.push_str("\t\t\t\t\t}\n");
142        }
143        //
144        s.push_str("\t\t\t\t}\n");
145        s
146    }
147}
148
149impl<I: TerminateId> std::fmt::Display for Terminate<I> {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        write!(f, "{}", self.name)
152    }
153}