1pub mod ac_matching;
4pub mod advanced_analysis;
5pub mod advanced_rewriting;
6mod analysis;
7pub mod confluence;
8pub mod defuzzification;
9pub mod distributive_laws;
10mod domain_validation;
11pub mod ltl_ctl_utilities;
12pub mod modal_axioms;
13pub mod modal_equivalences;
14pub mod normal_forms;
15pub mod optimization;
16pub mod optimization_pipeline;
17pub mod probabilistic_reasoning;
18pub mod rewriting;
19pub mod strategy_selector;
20pub mod temporal_equivalences;
21mod validation;
22
23use serde::{Deserialize, Serialize};
24
25use crate::term::Term;
26
27#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
29pub enum AggregateOp {
30 Count,
32 Sum,
34 Average,
36 Max,
38 Min,
40 Product,
42 Any,
44 All,
46}
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
55pub enum TNormKind {
56 Minimum,
59
60 Product,
63
64 Lukasiewicz,
67
68 Drastic,
71
72 NilpotentMinimum,
74
75 Hamacher,
78}
79
80#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
83pub enum TCoNormKind {
84 Maximum,
87
88 ProbabilisticSum,
91
92 BoundedSum,
95
96 Drastic,
99
100 NilpotentMaximum,
103
104 Hamacher,
106}
107
108#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
110pub enum FuzzyNegationKind {
111 Standard,
113
114 Sugeno {
117 lambda: i32, },
120
121 Yager {
123 w: u32,
125 },
126}
127
128#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
130pub enum FuzzyImplicationKind {
131 Godel,
133
134 Lukasiewicz,
136
137 Reichenbach,
139
140 KleeneDienes,
142
143 Rescher,
145
146 Goguen,
148}
149
150#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
151pub enum TLExpr {
152 Pred {
153 name: String,
154 args: Vec<Term>,
155 },
156 And(Box<TLExpr>, Box<TLExpr>),
157 Or(Box<TLExpr>, Box<TLExpr>),
158 Not(Box<TLExpr>),
159 Exists {
160 var: String,
161 domain: String,
162 body: Box<TLExpr>,
163 },
164 ForAll {
165 var: String,
166 domain: String,
167 body: Box<TLExpr>,
168 },
169 Imply(Box<TLExpr>, Box<TLExpr>),
170 Score(Box<TLExpr>),
171
172 Add(Box<TLExpr>, Box<TLExpr>),
174 Sub(Box<TLExpr>, Box<TLExpr>),
175 Mul(Box<TLExpr>, Box<TLExpr>),
176 Div(Box<TLExpr>, Box<TLExpr>),
177 Pow(Box<TLExpr>, Box<TLExpr>),
178 Mod(Box<TLExpr>, Box<TLExpr>),
179 Min(Box<TLExpr>, Box<TLExpr>),
180 Max(Box<TLExpr>, Box<TLExpr>),
181
182 Abs(Box<TLExpr>),
184 Floor(Box<TLExpr>),
185 Ceil(Box<TLExpr>),
186 Round(Box<TLExpr>),
187 Sqrt(Box<TLExpr>),
188 Exp(Box<TLExpr>),
189 Log(Box<TLExpr>),
190 Sin(Box<TLExpr>),
191 Cos(Box<TLExpr>),
192 Tan(Box<TLExpr>),
193
194 Eq(Box<TLExpr>, Box<TLExpr>),
196 Lt(Box<TLExpr>, Box<TLExpr>),
197 Gt(Box<TLExpr>, Box<TLExpr>),
198 Lte(Box<TLExpr>, Box<TLExpr>),
199 Gte(Box<TLExpr>, Box<TLExpr>),
200
201 IfThenElse {
203 condition: Box<TLExpr>,
204 then_branch: Box<TLExpr>,
205 else_branch: Box<TLExpr>,
206 },
207
208 Constant(f64),
210
211 Aggregate {
213 op: AggregateOp,
214 var: String,
215 domain: String,
216 body: Box<TLExpr>,
217 group_by: Option<Vec<String>>,
219 },
220
221 Let {
223 var: String,
224 value: Box<TLExpr>,
225 body: Box<TLExpr>,
226 },
227
228 Box(Box<TLExpr>),
232
233 Diamond(Box<TLExpr>),
237
238 Next(Box<TLExpr>),
241
242 Eventually(Box<TLExpr>),
244
245 Always(Box<TLExpr>),
247
248 Until {
250 before: Box<TLExpr>,
251 after: Box<TLExpr>,
252 },
253
254 TNorm {
257 kind: TNormKind,
258 left: Box<TLExpr>,
259 right: Box<TLExpr>,
260 },
261
262 TCoNorm {
264 kind: TCoNormKind,
265 left: Box<TLExpr>,
266 right: Box<TLExpr>,
267 },
268
269 FuzzyNot {
271 kind: FuzzyNegationKind,
272 expr: Box<TLExpr>,
273 },
274
275 FuzzyImplication {
277 kind: FuzzyImplicationKind,
278 premise: Box<TLExpr>,
279 conclusion: Box<TLExpr>,
280 },
281
282 SoftExists {
288 var: String,
289 domain: String,
290 body: Box<TLExpr>,
291 temperature: f64,
293 },
294
295 SoftForAll {
300 var: String,
301 domain: String,
302 body: Box<TLExpr>,
303 temperature: f64,
305 },
306
307 WeightedRule {
310 weight: f64,
311 rule: Box<TLExpr>,
312 },
313
314 ProbabilisticChoice {
317 alternatives: Vec<(f64, TLExpr)>, },
319
320 Release {
324 released: Box<TLExpr>,
325 releaser: Box<TLExpr>,
326 },
327
328 WeakUntil {
330 before: Box<TLExpr>,
331 after: Box<TLExpr>,
332 },
333
334 StrongRelease {
336 released: Box<TLExpr>,
337 releaser: Box<TLExpr>,
338 },
339}
340
341impl TLExpr {
342 pub fn pred(name: impl Into<String>, args: Vec<Term>) -> Self {
343 TLExpr::Pred {
344 name: name.into(),
345 args,
346 }
347 }
348
349 pub fn and(left: TLExpr, right: TLExpr) -> Self {
350 TLExpr::And(Box::new(left), Box::new(right))
351 }
352
353 pub fn or(left: TLExpr, right: TLExpr) -> Self {
354 TLExpr::Or(Box::new(left), Box::new(right))
355 }
356
357 pub fn negate(expr: TLExpr) -> Self {
358 TLExpr::Not(Box::new(expr))
359 }
360
361 pub fn exists(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
362 TLExpr::Exists {
363 var: var.into(),
364 domain: domain.into(),
365 body: Box::new(body),
366 }
367 }
368
369 pub fn forall(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
370 TLExpr::ForAll {
371 var: var.into(),
372 domain: domain.into(),
373 body: Box::new(body),
374 }
375 }
376
377 pub fn imply(premise: TLExpr, conclusion: TLExpr) -> Self {
378 TLExpr::Imply(Box::new(premise), Box::new(conclusion))
379 }
380
381 pub fn score(expr: TLExpr) -> Self {
382 TLExpr::Score(Box::new(expr))
383 }
384
385 #[allow(clippy::should_implement_trait)]
387 pub fn add(left: TLExpr, right: TLExpr) -> Self {
388 TLExpr::Add(Box::new(left), Box::new(right))
389 }
390
391 #[allow(clippy::should_implement_trait)]
392 pub fn sub(left: TLExpr, right: TLExpr) -> Self {
393 TLExpr::Sub(Box::new(left), Box::new(right))
394 }
395
396 #[allow(clippy::should_implement_trait)]
397 pub fn mul(left: TLExpr, right: TLExpr) -> Self {
398 TLExpr::Mul(Box::new(left), Box::new(right))
399 }
400
401 #[allow(clippy::should_implement_trait)]
402 pub fn div(left: TLExpr, right: TLExpr) -> Self {
403 TLExpr::Div(Box::new(left), Box::new(right))
404 }
405
406 pub fn pow(left: TLExpr, right: TLExpr) -> Self {
407 TLExpr::Pow(Box::new(left), Box::new(right))
408 }
409
410 pub fn modulo(left: TLExpr, right: TLExpr) -> Self {
411 TLExpr::Mod(Box::new(left), Box::new(right))
412 }
413
414 pub fn min(left: TLExpr, right: TLExpr) -> Self {
415 TLExpr::Min(Box::new(left), Box::new(right))
416 }
417
418 pub fn max(left: TLExpr, right: TLExpr) -> Self {
419 TLExpr::Max(Box::new(left), Box::new(right))
420 }
421
422 pub fn abs(expr: TLExpr) -> Self {
424 TLExpr::Abs(Box::new(expr))
425 }
426
427 pub fn floor(expr: TLExpr) -> Self {
428 TLExpr::Floor(Box::new(expr))
429 }
430
431 pub fn ceil(expr: TLExpr) -> Self {
432 TLExpr::Ceil(Box::new(expr))
433 }
434
435 pub fn round(expr: TLExpr) -> Self {
436 TLExpr::Round(Box::new(expr))
437 }
438
439 pub fn sqrt(expr: TLExpr) -> Self {
440 TLExpr::Sqrt(Box::new(expr))
441 }
442
443 pub fn exp(expr: TLExpr) -> Self {
444 TLExpr::Exp(Box::new(expr))
445 }
446
447 pub fn log(expr: TLExpr) -> Self {
448 TLExpr::Log(Box::new(expr))
449 }
450
451 pub fn sin(expr: TLExpr) -> Self {
452 TLExpr::Sin(Box::new(expr))
453 }
454
455 pub fn cos(expr: TLExpr) -> Self {
456 TLExpr::Cos(Box::new(expr))
457 }
458
459 pub fn tan(expr: TLExpr) -> Self {
460 TLExpr::Tan(Box::new(expr))
461 }
462
463 pub fn eq(left: TLExpr, right: TLExpr) -> Self {
465 TLExpr::Eq(Box::new(left), Box::new(right))
466 }
467
468 pub fn lt(left: TLExpr, right: TLExpr) -> Self {
469 TLExpr::Lt(Box::new(left), Box::new(right))
470 }
471
472 pub fn gt(left: TLExpr, right: TLExpr) -> Self {
473 TLExpr::Gt(Box::new(left), Box::new(right))
474 }
475
476 pub fn lte(left: TLExpr, right: TLExpr) -> Self {
477 TLExpr::Lte(Box::new(left), Box::new(right))
478 }
479
480 pub fn gte(left: TLExpr, right: TLExpr) -> Self {
481 TLExpr::Gte(Box::new(left), Box::new(right))
482 }
483
484 pub fn if_then_else(condition: TLExpr, then_branch: TLExpr, else_branch: TLExpr) -> Self {
486 TLExpr::IfThenElse {
487 condition: Box::new(condition),
488 then_branch: Box::new(then_branch),
489 else_branch: Box::new(else_branch),
490 }
491 }
492
493 pub fn constant(value: f64) -> Self {
495 TLExpr::Constant(value)
496 }
497
498 pub fn aggregate(
500 op: AggregateOp,
501 var: impl Into<String>,
502 domain: impl Into<String>,
503 body: TLExpr,
504 ) -> Self {
505 TLExpr::Aggregate {
506 op,
507 var: var.into(),
508 domain: domain.into(),
509 body: Box::new(body),
510 group_by: None,
511 }
512 }
513
514 pub fn aggregate_with_group_by(
515 op: AggregateOp,
516 var: impl Into<String>,
517 domain: impl Into<String>,
518 body: TLExpr,
519 group_by: Vec<String>,
520 ) -> Self {
521 TLExpr::Aggregate {
522 op,
523 var: var.into(),
524 domain: domain.into(),
525 body: Box::new(body),
526 group_by: Some(group_by),
527 }
528 }
529
530 pub fn count(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
531 Self::aggregate(AggregateOp::Count, var, domain, body)
532 }
533
534 pub fn sum(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
535 Self::aggregate(AggregateOp::Sum, var, domain, body)
536 }
537
538 pub fn average(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
539 Self::aggregate(AggregateOp::Average, var, domain, body)
540 }
541
542 pub fn max_agg(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
543 Self::aggregate(AggregateOp::Max, var, domain, body)
544 }
545
546 pub fn min_agg(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
547 Self::aggregate(AggregateOp::Min, var, domain, body)
548 }
549
550 pub fn product(var: impl Into<String>, domain: impl Into<String>, body: TLExpr) -> Self {
551 Self::aggregate(AggregateOp::Product, var, domain, body)
552 }
553
554 pub fn let_binding(var: impl Into<String>, value: TLExpr, body: TLExpr) -> Self {
556 TLExpr::Let {
557 var: var.into(),
558 value: Box::new(value),
559 body: Box::new(body),
560 }
561 }
562
563 pub fn modal_box(expr: TLExpr) -> Self {
568 TLExpr::Box(Box::new(expr))
569 }
570
571 pub fn modal_diamond(expr: TLExpr) -> Self {
575 TLExpr::Diamond(Box::new(expr))
576 }
577
578 pub fn next(expr: TLExpr) -> Self {
583 TLExpr::Next(Box::new(expr))
584 }
585
586 pub fn eventually(expr: TLExpr) -> Self {
590 TLExpr::Eventually(Box::new(expr))
591 }
592
593 pub fn always(expr: TLExpr) -> Self {
597 TLExpr::Always(Box::new(expr))
598 }
599
600 pub fn until(before: TLExpr, after: TLExpr) -> Self {
604 TLExpr::Until {
605 before: Box::new(before),
606 after: Box::new(after),
607 }
608 }
609
610 pub fn tnorm(kind: TNormKind, left: TLExpr, right: TLExpr) -> Self {
614 TLExpr::TNorm {
615 kind,
616 left: Box::new(left),
617 right: Box::new(right),
618 }
619 }
620
621 pub fn fuzzy_and(left: TLExpr, right: TLExpr) -> Self {
623 Self::tnorm(TNormKind::Minimum, left, right)
624 }
625
626 pub fn probabilistic_and(left: TLExpr, right: TLExpr) -> Self {
628 Self::tnorm(TNormKind::Product, left, right)
629 }
630
631 pub fn tconorm(kind: TCoNormKind, left: TLExpr, right: TLExpr) -> Self {
633 TLExpr::TCoNorm {
634 kind,
635 left: Box::new(left),
636 right: Box::new(right),
637 }
638 }
639
640 pub fn fuzzy_or(left: TLExpr, right: TLExpr) -> Self {
642 Self::tconorm(TCoNormKind::Maximum, left, right)
643 }
644
645 pub fn probabilistic_or(left: TLExpr, right: TLExpr) -> Self {
647 Self::tconorm(TCoNormKind::ProbabilisticSum, left, right)
648 }
649
650 pub fn fuzzy_not(kind: FuzzyNegationKind, expr: TLExpr) -> Self {
652 TLExpr::FuzzyNot {
653 kind,
654 expr: Box::new(expr),
655 }
656 }
657
658 pub fn standard_fuzzy_not(expr: TLExpr) -> Self {
660 Self::fuzzy_not(FuzzyNegationKind::Standard, expr)
661 }
662
663 pub fn fuzzy_imply(kind: FuzzyImplicationKind, premise: TLExpr, conclusion: TLExpr) -> Self {
665 TLExpr::FuzzyImplication {
666 kind,
667 premise: Box::new(premise),
668 conclusion: Box::new(conclusion),
669 }
670 }
671
672 pub fn soft_exists(
682 var: impl Into<String>,
683 domain: impl Into<String>,
684 body: TLExpr,
685 temperature: f64,
686 ) -> Self {
687 TLExpr::SoftExists {
688 var: var.into(),
689 domain: domain.into(),
690 body: Box::new(body),
691 temperature,
692 }
693 }
694
695 pub fn soft_forall(
703 var: impl Into<String>,
704 domain: impl Into<String>,
705 body: TLExpr,
706 temperature: f64,
707 ) -> Self {
708 TLExpr::SoftForAll {
709 var: var.into(),
710 domain: domain.into(),
711 body: Box::new(body),
712 temperature,
713 }
714 }
715
716 pub fn weighted_rule(weight: f64, rule: TLExpr) -> Self {
722 TLExpr::WeightedRule {
723 weight,
724 rule: Box::new(rule),
725 }
726 }
727
728 pub fn probabilistic_choice(alternatives: Vec<(f64, TLExpr)>) -> Self {
733 TLExpr::ProbabilisticChoice { alternatives }
734 }
735
736 pub fn release(released: TLExpr, releaser: TLExpr) -> Self {
742 TLExpr::Release {
743 released: Box::new(released),
744 releaser: Box::new(releaser),
745 }
746 }
747
748 pub fn weak_until(before: TLExpr, after: TLExpr) -> Self {
752 TLExpr::WeakUntil {
753 before: Box::new(before),
754 after: Box::new(after),
755 }
756 }
757
758 pub fn strong_release(released: TLExpr, releaser: TLExpr) -> Self {
762 TLExpr::StrongRelease {
763 released: Box::new(released),
764 releaser: Box::new(releaser),
765 }
766 }
767}