reasoninglayer 0.2.1

Rust client SDK for the Reasoning Layer API
Documentation
//! Fuzzy operations DTOs.

use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

use super::terms::TermDto;
use super::values::ValueDto;

// ─── Unify ────────────────────────────────────────────────────────────────────

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FuzzyUnifyRequest {
    pub term1_id: String,
    pub term2_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub threshold: Option<f64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub similarity_mode: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub fail_on_unknown: Option<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FuzzyUnifyResponse {
    pub degree: f64,
    pub confidence_percent: f64,
    pub term: TermDto,
}

// ─── Merge ────────────────────────────────────────────────────────────────────

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FuzzyMergeRequest {
    pub term1_id: String,
    pub term2_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub strategy: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct FuzzyMergeResponse {
    pub computation_time_ms: u64,
    pub merged_features: u64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub strategy: Option<String>,
}

// ─── Subsumption ──────────────────────────────────────────────────────────────

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FuzzySubsumptionRequest {
    pub general_term_id: String,
    pub specific_term_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub threshold: Option<f64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FuzzySubsumptionResponse {
    pub degree: f64,
    pub subsumes: bool,
    pub computation_time_ms: u64,
}

// ─── Query term ───────────────────────────────────────────────────────────────

/// A fuzzy query term — either an existing term by UUID or an inline pattern.
///
/// Serialises with a `type` discriminator plus the variant's fields, matching the flat wire shape.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum QueryTerm {
    ById {
        term_id: String,
    },
    Inline {
        sort_id: String,
        features: BTreeMap<String, ValueDto>,
    },
}

// ─── Similarity search ────────────────────────────────────────────────────────

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FindSimilarRequest {
    /// Query term (flattened into the request body — the wire has `type`, `term_id`/`sort_id`,
    /// plus the similarity parameters).
    #[serde(flatten)]
    pub query: QueryTerm,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub min_degree: Option<f64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub similarity_mode: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub fail_on_unknown: Option<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FuzzySearchTopKRequest {
    #[serde(flatten)]
    pub query: QueryTerm,
    pub k: u32,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub min_degree: Option<f64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub similarity_mode: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub fail_on_unknown: Option<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimilarityMatch {
    pub confidence_percent: f64,
    pub degree: f64,
    pub term: TermDto,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SimilaritySearchResponse {
    #[serde(default)]
    pub count: u64,
    #[serde(default)]
    pub results: Vec<SimilarityMatch>,
}

// ─── Effect prediction ────────────────────────────────────────────────────────

/// Effect represented as a fuzzy number — externally tagged (`{"gaussian": {...}}`).
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum EffectDto {
    Gaussian { mean: f64, std_dev: f64 },
    Triangular { a: f64, b: f64, c: f64 },
    Trapezoidal { a: f64, b: f64, c: f64, d: f64 },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PredictEffectRequest {
    #[serde(flatten)]
    pub query: QueryTerm,
    pub effect_var: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub min_degree: Option<f64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub conformal: Option<f64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub robust: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub similarity_mode: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub gating: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PredictEffectResponse {
    pub degree: f64,
    pub success: bool,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub effect: Option<EffectDto>,
    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
    pub all_effects: BTreeMap<String, EffectDto>,
    #[serde(default)]
    pub proof_trace: Vec<String>,
    pub query_time_ms: u64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub source: Option<String>,
    #[serde(default)]
    pub sources_merged: u64,
}