fn query(&mut self, term: &Term) -> PolarResult<QueryEvent> {
        // Don't log if it's just a single element AND like lots of rule bodies tend to be.
        match &term.value() {
            Value::Expression(Operation {
                operator: Operator::And,
                args,
            }) if args.len() < 2 => (),
            _ => {
                self.log_with(|| format!("QUERY: {}", term.to_polar()), &[term]);
            }
        };

        self.queries.push(term.clone());
        self.push_goal(Goal::PopQuery { term: term.clone() })?;
        self.trace.push(Rc::new(Trace {
            node: Node::Term(term.clone()),
            children: vec![],
        }));

        match &term.value() {
            Value::Call(predicate) => {
                self.query_for_predicate(predicate.clone())?;
            }
            Value::Expression(_) => {
                return self.query_for_operation(&term);
            }
            Value::Variable(_a_symbol) => {
                let val = self.deref(term);

                if val == *term {
                    // variable was unbound
                    // apply a constraint to variable that it must be truthy
                    self.push_goal(Goal::Unify {
                        left: term.clone(),
                        right: term!(true),
                    })?;
                } else {
                    self.push_goal(Goal::Query { term: val })?;
                }
            }
            Value::Boolean(value) => {
                if !value {
                    // Backtrack if the boolean is false.
                    self.push_goal(Goal::Backtrack)?;
                }

                return Ok(QueryEvent::None);
            }
            _ => {
                // everything else dies horribly and in pain
                return Err(self.type_error(
                    &term,
                    format!(
                        "{} isn't something that is true or false so can't be a condition",
                        term.value().to_polar()
                    ),
                ));
            }
        }
        Ok(QueryEvent::None)
    }
/// Query for the provided term.
///
/// Uses the knowledge base to get an ordered list of rules.
/// Creates a choice point over each rule, where each alternative
/// consists of unifying the rule head with the arguments, then
/// querying for each body clause.
Query for the provided term.
Uses the knowledge base to get an ordered list of rules.
Creates a choice point over each rule, where each alternative
consists of unifying the rule head with the arguments, then
querying for each body clause.
Query for the provided term . Uses the knowledge base to get an ordered list of rules . Creates a choice point over each rule where each alternative consists of unifying the rule head with the arguments then querying for each body clause .
fn query(&mut self, term: &Term) -> PolarResult<QueryEvent> {
        // Don't log if it's just a single element AND like lots of rule bodies tend to be.
        match &term.value() {
            Value::Expression(Operation {
                operator: Operator::And,
                args,
            }) if args.len() < 2 => (),
            _ => {
                self.log_with(|| format!("QUERY: {}", term.to_polar()), &[term]);
            }
        };
        self.queries.push(term.clone());
        self.push_goal(Goal::PopQuery { term: term.clone() })?;
        self.trace.push(Rc::new(Trace {
            node: Node::Term(term.clone()),
            children: vec![],
        }));
        match &term.value() {
            Value::Call(predicate) => {
                self.query_for_predicate(predicate.clone())?;
            }
            Value::Expression(_) => {
                return self.query_for_operation(&term);
            }
            Value::Variable(_a_symbol) => {
                let val = self.deref(term);
                if val == *term {
                    // variable was unbound
                    // apply a constraint to variable that it must be truthy
                    self.push_goal(Goal::Unify {
                        left: term.clone(),
                        right: term!(true),
                    })?;
                } else {
                    self.push_goal(Goal::Query { term: val })?;
                }
            }
            Value::Boolean(value) => {
                if !value {
                    // Backtrack if the boolean is false.
                    self.push_goal(Goal::Backtrack)?;
                }
                return Ok(QueryEvent::None);
            }
            _ => {
                // everything else dies horribly and in pain
                return Err(self.type_error(
                    &term,
                    format!(
                        "{} isn't something that is true or false so can't be a condition",
                        term.value().to_polar()
                    ),
                ));
            }
        }
        Ok(QueryEvent::None)
    }
fn query ( & mut self , term : & Term ) -> PolarResult < QueryEvent > { // Don't log if it's just a single element AND like lots of rule bodies tend to be. match & term . value ( ) { Value :: Expression ( Operation { operator : Operator :: And , args , } ) if args . len ( ) < 2 => ( ) , _ => { self . log_with ( | | format ! ( " " term to_polar ( ) ) , & [ term ] ) ; } } ; self . queries . push ( term . clone ( ) ) ; self . push_goal ( Goal :: PopQuery { term : term . clone ( ) } ) ? ; self . trace . push ( Rc :: new ( Trace { node : Node :: Term ( term . clone ( ) ) , children : vec ! [ ] , } ) ) ; match & term . value ( ) { Value :: Call ( predicate ) => { self . query_for_predicate ( predicate . clone ( ) ) ? ; } Value :: Expression ( _ ) => { return self . query_for_operation ( & term ) ; } Value :: Variable ( _a_symbol ) => { let val = self . deref ( term ) ; if val == * term { // variable was unbound // apply a constraint to variable that it must be truthy self . push_goal ( Goal :: Unify { left : term . clone ( ) , right : term ! ( true ) , } ) ? ; } else { self . push_goal ( Goal :: Query { term : val } ) ? ; } } Value :: Boolean ( value ) => { if ! value { // Backtrack if the boolean is false. self . push_goal ( Goal :: Backtrack ) ? ; } return Ok ( QueryEvent :: None ) ; } _ => { // everything else dies horribly and in pain return Err ( self . type_error ( & term , format ! ( " " term value ( ) to_polar ( ) ) , ) ) ; } } Ok ( QueryEvent :: None ) }
Query for the provided term.
Query for the provided term .
&mut self
term
&Term