1use crate::prelude::*;
2
3impl Runtime {
4 pub fn define_parameter_by_binding_param_type(
6 &mut self,
7 name: &str,
8 param_type: &ParamType,
9 binding_kind: ParamObjType,
10 ) -> Result<InferResult, RuntimeError> {
11 match param_type {
12 ParamType::Obj(obj) => match obj {
13 Obj::FamilyObj(family_ty) => {
14 self.define_parameter_by_binding_family(name, family_ty, binding_kind)
15 }
16 Obj::FiniteSeqSet(fs) => {
17 let fn_set = self.finite_seq_set_to_fn_set(fs, default_line_file());
18 let type_fact = InFact::new(
19 param_binding_element_obj_for_store(name.to_string(), binding_kind),
20 fn_set.into(),
21 default_line_file(),
22 )
23 .into();
24 self.verify_well_defined_and_store_and_infer_with_default_verify_state(
25 type_fact,
26 )
27 }
28 Obj::SeqSet(ss) => {
29 let fn_set = self.seq_set_to_fn_set(ss, default_line_file());
30 let type_fact = InFact::new(
31 param_binding_element_obj_for_store(name.to_string(), binding_kind),
32 fn_set.into(),
33 default_line_file(),
34 )
35 .into();
36 self.verify_well_defined_and_store_and_infer_with_default_verify_state(
37 type_fact,
38 )
39 }
40 Obj::MatrixSet(ms) => {
41 let fn_set = self.matrix_set_to_fn_set(ms, default_line_file());
42 let type_fact = InFact::new(
43 param_binding_element_obj_for_store(name.to_string(), binding_kind),
44 fn_set.into(),
45 default_line_file(),
46 )
47 .into();
48 self.verify_well_defined_and_store_and_infer_with_default_verify_state(
49 type_fact,
50 )
51 }
52 _ => self.define_parameter_by_binding_obj(name, obj, binding_kind),
53 },
54 ParamType::Set(set) => self.define_parameter_by_binding_set(name, set, binding_kind),
55 ParamType::NonemptySet(nonempty_set) => {
56 self.define_parameter_by_binding_nonempty_set(name, nonempty_set, binding_kind)
57 }
58 ParamType::FiniteSet(finite_set) => {
59 self.define_parameter_by_binding_finite_set(name, finite_set, binding_kind)
60 }
61 ParamType::Restrictive(fn_set) => {
62 self.define_parameter_by_binding_restrictive(name, fn_set, binding_kind)
63 }
64 }
65 }
66
67 fn define_parameter_by_binding_restrictive(
68 &mut self,
69 name: &str,
70 fn_set: &FnSet,
71 binding_kind: ParamObjType,
72 ) -> Result<InferResult, RuntimeError> {
73 let element = param_binding_element_obj_for_store(name.to_string(), binding_kind);
74 let restrict_fact: Fact =
75 RestrictFact::new(element, fn_set.clone().into(), default_line_file()).into();
76 self.verify_well_defined_and_store_and_infer_with_default_verify_state(restrict_fact)
77 }
78
79 fn define_parameter_by_binding_family(
80 &mut self,
81 name: &str,
82 family_ty: &FamilyObj,
83 binding_kind: ParamObjType,
84 ) -> Result<InferResult, RuntimeError> {
85 self.infer_membership_in_family_for_param_binding(name, family_ty, binding_kind)
86 }
87
88 fn define_parameter_by_binding_obj(
89 &mut self,
90 name: &str,
91 obj: &Obj,
92 binding_kind: ParamObjType,
93 ) -> Result<InferResult, RuntimeError> {
94 let type_fact = InFact::new(
95 param_binding_element_obj_for_store(name.to_string(), binding_kind),
96 obj.clone(),
97 default_line_file(),
98 )
99 .into();
100 self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
101 }
102
103 fn define_parameter_by_binding_set(
104 &mut self,
105 name: &str,
106 _set: &Set,
107 binding_kind: ParamObjType,
108 ) -> Result<InferResult, RuntimeError> {
109 let type_fact = IsSetFact::new(
110 param_binding_element_obj_for_store(name.to_string(), binding_kind),
111 default_line_file(),
112 )
113 .into();
114 self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
115 }
116
117 fn define_parameter_by_binding_nonempty_set(
118 &mut self,
119 name: &str,
120 _nonempty_set: &NonemptySet,
121 binding_kind: ParamObjType,
122 ) -> Result<InferResult, RuntimeError> {
123 let type_fact = IsNonemptySetFact::new(
124 param_binding_element_obj_for_store(name.to_string(), binding_kind),
125 default_line_file(),
126 )
127 .into();
128 self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
129 }
130
131 fn define_parameter_by_binding_finite_set(
132 &mut self,
133 name: &str,
134 _finite_set: &FiniteSet,
135 binding_kind: ParamObjType,
136 ) -> Result<InferResult, RuntimeError> {
137 let type_fact = IsFiniteSetFact::new(
138 param_binding_element_obj_for_store(name.to_string(), binding_kind),
139 default_line_file(),
140 )
141 .into();
142 self.verify_well_defined_and_store_and_infer_with_default_verify_state(type_fact)
143 }
144
145 pub fn define_params_with_type(
146 &mut self,
147 param_defs: &ParamDefWithType,
148 check_type_nonempty: bool,
149 binding_kind: ParamObjType,
150 ) -> Result<InferResult, RuntimeError> {
151 let mut infer_result = InferResult::new();
152 for param_def in param_defs.groups.iter() {
153 self.verify_param_type_well_defined(¶m_def.param_type, &VerifyState::new(0, false))
154 .map_err(|well_defined_error| {
155 let param_names_text = param_def.params.join(", ");
156 let error_line_file = well_defined_error.line_file().clone();
157 RuntimeError::from(DefineParamsRuntimeError(RuntimeErrorStruct::new(
158 None,
159 format!(
160 "define params with type: failed to verify type well-defined for params [{}] with type {}",
161 param_names_text, param_def.param_type
162 ),
163 error_line_file,
164 Some(well_defined_error),
165 vec![],
166 )))
167 })?;
168 self.verify_param_type_nonempty_if_required(¶m_def.param_type, check_type_nonempty)
169 .map_err(|inner_exec_error| {
170 let param_names_text = param_def.params.join(", ");
171 RuntimeError::from(DefineParamsRuntimeError(RuntimeErrorStruct::new_with_msg_and_cause(format!(
172 "define params with type: nonempty check failed for params [{}] with type {}",
173 param_names_text, param_def.param_type
174 ), inner_exec_error)))
175 })?;
176
177 for name in param_def.params.iter() {
178 self.store_free_param_or_identifier_name(name, binding_kind)
179 .map_err(|runtime_error| {
180 RuntimeError::from(DefineParamsRuntimeError(
181 RuntimeErrorStruct::new_with_msg_and_cause(
182 format!(
183 "define params with type: failed to declare parameter `{}`",
184 name
185 ),
186 runtime_error,
187 ),
188 ))
189 })?;
190 let fact_infer_result = self
191 .define_parameter_by_binding_param_type(
192 name,
193 ¶m_def.param_type,
194 binding_kind,
195 )
196 .map_err(|runtime_error| {
197 RuntimeError::from(DefineParamsRuntimeError(RuntimeErrorStruct::new_with_msg_and_cause(format!(
198 "define params with type: failed to apply param type for parameter `{}` with type {}",
199 name, param_def.param_type
200 ), runtime_error)))
201 })?;
202 infer_result.new_infer_result_inside(fact_infer_result);
203 }
204 }
205 Ok(infer_result)
206 }
207}