vidi::util::search

Struct TextualUniverse

pub struct TextualUniverse {
    pub symbols: SymbolStore,
    pub rules: RuleSet,
}
Expand description

A universe that can be interacted with using a Prolog like syntax.

It builds on the [SymbolStore] and [RuleSet] abstractions and additionally provides a fully textual syntax for defining rules and queries, looking very similar to Prolog.

Syntactic elements:

  • Variables: An identifier starting with a upper case ASCII latter followed by zero or more ASCII letters, digits or underscores, e.g. X, Person, FooBar.
  • Symbols: An identifier starting with a lower case ASCII latter followed by zero or more ASCII letters, digits or underscores, e.g. foo, rightOf, is_natural.
  • Application Terms: An application of a functor to arguments, e.g. is_natural(X) or add(X, z, Y).
  • Facts: An application term followed by a dot, e.g. is_natural(z)..
  • Rules: An application term followed by :- (a reverse implication arrow) and a comma separated list of one or more conjunctive conditions, followed by a dot, e.g. grandparent(A, B) :- parent(A, C), parent(C, B)..
  • Queries: A comma separated list of one or more conjunctive conditions, followed by a dot, e.g. grandparent(bob, A), female(A)..

It doesn’t support comments and the moment, so that is probably a good idea for the future.

Besides functions for parsing, the textual universe also provides pretty-printing facilities.

§Example

Definitions of facts and rules can be loaded from a string that contains zero or more facts or rules as described above. In the following example, we define a set of Peano arithmetic rules and compute the first 5 square numbers.

let mut u = TextualUniverse::new();
u.load_str(
    r#"
is_natural(z).
is_natural(s(A)) :- is_natural(A).
add(A, z, A) :- is_natural(A).
add(A, s(B), s(C)) :- add(A, B, C).
mul(A, z, z) :- is_natural(A).
mul(A, s(B), C) :- mul(A, B, D), add(A, D, C).
"#,
)
.unwrap();

let query = u.prepare_query("mul(X,X,Y).").unwrap();
let solutions = query_dfs(u.resolver(), query.query());
for solution in solutions.take(5) {
    println!("SOLUTION:");
    for (var, term) in solution.iter_vars() {
        if let Some(term) = term {
            println!("  ${} = {}", var.ord(), query.pretty().term_to_string(&term));
        } else {
            println!("<bug: no solution>");
        }
    }
}

Fields§

§symbols: SymbolStore§rules: RuleSet

Implementations§

§

impl TextualUniverse

pub fn new() -> TextualUniverse

pub fn load_str(&mut self, rules: &str) -> Result<(), ParseError>

Load a set of rules from a string.

pub fn prepare_query( &self, query: &str, ) -> Result<UniverseQuery<'_>, ParseError>

Parse a query, but do not run it.

pub fn query_dfs( &mut self, query: &str, ) -> Result<SolutionIter<RuleResolver<'_>>, ParseError>

Run a query against the universe using the DFS solver.

§Notes

When you need access to the pretty printer while the solution iterator is still live, use Self::prepare_query instead. This method needs to take a mutable reference of the universe because parsing can discover new symbols that need to be added to the universe before running the query. Running a query by itself only requires a shared reference, and thus the pretty-printer is still accessible.

pub fn pretty(&self) -> Prettifier<'_, SymbolStore>

Return a pretty-printer using the symbols defined in this universe.

pub fn parse(&mut self) -> Parser<&mut SymbolStore>

Return a term parser that uses the name mapping of this universe for parsing terms.

pub fn resolver(&self) -> RuleResolver<'_>

Return a resolver for the internal rule database.

Trait Implementations§

Source§

impl Database for TextualUniverse

Source§

type Error = ParseError

Source§

fn empty() -> Self

Source§

fn add_facts(&mut self, facts: &str) -> Result<(), Self::Error>

Add a string containing Prolog facts
§

impl Default for TextualUniverse

§

fn default() -> TextualUniverse

Returns the “default value” for a type. Read more
Source§

impl From<ConfigsDatabase> for TextualUniverse

Source§

fn from(value: ConfigsDatabase) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more