avalog/
lib.rs

1#![deny(missing_docs)]
2
3//! # Avalog
4//!
5//! An experimental implementation of [Avatar Logic](https://advancedresearch.github.io/avatar-extensions/summary.html)
6//! with a Prolog-like syntax.
7//!
8//! ```text
9//! === Avalog 0.7 ===
10//! Type `help` for more information.
11//! > parent'(alice) : mom
12//! > (bob, parent'(alice))
13//! > prove mom(bob) => parent'(alice)
14//! parent'(alice) : mom
15//! (bob, parent'(alice))
16//! ----------------------------------
17//! mom(bob) => parent'(alice)
18//!
19//! OK
20//! ```
21//!
22//! To run Avalog from your Terminal, type:
23//!
24//! ```text
25//! cargo install --example avalog_repl avalog
26//! ```
27//!
28//! Then, to run:
29//!
30//! ```text
31//! avalog_repl
32//! ```
33//!
34//! Based on paper [Avatar Binary Relations](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip/avatar-binary-relations.pdf).
35//!
36//! ### Motivation
37//!
38//! Avatar Logic is an attempt to create a formal language that satisfies "avatars",
39//! in the sense of [Avatar Extensions](https://github.com/advancedresearch/path_semantics/blob/master/sequences.md#avatar-extensions).
40//! Avatar Extensions is a technique for abstract generalization in [Path Semantics](https://github.com/advancedresearch/path_semantics),
41//! an extremely expressive language for mathematical programming.
42//!
43//! In higher dimensional programming, such as Path Semantics, one would like to generalize
44//! the abstractions across multiple dimensions at the same time, without having to write axioms
45//! for each dimension.
46//!
47//! If normal programming is 2D, then [normal paths](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip/normal-paths.pdf)
48//! in Path Semantics is 3D.
49//! Avatar Extensions seeks to go beyond 3D programming to arbitrary higher dimensions.
50//! Avatar Logic is a deep result from discussing interpretations of [Avatar Graphs](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip/avatar-graphs.pdf),
51//! which relates a variant of Cartesian combinatorics with graphs, group actions and topology.
52//!
53//! ### Example: Grandma Alice
54//!
55//! ```text
56//! uniq parent
57//! parent'(alice) : mom
58//! grandparent'(alice) : grandma
59//! parent'(bob) : dad
60//! (bob, parent'(alice))
61//! (carl, parent'(bob))
62//! (X, grandparent'(Z)) :- (X, parent'(Y)), (Y, parent'(Z)).
63//! ```
64//!
65//! This can be used to prove the following goal:
66//!
67//! ```text
68//! grandma(carl) => grandparent'(alice)
69//! ```
70//!
71//! The first statement `uniq parent` tells that the 1-avatar `parent` should behave uniquely.
72//! Basically, this means one person can have maximum one mom and one dad.
73//!
74//! When this is turned off, one can only say e.g. "Bob has a mom who's name is Alice",
75//! but not "Bob's mom is Alice", because Bob might have more than one mom.
76//!
77//! Formally, `mom(bob) => parent'(alice)` (has) vs `mom(bob) = parent'(alice)` (is).
78//!
79//! The statement `parent'(alice) : mom` says that Alice has a 1-avatar "parent" which
80//! is assigned the role "mom".
81//! Avatar Logic "knows" that Alice, and Alice as a parent, are one and the same,
82//! but the relations to Alice are universal while relations to Alice as a parent depends on context.
83//!
84//! The relation `(bob, parent'(alice))` does not specify how Bob and Alice as a parent are related,
85//! because it is inferred from the assigned role to Alice as a parent.
86//! This simplifies the logic a lot for higher dimensions of programming.
87//!
88//! The rule `(X, grandparent'(Z)) :- (X, parent'(Y)), (Y, parent'(Z)).` is similar
89//! to a [Horn clause](https://en.wikipedia.org/wiki/Horn_clause), which is used in
90//! [Prolog](https://en.wikipedia.org/wiki/Prolog).
91//!
92//! The grandparent rule works for any combination of moms and dads.
93//! It also works for other parental relationship that can be used for e.g. animals.
94//! You can use separate roles for separate kind of objects, but not mix e.g. humans and animals.
95//! This is because Avatar Logic is kind of like [dependent types](https://en.wikipedia.org/wiki/Dependent_type), but for logic.
96//! Relationships depends on the values, but enforces local consistency, kind of like types.
97//!
98//! ### Introduction to Avatar Logic
99//!
100//! In Prolog, you would write relations using predicates, e.g. `mom(alice, bob)`.
101//! The problem is that predicates are 1) unconstrained and 2) axioms doesn't carry over
102//! arbitrary Cartesian relations.
103//!
104//! In Avatar Logic, instead of predicates, you use "binary relations" with added axioms for roles and avatars.
105//!
106//! To explain how Avatar Logic works, one can start with binary relations.
107//!
108//! A binary relation is an ordered pair:
109//!
110//! ```text
111//! (a, b)
112//! ```
113//!
114//! By adding axioms to binary relations, one can improve expressiveness and simplify
115//! modeling over abstract relations. This is used because unconstrained relations are
116//! too hard to use for formalizing advanced mathematical theories, like Path Semantics.
117//!
118//! Avatar Logic consists of two kinds of pairs:
119//!
120//! - [Unique Universal Binary Relations](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip/unique-universal-binary-relations.pdf)
121//! - [Avatar Binary Relations](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip/avatar-binary-relations.pdf)
122//!
123//! Axioms:
124//!
125//! ```text
126//! p(a, b)         b : p           p(a) = b
127//! p(a, q'(b))     q'(b) : p       p(a) = {q'(_)} ∈ q'(b)
128//! ```
129//!
130//! To make Avatar Binary Relations behave like Unique Universal Binary Relations,
131//! one can use the `uniq q` directive where `q` is a 1-avatar.
132//! This forces the following relation for `q`:
133//!
134//! ```text
135//! p(a) = q'(b)
136//! ```
137//!
138//! ### Design
139//!
140//! Uses the [Monotonic-Solver](https://github.com/advancedresearch/monotonic_solver) library
141//! for generic automated theorem proving.
142//!
143//! Uses the [Piston-Meta](https://github.com/pistondevelopers/meta) library for meta parsing.
144//!
145//! The axioms for Avatar Logic can not be used directly,
146//! but instead inference rules are derived from the axioms.
147//!
148//! A part of this project is to experiment with inference rules,
149//! so no recommended set of inference is published yet.
150//!
151//! The inference rules are coded in the `infer` function.
152
153use std::sync::Arc;
154use std::fmt;
155use std::collections::HashMap;
156use std::cmp;
157use std::hash::Hash;
158
159use Expr::*;
160
161pub use monotonic_solver::*;
162pub use parsing::*;
163
164mod parsing;
165
166/// Detect a variable when parsing.
167pub trait IsVar {
168    /// Returns `true` if string is a variable.
169    fn is_var(val: &str) -> bool {
170        if let Some(c) = val.chars().next() {c.is_uppercase()} else {false}
171    }
172}
173
174/// Implemented by symbol types.
175pub trait Symbol:
176    IsVar +
177    From<Arc<String>> +
178    Clone +
179    fmt::Debug +
180    fmt::Display +
181    cmp::PartialEq +
182    cmp::Eq +
183    cmp::PartialOrd +
184    Hash {
185}
186
187impl IsVar for Arc<String> {}
188
189impl<T> Symbol for T
190    where T: IsVar +
191             From<Arc<String>> +
192             Clone +
193             fmt::Debug +
194             fmt::Display +
195             cmp::PartialEq +
196             cmp::Eq +
197             cmp::PartialOrd +
198             Hash
199{}
200
201/// Represents an expression.
202#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
203pub enum Expr<T: Symbol = Arc<String>> {
204    /// A symbol.
205    Sym(T),
206    /// A variable.
207    Var(Arc<String>),
208    /// A relation between two symbols.
209    Rel(Box<Expr<T>>, Box<Expr<T>>),
210    /// A 1-avatar of some expression.
211    Ava(Box<Expr<T>>, Box<Expr<T>>),
212    /// Unwraps 1-avatar.
213    Inner(Box<Expr<T>>),
214    /// A 1-avatar `q'(b)` such that `p(a) = q'(b)`.
215    UniqAva(Box<Expr<T>>),
216    /// A role of expression.
217    RoleOf(Box<Expr<T>>, Box<Expr<T>>),
218    /// An equality, e.g. `p(a) = b`.
219    Eq(Box<Expr<T>>, Box<Expr<T>>),
220    /// An inequality, e.g. `X != a`.
221    Neq(Box<Expr<T>>, Box<Expr<T>>),
222    /// A set membership relation, e.g. `p(a) ∋ b`.
223    Has(Box<Expr<T>>, Box<Expr<T>>),
224    /// Apply an argument to a role, e.g. `p(a)`.
225    App(Box<Expr<T>>, Box<Expr<T>>),
226    /// There is an ambiguous role.
227    AmbiguousRole(Box<Expr<T>>, Box<Expr<T>>, Box<Expr<T>>),
228    /// There is an ambiguous relation.
229    AmbiguousRel(Box<Expr<T>>, Box<Expr<T>>, Box<Expr<T>>),
230    /// Defines a rule.
231    Rule(Box<Expr<T>>, Vec<Expr<T>>),
232    /// Ambiguity summary.
233    ///
234    /// This is `true` when some ambiguity is found,
235    /// and `false` when no ambiguity is found.
236    Ambiguity(bool),
237    /// Represents the tail of an argument list `..`.
238    Tail,
239    /// Represents the tail of an argument list bound a symbol `..x`.
240    TailVar(Arc<String>),
241    /// Represents a list.
242    List(Vec<Expr<T>>),
243}
244
245impl<T: Symbol> fmt::Display for Expr<T> {
246    fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
247        match self {
248            Sym(a) => write!(w, "{}", a)?,
249            Var(a) => write!(w, "{}", a)?,
250            Rel(a, b) => write!(w, "({}, {})", a, b)?,
251            Ava(a, b) => write!(w, "{}'({})", a, b)?,
252            Inner(a) => write!(w, ".{}", a)?,
253            UniqAva(a) => write!(w, "uniq {}", a)?,
254            RoleOf(a, b) => write!(w, "{} : {}", a, b)?,
255            Eq(a, b) => write!(w, "{} = {}", a, b)?,
256            Neq(a, b) => write!(w, "{} != {}", a, b)?,
257            Has(a, b) => write!(w, "{} => {}", a, b)?,
258            App(a, b) => {
259                let mut expr = a;
260                let mut args = vec![];
261                let mut found_f = false;
262                while let App(a1, a2) = &**expr {
263                    if let App(_, _) = &**a1 {} else {
264                        found_f = true;
265                        write!(w, "{}(", a1)?;
266                    }
267                    args.push(a2);
268                    expr = a1;
269                }
270
271                if !found_f {
272                    write!(w, "{}(", a)?;
273                }
274                let mut first = true;
275                for arg in args.iter().rev() {
276                    if !first {
277                        write!(w, ", ")?;
278                    }
279                    first = false;
280                    write!(w, "{}", arg)?;
281                }
282                if !first {
283                    write!(w, ", ")?;
284                }
285                write!(w, "{})", b)?;
286            }
287            AmbiguousRole(a, b, c) => write!(w, "amb_role({}, {}, {})", a, b, c)?,
288            AmbiguousRel(a, b, c) => write!(w, "amb_rel({}, {}, {})", a, b, c)?,
289            Ambiguity(v) => if *v {write!(w, "amb")?} else {write!(w, "no amb")?},
290            Rule(a, b) => {
291                write!(w, "{} :- ", a)?;
292                let mut first = true;
293                for arg in b {
294                    if !first {
295                        write!(w, ", ")?;
296                    }
297                    first = false;
298                    write!(w, "{}", arg)?;
299                }
300                write!(w, ".")?;
301            }
302            Tail => write!(w, "..")?,
303            TailVar(a) => write!(w, "..{}", a)?,
304            List(a) => {
305                write!(w, "[")?;
306                let mut first = true;
307                for item in a {
308                    if !first {
309                        write!(w, ", ")?;
310                    }
311                    first = false;
312                    write!(w, "{}", item)?;
313                }
314                write!(w, "]")?;
315            }
316        }
317        Ok(())
318    }
319}
320
321/// Constructs a unique directive expression, e.g. `uniq a`.
322pub fn uniq_ava<T, S>(a: T) -> Expr<S>
323    where T: Into<Expr<S>>, S: Symbol
324{
325    UniqAva(Box::new(a.into()))
326}
327
328/// Constructs a role-of expression, e.g. `a : b`.
329pub fn role_of<T, U, S>(a: T, b: U) -> Expr<S>
330    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
331{
332    RoleOf(Box::new(a.into()), Box::new(b.into()))
333}
334
335/// Constructs a relation expression, e.g. `(a, b)`.
336pub fn rel<T, U, S>(a: T, b: U) -> Expr<S>
337    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
338{
339    Rel(Box::new(a.into()), Box::new(b.into()))
340}
341
342/// Constructs a 1-avatar expression, e.g. `p'(a)`.
343pub fn ava<T, U, S>(a: T, b: U) -> Expr<S>
344    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
345{
346    Ava(Box::new(a.into()), Box::new(b.into()))
347}
348
349/// Constructs an equality expression.
350pub fn eq<T, U, S>(a: T, b: U) -> Expr<S>
351    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
352{
353    Eq(Box::new(a.into()), Box::new(b.into()))
354}
355
356/// Constructs an inequality expression.
357pub fn neq<T, U, S>(a: T, b: U) -> Expr<S>
358    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
359{
360    Neq(Box::new(a.into()), Box::new(b.into()))
361}
362
363/// Constructs a "has" expression e.g. `p(a) => b`.
364pub fn has<T, U, S>(a: T, b: U) -> Expr<S>
365    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
366{
367    Has(Box::new(a.into()), Box::new(b.into()))
368}
369
370/// Constructs an apply expression.
371pub fn app<T, U, S>(a: T, b: U) -> Expr<S>
372    where T: Into<Expr<S>>, U: Into<Expr<S>>, S: Symbol
373{
374    App(Box::new(a.into()), Box::new(b.into()))
375}
376
377/// Constructs an inner expression e.g. `.p'(a) = a`.
378pub fn inner<T: Into<Expr<S>>, S: Symbol>(a: T) -> Expr<S> {
379    Inner(Box::new(a.into()))
380}
381
382/// Constructs an ambiguous role expression.
383pub fn ambiguous_role<T, U, V, S>(a: T, b: U, c: V) -> Expr<S>
384    where T: Into<Expr<S>>, U: Into<Expr<S>>, V: Into<Expr<S>>, S: Symbol
385{
386    let b = b.into();
387    let c = c.into();
388    let (b, c) = if b < c {(b, c)} else {(c, b)};
389    AmbiguousRole(Box::new(a.into()), Box::new(b), Box::new(c))
390}
391
392/// Constructs an ambiguous relation expression.
393pub fn ambiguous_rel<T, U, V, S>(a: T, b: U, c: V) -> Expr<S>
394    where T: Into<Expr<S>>, U: Into<Expr<S>>, V: Into<Expr<S>>, S: Symbol
395{
396    let b = b.into();
397    let c = c.into();
398    let (b, c) = if b < c {(b, c)} else {(c, b)};
399    AmbiguousRel(Box::new(a.into()), Box::new(b), Box::new(c))
400}
401
402impl<T: Symbol> Expr<T> {
403    /// Lifts apply with an eval role.
404    pub fn eval_lift(&self, eval: &T, top: bool) -> Expr<T> {
405        match self {
406            Rel(a, b) => rel(a.eval_lift(eval, true), b.eval_lift(eval, true)),
407            App(a, b) => {
408                if top {
409                    app(a.eval_lift(eval, true), b.eval_lift(eval, false))
410                } else {
411                    app(Sym(eval.clone()),
412                        app(a.eval_lift(eval, true), b.eval_lift(eval, false))
413                    )
414                }
415            }
416            Rule(res, arg) => {
417                let new_res = res.eval_lift(eval, true);
418                let new_arg: Vec<Expr<T>> = arg.iter().map(|a| a.eval_lift(eval, true)).collect();
419                Rule(Box::new(new_res), new_arg)
420            }
421            Sym(_) | Var(_) => self.clone(),
422            UniqAva(_) => self.clone(),
423            Ambiguity(_) => self.clone(),
424            Tail => self.clone(),
425            TailVar(_) => self.clone(),
426            RoleOf(a, b) => {
427                role_of(a.eval_lift(eval, false), b.eval_lift(eval, false))
428            }
429            Ava(a, b) => ava((**a).clone(), b.eval_lift(eval, false)),
430            Inner(a) => inner(a.eval_lift(eval, false)),
431            Eq(a, b) => {
432                if let App(a1, a2) = &**a {
433                    eq(app((**a1).clone(), a2.eval_lift(eval, true)), b.eval_lift(eval, false))
434                } else {
435                    self.clone()
436                }
437            }
438            // TODO: Handle these cases.
439            Neq(_, _) => self.clone(),
440            Has(_, _) => self.clone(),
441            AmbiguousRole(_, _, _) => self.clone(),
442            AmbiguousRel(_, _, _) => self.clone(),
443            List(_) => self.clone(),
444            // _ => unimplemented!("{:?}", self)
445        }
446    }
447
448    /// Returns `true` if expression contains no variables.
449    pub fn is_const(&self) -> bool {
450        match self {
451            Var(_) => false,
452            Sym(_) => true,
453            App(ref a, ref b) => a.is_const() && b.is_const(),
454            Ava(ref a, ref b) => a.is_const() && b.is_const(),
455            _ => false
456        }
457    }
458
459    /// Returns `true` if expression is a tail pattern.
460    pub fn is_tail(&self) -> bool {
461        match self {
462            Tail | TailVar(_) => true,
463            _ => false
464        }
465    }
466
467    /// Returns the number of arguments in apply expression.
468    pub fn arity(&self) -> usize {
469        if let App(a, _) = self {a.arity() + 1} else {0}
470    }
471}
472
473/// Bind `a` to pattern `e`.
474pub fn bind<T: Symbol>(
475    e: &Expr<T>,
476    a: &Expr<T>,
477    vs: &mut Vec<(Arc<String>, Expr<T>)>,
478    tail: &mut Vec<Expr<T>>
479) -> bool {
480    match (e, a) {
481        (&Rel(ref a1, ref b1), &Rel(ref a2, ref b2)) => {
482            bind(a1, a2, vs, tail) &&
483            bind(b1, b2, vs, tail)
484        }
485        (&RoleOf(ref a1, ref b1), &RoleOf(ref a2, ref b2)) => {
486            bind(a1, a2, vs, tail) &&
487            bind(b1, b2, vs, tail)
488        }
489        (&Eq(ref a1, ref b1), &Eq(ref a2, ref b2)) => {
490            bind(a1, a2, vs, tail) &&
491            bind(b1, b2, vs, tail)
492        }
493        (&Has(ref a1, ref b1), &Has(ref a2, ref b2)) => {
494            bind(a1, a2, vs, tail) &&
495            bind(b1, b2, vs, tail)
496        }
497        (&App(ref a1, ref b1), &App(ref a2, ref b2)) if b1.is_tail() &&
498            a2.arity() >= a1.arity() && b2.is_const() => {
499            tail.push((**b2).clone());
500            if a2.arity() > a1.arity() {
501                bind(e, a2, vs, tail)
502            } else {
503                bind(a1, a2, vs, tail) &&
504                if let TailVar(b1_sym) = &**b1 {
505                    if tail.len() > 0 {
506                        tail.reverse();
507                        vs.push((b1_sym.clone(), List(tail.clone())));
508                        tail.clear();
509                        true
510                    } else {
511                        tail.clear();
512                        false
513                    }
514                } else {
515                    true
516                }
517            }
518        }
519        (&App(ref a1, ref b1), &App(ref a2, ref b2)) => {
520            bind(a1, a2, vs, tail) &&
521            bind(b1, b2, vs, tail)
522        }
523        (&Sym(ref a1), &Sym(ref a2)) => a1 == a2,
524        (&Var(ref a1), &Sym(_)) => {
525            // Look for previous occurences of bound variable.
526            let mut found = false;
527            for &(ref b, ref b_expr) in &*vs {
528                if b == a1 {
529                    if let Some(true) = equal(b_expr, a) {
530                        found = true;
531                        break;
532                    } else {
533                        return false;
534                    }
535                }
536            }
537            if !found {
538                vs.push((a1.clone(), a.clone()));
539            }
540            true
541        }
542        (&Var(ref a1), _) if a.is_const() => {
543            vs.push((a1.clone(), a.clone()));
544            true
545        }
546        (&Ava(ref a1, ref b1), &Ava(ref a2, ref b2)) => {
547            bind(a1, a2, vs, tail) &&
548            bind(b1, b2, vs, tail)
549        }
550        _ => false
551    }
552}
553
554fn substitute<T: Symbol>(r: &Expr<T>, vs: &Vec<(Arc<String>, Expr<T>)>) -> Expr<T> {
555    match r {
556        Rel(a1, b1) => {
557            rel(substitute(a1, vs), substitute(b1, vs))
558        }
559        Var(a1) => {
560            for v in vs {
561                if &v.0 == a1 {
562                    return v.1.clone();
563                }
564            }
565            r.clone()
566        }
567        Sym(_) => r.clone(),
568        Ava(a1, b1) => {
569            ava(substitute(a1, vs), substitute(b1, vs))
570        }
571        RoleOf(a, b) => {
572            role_of(substitute(a, vs), substitute(b, vs))
573        }
574        Eq(a, b) => {
575            eq(substitute(a, vs), substitute(b, vs))
576        }
577        Neq(a, b) => {
578            neq(substitute(a, vs), substitute(b, vs))
579        }
580        Has(a, b) => {
581            has(substitute(a, vs), substitute(b, vs))
582        }
583        App(a, b) => {
584            let a_expr = substitute(a, vs);
585            if let Var(a1) = &**b {
586                for v in vs {
587                    if &v.0 == a1 {
588                        if let List(args) = &v.1 {
589                            let mut expr = a_expr;
590                            for arg in args {
591                                expr = app(expr, arg.clone());
592                            }
593                            return expr;
594                        }
595                    }
596                }
597            }
598            app(a_expr, substitute(b, vs))
599        }
600        Ambiguity(_) => r.clone(),
601        UniqAva(a) => {
602            uniq_ava(substitute(a, vs))
603        }
604        Inner(a) => {
605            inner(substitute(a, vs))
606        }
607        x => unimplemented!("{:?}", x)
608    }
609}
610
611// Returns `Some(true)` if two expressions are proven to be equal,
612// `Some(false)` when proven to be inequal, and `None` when unknown.
613fn equal<T: Symbol>(a: &Expr<T>, b: &Expr<T>) -> Option<bool> {
614    fn false_or_none(val: Option<bool>) -> bool {
615        if let Some(val) = val {!val} else {true}
616    }
617
618    if a.is_const() && b.is_const() {Some(a == b)}
619    else {
620        match (a, b) {
621            (&Sym(_), &Sym(_)) |
622            (&Sym(_), &Var(_)) | (&Var(_), &Sym(_)) |
623            (&Var(_), &Var(_)) |
624            (&Var(_), &Ava(_, _)) | (&Ava(_, _), &Var(_)) |
625            (&App(_, _), &Sym(_)) | (&Sym(_), &App(_, _)) |
626            (&App(_, _), &Var(_)) | (&Var(_), &App(_, _)) |
627            (&App(_, _), &Ava(_, _)) | (&Ava(_, _), &App(_, _)) => None,
628            (&Sym(_), &Ava(_, _)) | (&Ava(_, _), &Sym(_)) => Some(false),
629            (&Ava(ref a1, ref b1), &Ava(ref a2, ref b2)) |
630            (&App(ref a1, ref b1), &App(ref a2, ref b2)) => {
631                let cmp_a = equal(a1, a2);
632                if false_or_none(cmp_a) {return cmp_a};
633                equal(b1, b2)
634            }
635            // TODO: Handle other cases.
636            x => unimplemented!("{:?}", x)
637        }
638    }
639}
640
641fn match_rule<T: Symbol>(r: &Expr<T>, rel: &Expr<T>) -> Option<Expr<T>> {
642    if let Rule(res, args) = r {
643        let mut vs = vec![];
644        let mut tail: Vec<Expr<T>> = vec![];
645        if bind(&args[0], rel, &mut vs, &mut tail) {
646            if args.len() > 1 {
647                let mut new_args = vec![];
648                for e in &args[1..] {
649                    let new_e = substitute(e, &vs);
650                    if let Neq(a, b) = &new_e {
651                        match equal(a, b) {
652                            Some(true) => return None,
653                            Some(false) => continue,
654                            None => {}
655                        }
656                    }
657                    new_args.push(new_e);
658                }
659                let new_res = substitute(res, &vs);
660                if new_args.len() > 0 {
661                    return Some(Rule(Box::new(new_res), new_args));
662                } else {
663                    return Some(new_res);
664                }
665            } else {
666                let new_res = substitute(res, &vs);
667                return Some(new_res);
668            }
669        }
670        None
671    } else {
672        None
673    }
674}
675
676fn apply<T: Symbol>(e: &Expr<T>, facts: &[Expr<T>]) -> Option<Expr<T>> {
677    match e {
678        App(a, b) => {
679            for e2 in facts {
680                if let Eq(b2, b3) = e2 {
681                    if &**b2 == e {
682                        return Some((**b3).clone());
683                    }
684                }
685            }
686
687            match (apply(a, facts), apply(b, facts)) {
688                (Some(a), Some(b)) => return Some(app(a, b)),
689                (None, Some(b)) => return Some(app((**a).clone(), b)),
690                (Some(a), None) => return Some(app(a, (**b).clone())),
691                (None, None) => {}
692            }
693        }
694        Rel(a, b) => {
695            match (apply(a, facts), apply(b, facts)) {
696                (Some(a), Some(b)) => return Some(rel(a, b)),
697                (None, Some(b)) => return Some(rel((**a).clone(), b)),
698                (Some(a), None) => return Some(rel(a, (**b).clone())),
699                (None, None) => {}
700            }
701        }
702        Ava(a, b) => {
703            match (apply(a, facts), apply(b, facts)) {
704                (Some(a), Some(b)) => return Some(ava(a, b)),
705                (None, Some(b)) => return Some(ava((**a).clone(), b)),
706                (Some(a), None) => return Some(ava(a, (**b).clone())),
707                (None, None) => {}
708            }
709        }
710        Eq(a, b) => {
711            let new_b = apply(b, facts)?;
712            return Some(eq((**a).clone(), new_b))
713        }
714        Has(a, b) => {
715            let new_b = apply(b, facts)?;
716            return Some(has((**a).clone(), new_b))
717        }
718        Inner(a) => {
719            let new_a = apply(a, facts);
720            if new_a.is_some() {return new_a.map(|n| inner(n))};
721            if let Ava(_, b) = &**a {
722                if let Some(new_b) = apply(b, facts) {
723                    return Some(new_b);
724                } else {
725                    return Some((**b).clone());
726                }
727            } else {
728                return Some(inner(apply(a, facts)?));
729            }
730        }
731        _ => {}
732    }
733    None
734}
735
736/// Index of sub-expressions.
737pub struct Accelerator<T: Symbol> {
738    /// Index for each sub-expression.
739    pub index: HashMap<Expr<T>, Vec<usize>>,
740    /// The number of facts that has been indexed.
741    pub len: usize,
742    /// The index of the last rule.
743    pub last_rule: Option<usize>,
744}
745
746impl<T: Symbol> Accelerator<T> {
747    /// Creates a new accelerator.
748    pub fn new() -> Accelerator<T> {
749        Accelerator {index: HashMap::new(), len: 0, last_rule: None}
750    }
751
752    /// Returns a constructor for solve-and-reduce.
753    pub fn constructor() -> fn(&[Expr<T>], &[Expr<T>]) -> Accelerator<T> {
754        |_, _| Accelerator::new()
755    }
756
757    /// Updates the accelerator with list of facts.
758    pub fn update(&mut self, facts: &[Expr<T>])
759        where T: Clone + std::hash::Hash + std::cmp::Eq
760    {
761        let accelerator_len = self.len;
762        let ref mut index = self.index;
763        let mut insert = |i: usize, e: &Expr<T>| {
764            index.entry(e.clone()).or_insert(vec![]).push(i);
765        };
766        for (i, e) in facts[accelerator_len..].iter().enumerate() {
767            let i = i + accelerator_len;
768            match e {
769                RoleOf(a, b) | Rel(a, b) | Ava(a, b) | Eq(a, b) |
770                Neq(a, b) | Has(a, b) | App(a, b) => {
771                    insert(i, a);
772                    insert(i, b);
773                }
774                Sym(_) | Var(_) | Inner(_) | UniqAva(_) => {
775                    insert(i, e);
776                }
777                AmbiguousRel(_, _, _) |
778                AmbiguousRole(_, _, _) |
779                Rule(_, _) |
780                Ambiguity(_) |
781                Tail | TailVar(_) | List(_) => {}
782            }
783        }
784        self.len = facts.len();
785    }
786}
787
788/// Specifies inference rules for monotonic solver.
789pub fn infer<T: Symbol>(
790    solver: Solver<Expr<T>, Accelerator<T>>,
791    facts: &[Expr<T>]
792) -> Option<Expr<T>> {
793    // Build an index to improve worst-case performance.
794    solver.accelerator.update(facts);
795    let find = |e: &Expr<T>| {
796        solver.accelerator.index.get(e).unwrap().iter().map(|&i| &facts[i])
797    };
798
799    for e in facts.iter().rev() {
800        // Detect ambiguous roles.
801        if let RoleOf(a, b) = e {
802            for e2 in find(a) {
803                if let RoleOf(a2, b2) = e2 {
804                    if a2 == a && b2 != b {
805                        let new_expr = ambiguous_role((**a).clone(), (**b).clone(), (**b2).clone());
806                        if solver.can_add(&new_expr) {return Some(new_expr)};
807
808                        let new_expr = Ambiguity(true);
809                        if solver.can_add(&new_expr) {return Some(new_expr)};
810                    }
811                }
812            }
813        }
814
815        // Convert 'has' into 'eq' using uniqueness.
816        if let Has(a, b) = e {
817            if let Ava(b1, _) = &**b {
818                // `p(a) => q'(b), uniq q   =>   p(a) = q'(b)`
819                let uniq_expr = uniq_ava((**b1).clone());
820                if solver.cache.contains(&uniq_expr) {
821                    let new_expr = eq((**a).clone(), (**b).clone());
822                    if solver.can_add(&new_expr) {return Some(new_expr)};
823                }
824            } else {
825                // `p(a) => b   =>   p(a) = b`
826                let new_expr = eq((**a).clone(), (**b).clone());
827                if solver.can_add(&new_expr) {return Some(new_expr)};
828            }
829        }
830
831        // Convert 'eq' into 'has'.
832        if let Eq(a, b) = e {
833            let new_expr = has((**a).clone(), (**b).clone());
834            if solver.can_add(&new_expr) {return Some(new_expr)};
835        }
836
837        if let Rel(a, b) = e {
838            if let Ava(av, _) = &**b {
839                // Avatar Binary Relation.
840                let mut b_role: Option<Expr<T>> = None;
841                let mut uniq = false;
842                for e2 in find(b) {
843                    if let RoleOf(b2, r) = e2 {
844                        if b2 == b {
845                            if solver.cache.contains(&uniq_ava((**av).clone())) {
846                                uniq = true;
847                                let new_expr = eq(app((**r).clone(), (**a).clone()), (**b).clone());
848                                if solver.can_add(&new_expr) {return Some(new_expr)};
849                            }
850
851                            let new_expr = has(app((**r).clone(), (**a).clone()), (**b).clone());
852                            if solver.can_add(&new_expr) {return Some(new_expr)};
853                            b_role = Some((**r).clone());
854                        }
855                    }
856                }
857
858                // Look for another avatar relation with same role.
859                if let Some(b_role) = &b_role {
860                    for e1 in find(a) {
861                        if let Rel(a2, b2) = e1 {
862                            if a2 == a && b2 != b {
863                                if let Ava(av2, _) = &**b2 {
864                                    if uniq || av2 != av {
865                                        for e2 in find(b2) {
866                                            if let RoleOf(a3, b3) = e2 {
867                                                if a3 == b2 && &**b3 == b_role {
868                                                    let new_expr = ambiguous_rel((**a).clone(),
869                                                        (**b).clone(), (**b2).clone());
870                                                    if solver.can_add(&new_expr) {
871                                                        return Some(new_expr)
872                                                    }
873
874                                                    let new_expr = Ambiguity(true);
875                                                    if solver.can_add(&new_expr) {
876                                                        return Some(new_expr)
877                                                    }
878                                                }
879                                            }
880                                        }
881                                    }
882                                }
883                            }
884                        }
885                    }
886                }
887            } else {
888                // Unique Universal Binary Relation.
889                let mut b_role: Option<Expr<T>> = None;
890                for e2 in find(b) {
891                    if let RoleOf(b2, r) = e2 {
892                        if b2 == b {
893                            let new_expr = eq(app((**r).clone(), (**a).clone()), (**b).clone());
894                            if solver.can_add(&new_expr) {return Some(new_expr)};
895                            let new_expr = has(app((**r).clone(), (**a).clone()), (**b).clone());
896                            if solver.can_add(&new_expr) {return Some(new_expr)};
897                            b_role = Some((**r).clone());
898                        }
899                    }
900                }
901
902                // Look for another relation with same role.
903                if let Some(b_role) = &b_role {
904                    for e1 in find(a) {
905                        if let Rel(a2, b2) = e1 {
906                            if a2 == a && b2 != b {
907                                if solver.cache.contains(&role_of((**b2).clone(), b_role.clone())) {
908                                    let new_expr = ambiguous_rel((**a).clone(),
909                                        (**b).clone(), (**b2).clone());
910                                    if solver.can_add(&new_expr) {return Some(new_expr)};
911
912                                    let new_expr = Ambiguity(true);
913                                    if solver.can_add(&new_expr) {return Some(new_expr)};
914                                }
915                            }
916                        }
917                    }
918                }
919            }
920        }
921    }
922
923    for e in facts {
924        if let Some(new_expr) = apply(e, facts) {
925            if solver.can_add(&new_expr) {return Some(new_expr)};
926        }
927    }
928
929    match solver.accelerator.last_rule {
930        None => {
931            // Normal rule order.
932            for (i, e) in facts.iter().enumerate() {
933                if let Rule(_, _) = e {
934                    for e2 in facts {
935                        if let Some(new_expr) = match_rule(e, e2) {
936                            solver.accelerator.last_rule = Some(i);
937                            if solver.can_add(&new_expr) {return Some(new_expr)};
938                        }
939                    }
940                }
941            }
942        }
943        Some(i) => {
944            // Diagonalize rules.
945            // Start with the next rule.
946            for (j, e) in facts[i + 1..].iter().enumerate() {
947                if let Rule(_, _) = e {
948                    for e2 in facts {
949                        if let Some(new_expr) = match_rule(e, e2) {
950                            solver.accelerator.last_rule = Some(i + 1 + j);
951                            if solver.can_add(&new_expr) {return Some(new_expr)};
952                        }
953                    }
954                }
955            }
956            // Try previous used rules.
957            for (j, e) in facts[..i + 1].iter().enumerate() {
958                if let Rule(_, _) = e {
959                    for e2 in facts {
960                        if let Some(new_expr) = match_rule(e, e2) {
961                            solver.accelerator.last_rule = Some(j);
962                            if solver.can_add(&new_expr) {return Some(new_expr)};
963                        }
964                    }
965                }
966            }
967        }
968    }
969
970    if !solver.cache.contains(&Ambiguity(true)) {
971        let mut amb = false;
972        for e in facts {
973            if let AmbiguousRel(_, _, _) = e {
974                amb = true;
975                break;
976            } else if let AmbiguousRole(_, _, _) = e {
977                amb = true;
978                break;
979            }
980        }
981        let new_expr = Ambiguity(amb);
982        if solver.can_add(&new_expr) {return Some(new_expr)};
983    }
984    None
985}