SNAPKITTYWEST's picture
push from SNAPKITTYWEST/carry-agent
80d7559 verified
Raw History Blame Contribute Delete
3.59 kB
// CARRY Quantum Execution DAG Module
// DAG representation of quantum multi-agent computation with strict node provenance.
use std::collections::HashMap;
/// Quantum DAG Node Type.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum QuantumDAGNodeType {
Input,
StatePreparation,
Entanglement,
AgentComputation,
PartnerVerification,
QuantumOperation,
Measurement,
ICPGate,
Commit,
}
/// Quantum DAG Node with provenance and metadata.
#[derive(Debug, Clone)]
pub struct QuantumDAGNode {
pub id: usize,
pub node_type: QuantumDAGNodeType,
pub label: String,
pub agent_id: String,
pub target_qubits: Vec<usize>,
pub provenance_hash: String,
pub parent_ids: Vec<usize>,
}
/// Quantum DAG Graph structure.
#[derive(Debug, Clone)]
pub struct QuantumDAG {
pub nodes: HashMap<usize, QuantumDAGNode>,
pub next_node_id: usize,
pub execution_order: Vec<usize>,
}
impl QuantumDAG {
pub fn new() -> Self {
Self {
nodes: HashMap::new(),
next_node_id: 1,
execution_order: Vec::new(),
}
}
/// Add a node to the DAG with edge provenance validation.
pub fn add_node(
&mut self,
node_type: QuantumDAGNodeType,
label: impl Into<String>,
agent_id: impl Into<String>,
target_qubits: Vec<usize>,
parent_ids: Vec<usize>,
) -> Result<usize, String> {
let label_str = label.into();
let agent_str = agent_id.into();
// Validate parents exist
for &parent_id in &parent_ids {
if !self.nodes.contains_key(&parent_id) {
return Err(format!("DAG_ERROR: Parent node {} does not exist", parent_id));
}
}
// Validate canonical DAG sequence invariants
if node_type == QuantumDAGNodeType::Commit {
let has_icp_parent = parent_ids.iter().any(|&p| {
self.nodes.get(&p).map(|n| n.node_type) == Some(QuantumDAGNodeType::ICPGate)
});
if !has_icp_parent {
return Err("INVALID_DAG_PATH: Commit node must be preceded by an ICP Gate node".into());
}
}
let id = self.next_node_id;
self.next_node_id += 1;
// Compute provenance hash
let provenance_hash = format!(
"NODE_{:?}_AG_{}_Q{:?}_P{:?}",
node_type, agent_str, target_qubits, parent_ids
);
let node = QuantumDAGNode {
id,
node_type,
label: label_str,
agent_id: agent_str,
target_qubits,
provenance_hash,
parent_ids,
};
self.nodes.insert(id, node);
self.execution_order.push(id);
Ok(id)
}
/// Validate complete execution path from Input to Commit.
pub fn validate_path(&self) -> Result<(), String> {
if self.execution_order.is_empty() {
return Err("DAG is empty".into());
}
let first = self.nodes.get(&self.execution_order[0]).unwrap();
if first.node_type != QuantumDAGNodeType::Input {
return Err("DAG path must start with Input node".into());
}
let last = self.nodes.get(self.execution_order.last().unwrap()).unwrap();
if last.node_type != QuantumDAGNodeType::Commit {
return Err("DAG path must terminate with Commit node".into());
}
Ok(())
}
}