use std::collections::BTreeMap;
use graph::prelude::{page_rank, PageRankConfig};
use miette::Result;
use smartstring::{LazyCompact, SmartString};
use crate::data::expr::Expr;
use crate::data::symb::Symbol;
use crate::data::value::DataValue;
use crate::fixed_rule::{FixedRule, FixedRulePayload};
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
use crate::runtime::temp_store::RegularTempStore;
pub(crate) struct PageRank;
impl FixedRule for PageRank {
#[allow(unused_variables)]
fn run(
&self,
payload: FixedRulePayload<'_, '_>,
out: &mut RegularTempStore,
poison: Poison,
) -> Result<()> {
let edges = payload.get_input(0)?;
let undirected = payload.bool_option("undirected", Some(false))?;
let theta = payload.unit_interval_option("theta", Some(0.85))? as f32;
let epsilon = payload.unit_interval_option("epsilon", Some(0.0001))? as f32;
let iterations = payload.pos_integer_option("iterations", Some(10))?;
let (graph, indices, _) = edges.as_directed_graph(undirected)?;
if indices.is_empty() {
return Ok(());
}
let (ranks, _n_run, _) = page_rank(
&graph,
PageRankConfig::new(iterations, epsilon as f64, theta),
);
for (idx, score) in ranks.iter().enumerate() {
out.put(vec![indices[idx].clone(), DataValue::from(*score as f64)]);
}
Ok(())
}
fn arity(
&self,
_options: &BTreeMap<SmartString<LazyCompact>, Expr>,
_rule_head: &[Symbol],
_span: SourceSpan,
) -> Result<usize> {
Ok(2)
}
}