Skip to content

Commit

Permalink
FFI for WMC with complex numbers (#191)
Browse files Browse the repository at this point in the history
* FFI for complex-valued WMC

* Remove dupe bdd_num_recursive_calls
  • Loading branch information
bamarsha authored Oct 15, 2024
1 parent 2ccf991 commit 9247bb6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 1 deletion.
54 changes: 53 additions & 1 deletion src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::os::raw::c_char;
use std::{collections::HashMap, ffi::CStr};

use crate::repr::DDNNFPtr;
use crate::util::semirings::{RealSemiring, Semiring};
use crate::util::semirings::{Complex, RealSemiring, Semiring};
use crate::{
builder::{bdd::RobddBuilder, cache::AllIteTable, BottomUpBuilder},
constants::primes,
Expand Down Expand Up @@ -270,12 +270,27 @@ pub unsafe extern "C" fn bdd_wmc(
DDNNFPtr::unsmoothed_wmc(&(*bdd), &(*wmc)).0
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn bdd_wmc_complex(
bdd: *mut BddPtr<'static>,
wmc: *mut WmcParams<Complex>,
) -> Complex {
DDNNFPtr::unsmoothed_wmc(&(*bdd), &(*wmc))
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn new_wmc_params_f64() -> *mut WmcParams<RealSemiring> {
Box::into_raw(Box::new(WmcParams::new(HashMap::from([]))))
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn new_wmc_params_complex() -> *mut WmcParams<Complex> {
Box::into_raw(Box::new(WmcParams::new(HashMap::from([]))))
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn wmc_param_f64_set_weight(
Expand All @@ -287,6 +302,17 @@ pub unsafe extern "C" fn wmc_param_f64_set_weight(
(*weights).set_weight(VarLabel::new(var), RealSemiring(low), RealSemiring(high))
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn wmc_param_complex_set_weight(
weights: *mut WmcParams<Complex>,
var: u64,
low: Complex,
high: Complex,
) {
(*weights).set_weight(VarLabel::new(var), low, high)
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct WeightF64(pub f64, pub f64);
Expand All @@ -312,3 +338,29 @@ pub unsafe extern "C" fn weight_f64_lo(w: WeightF64) -> f64 {
pub unsafe extern "C" fn weight_f64_hi(w: WeightF64) -> f64 {
w.1
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct WeightComplex(pub Complex, pub Complex);

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn wmc_param_complex_var_weight(
weights: *mut WmcParams<Complex>,
var: u64,
) -> WeightComplex {
let (l, h) = (*weights).var_weight(VarLabel::new(var));
WeightComplex(*l, *h)
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn weight_complex_lo(w: WeightComplex) -> Complex {
w.0
}

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn weight_complex_hi(w: WeightComplex) -> Complex {
w.1
}
65 changes: 65 additions & 0 deletions src/util/semirings/complex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use super::semiring_traits::*;
use std::{
fmt::{self, Display, Formatter},
ops::{Add, Mul, Sub},
};

#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
#[repr(C)]
pub struct Complex {
pub re: f64,
pub im: f64,
}

impl Display for Complex {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if self.im >= 0. {
write!(f, "{}+{}i", self.re, self.im)
} else {
write!(f, "{}{}i", self.re, self.im)
}
}
}

impl Add<Complex> for Complex {
type Output = Self;

fn add(self, rhs: Complex) -> Self::Output {
Self {
re: self.re + rhs.re,
im: self.im + rhs.im,
}
}
}

impl Mul<Complex> for Complex {
type Output = Self;

fn mul(self, rhs: Complex) -> Self::Output {
Self {
re: self.re * rhs.re - self.im * rhs.im,
im: self.re * rhs.im + self.im * rhs.re,
}
}
}

impl Sub<Complex> for Complex {
type Output = Self;

fn sub(self, rhs: Complex) -> Self::Output {
Self {
re: self.re - rhs.re,
im: self.im - rhs.im,
}
}
}

impl Semiring for Complex {
fn one() -> Self {
Self { re: 1.0, im: 0.0 }
}

fn zero() -> Self {
Self { re: 0.0, im: 0.0 }
}
}
2 changes: 2 additions & 0 deletions src/util/semirings/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod boolean;
mod complex;
mod expectation;
mod finitefield;
mod rational;
Expand All @@ -7,6 +8,7 @@ mod semiring_traits;
mod tropical;

pub use self::boolean::*;
pub use self::complex::*;
pub use self::expectation::*;
pub use self::finitefield::*;
pub use self::rational::*;
Expand Down

0 comments on commit 9247bb6

Please sign in to comment.