fn dot_op_helper(&mut self, term: &Term) -> PolarResult<QueryEvent> {
        let Operation { operator: op, args } = term.value().as_expression().unwrap();
        assert_eq!(*op, Operator::Dot, "expected a dot operation");

        let mut args = args.clone();
        assert_eq!(args.len(), 3);
        let object = &args[0];
        let field = &args[1];
        let value = &args[2];

        match object.value() {
            // Push a `Lookup` goal for simple field lookups on dictionaries.
            Value::Dictionary(dict)
                if matches!(field.value(), Value::String(_) | Value::Variable(_)) =>
            {
                self.push_goal(Goal::Lookup {
                    dict: dict.clone(),
                    field: field.clone(),
                    value: args.remove(2),
                })?
            }
            // Push an `ExternalLookup` goal for external instances and built-ins.
            Value::Dictionary(_)
            | Value::ExternalInstance(_)
            | Value::List(_)
            | Value::Number(_)
            | Value::String(_) => {
                // handle partial arguments to an external call
                if let Some(constraint_term) = self.check_partial_args(object, field, value)? {
                    // if there is a valid partial argument, it means we have a special case handler, so don't call out to the method
                    self.add_constraint(&constraint_term)?;
                    return Ok(QueryEvent::None);
                }
                let value = value
                    .value()
                    .as_symbol()
                    .map_err(|mut e| {
                        e.add_stack_trace(self);
                        e
                    })
                    .expect("bad lookup value");
                let call_id = self.new_call_id(value);
                self.append_goals(vec![
                    Goal::LookupExternal {
                        call_id,
                        field: field.clone(),
                        instance: object.clone(),
                    },
                    Goal::CheckError,
                ])?;
            }
            Value::Variable(v) => {
                if matches!(field.value(), Value::Call(_)) {
                    return Err(self.set_error_context(
                        object,
                        error::RuntimeError::Unsupported {
                            msg: format!("cannot call method on unbound variable {}", v),
                        },
                    ));
                }

                // Translate `.(object, field, value)` → `value = .(object, field)`.
                let dot2 = op!(Dot, object.clone(), field.clone());
                self.add_constraint(&op!(Unify, value.clone(), dot2.into_term()).into_term())?;
            }
            _ => {
                return Err(self.type_error(
                    &object,
                    format!(
                        "can only perform lookups on dicts and instances, this is {}",
                        object.to_polar()
                    ),
                ))
            }
        }
        Ok(QueryEvent::None)
    }
/// Push appropriate goals for lookups on dictionaries and instances.
Push appropriate goals for lookups on dictionaries and instances.
Push appropriate goals for lookups on dictionaries and instances .
fn dot_op_helper(&mut self, term: &Term) -> PolarResult<QueryEvent> {
        let Operation { operator: op, args } = term.value().as_expression().unwrap();
        assert_eq!(*op, Operator::Dot, "expected a dot operation");
        let mut args = args.clone();
        assert_eq!(args.len(), 3);
        let object = &args[0];
        let field = &args[1];
        let value = &args[2];
        match object.value() {
            // Push a `Lookup` goal for simple field lookups on dictionaries.
            Value::Dictionary(dict)
                if matches!(field.value(), Value::String(_) | Value::Variable(_)) =>
            {
                self.push_goal(Goal::Lookup {
                    dict: dict.clone(),
                    field: field.clone(),
                    value: args.remove(2),
                })?
            }
            // Push an `ExternalLookup` goal for external instances and built-ins.
            Value::Dictionary(_)
            | Value::ExternalInstance(_)
            | Value::List(_)
            | Value::Number(_)
            | Value::String(_) => {
                // handle partial arguments to an external call
                if let Some(constraint_term) = self.check_partial_args(object, field, value)? {
                    // if there is a valid partial argument, it means we have a special case handler, so don't call out to the method
                    self.add_constraint(&constraint_term)?;
                    return Ok(QueryEvent::None);
                }
                let value = value
                    .value()
                    .as_symbol()
                    .map_err(|mut e| {
                        e.add_stack_trace(self);
                        e
                    })
                    .expect("bad lookup value");
                let call_id = self.new_call_id(value);
                self.append_goals(vec![
                    Goal::LookupExternal {
                        call_id,
                        field: field.clone(),
                        instance: object.clone(),
                    },
                    Goal::CheckError,
                ])?;
            }
            Value::Variable(v) => {
                if matches!(field.value(), Value::Call(_)) {
                    return Err(self.set_error_context(
                        object,
                        error::RuntimeError::Unsupported {
                            msg: format!("cannot call method on unbound variable {}", v),
                        },
                    ));
                }
                // Translate `.(object, field, value)` → `value = .(object, field)`.
                let dot2 = op!(Dot, object.clone(), field.clone());
                self.add_constraint(&op!(Unify, value.clone(), dot2.into_term()).into_term())?;
            }
            _ => {
                return Err(self.type_error(
                    &object,
                    format!(
                        "can only perform lookups on dicts and instances, this is {}",
                        object.to_polar()
                    ),
                ))
            }
        }
        Ok(QueryEvent::None)
    }
fn dot_op_helper ( & mut self , term : & Term ) -> PolarResult < QueryEvent > { let Operation { operator : op , args } = term . value ( ) . as_expression ( ) . unwrap ( ) ; assert_eq ! ( op Operator Dot " " ) ; let mut args = args . clone ( ) ; assert_eq ! ( args len ( ) 3 ) ; let object = & args [ 0 ] ; let field = & args [ 1 ] ; let value = & args [ 2 ] ; match object . value ( ) { // Push a `Lookup` goal for simple field lookups on dictionaries. Value :: Dictionary ( dict ) if matches ! ( field value ( ) Value String ( ) Value Variable ( ) ) => { self . push_goal ( Goal :: Lookup { dict : dict . clone ( ) , field : field . clone ( ) , value : args . remove ( 2 ) , } ) ? } // Push an `ExternalLookup` goal for external instances and built-ins. Value :: Dictionary ( _ ) | Value :: ExternalInstance ( _ ) | Value :: List ( _ ) | Value :: Number ( _ ) | Value :: String ( _ ) => { // handle partial arguments to an external call if let Some ( constraint_term ) = self . check_partial_args ( object , field , value ) ? { // if there is a valid partial argument, it means we have a special case handler, so don't call out to the method self . add_constraint ( & constraint_term ) ? ; return Ok ( QueryEvent :: None ) ; } let value = value . value ( ) . as_symbol ( ) . map_err ( | mut e | { e . add_stack_trace ( self ) ; e } ) . expect ( " " ) ; let call_id = self . new_call_id ( value ) ; self . append_goals ( vec ! [ Goal LookupExternal { call_id field field clone ( ) instance object clone ( ) } Goal CheckError ] ) ? ; } Value :: Variable ( v ) => { if matches ! ( field value ( ) Value Call ( ) ) { return Err ( self . set_error_context ( object , error :: RuntimeError :: Unsupported { msg : format ! ( " " v ) , } , ) ) ; } // Translate `.(object, field, value)` → `value = .(object, field)`. let dot2 = op ! ( Dot object clone ( ) field clone ( ) ) ; self . add_constraint ( & op ! ( Unify value clone ( ) dot2 into_term ( ) ) . into_term ( ) ) ? ; } _ => { return Err ( self . type_error ( & object , format ! ( " " object to_polar ( ) ) , ) ) } } Ok ( QueryEvent :: None ) }
Push appropriate goals for lookups on dictionaries and instances.
Push appropriate goals for lookups on dictionaries and instances .
&mut self
term
&Term