mod datalog;
pub use datalog::Machine;
mod value_row;
mod results;
pub use results::{AnalysisResults, TailLoopTermination};
mod partial_value;
pub use partial_value::{AbstractValue, AsConcrete, LoadedFunction, PartialSum, PartialValue, Sum};
use hugr_core::ops::constant::OpaqueValue;
use hugr_core::ops::{ExtensionOp, Value};
pub trait DFContext<V>: ConstLoader<V> {
fn interpret_leaf_op(
&mut self,
_node: Self::Node,
_e: &ExtensionOp,
_ins: &[PartialValue<V, Self::Node>],
_outs: &mut [PartialValue<V, Self::Node>],
) {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ConstLocation<'a, N> {
Field(usize, &'a ConstLocation<'a, N>),
Node(N),
}
impl<N> From<N> for ConstLocation<'_, N> {
fn from(value: N) -> Self {
ConstLocation::Node(value)
}
}
pub trait ConstLoader<V> {
type Node;
fn value_from_opaque(&self, _loc: ConstLocation<Self::Node>, _val: &OpaqueValue) -> Option<V> {
None
}
}
pub fn partial_from_const<'a, V, CL: ConstLoader<V>>(
cl: &CL,
loc: impl Into<ConstLocation<'a, CL::Node>>,
cst: &Value,
) -> PartialValue<V, CL::Node>
where
CL::Node: 'a,
{
let loc = loc.into();
match cst {
Value::Sum(hugr_core::ops::constant::Sum { tag, values, .. }) => {
let elems = values
.iter()
.enumerate()
.map(|(idx, elem)| partial_from_const(cl, ConstLocation::Field(idx, &loc), elem));
PartialValue::new_variant(*tag, elems)
}
Value::Extension { e } => cl
.value_from_opaque(loc, e)
.map_or(PartialValue::Top, PartialValue::from),
}
}
pub fn row_contains_bottom<'a, V: 'a, N: 'a>(
elements: impl IntoIterator<Item = &'a PartialValue<V, N>>,
) -> bool {
elements.into_iter().any(PartialValue::contains_bottom)
}
#[cfg(test)]
mod test;