mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
feat(constraint_graph): make the constraint graph framework generic and move it into a separate crate (#3071)
This commit is contained in:
@ -4,11 +4,15 @@
|
||||
//! in the Euclid Rule DSL. These include standard control flow analyses like testing
|
||||
//! conflicting assertions, to Domain Specific Analyses making use of the
|
||||
//! [`Knowledge Graph Framework`](crate::dssa::graph).
|
||||
use hyperswitch_constraint_graph::{ConstraintGraph, Memoization};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use super::{graph::Memoization, types::EuclidAnalysable};
|
||||
use crate::{
|
||||
dssa::{graph, state_machine, truth, types},
|
||||
dssa::{
|
||||
graph::CgraphExt,
|
||||
state_machine, truth,
|
||||
types::{self, EuclidAnalysable},
|
||||
},
|
||||
frontend::{
|
||||
ast,
|
||||
dir::{self, EuclidDirFilter},
|
||||
@ -203,12 +207,12 @@ fn perform_condition_analyses(
|
||||
|
||||
fn perform_context_analyses(
|
||||
context: &types::ConjunctiveContext<'_>,
|
||||
knowledge_graph: &graph::KnowledgeGraph<'_>,
|
||||
knowledge_graph: &ConstraintGraph<'_, dir::DirValue>,
|
||||
) -> Result<(), types::AnalysisError> {
|
||||
perform_condition_analyses(context)?;
|
||||
let mut memo = Memoization::new();
|
||||
knowledge_graph
|
||||
.perform_context_analysis(context, &mut memo)
|
||||
.perform_context_analysis(context, &mut memo, None)
|
||||
.map_err(|err| types::AnalysisError {
|
||||
error_type: types::AnalysisErrorType::GraphAnalysis(err, memo),
|
||||
metadata: Default::default(),
|
||||
@ -218,7 +222,7 @@ fn perform_context_analyses(
|
||||
|
||||
pub fn analyze<O: EuclidAnalysable + EuclidDirFilter>(
|
||||
program: ast::Program<O>,
|
||||
knowledge_graph: Option<&graph::KnowledgeGraph<'_>>,
|
||||
knowledge_graph: Option<&ConstraintGraph<'_, dir::DirValue>>,
|
||||
) -> Result<vir::ValuedProgram<O>, types::AnalysisError> {
|
||||
let dir_program = ast::lowering::lower_program(program)?;
|
||||
|
||||
@ -241,9 +245,14 @@ mod tests {
|
||||
use std::{ops::Deref, sync::Weak};
|
||||
|
||||
use euclid_macros::knowledge;
|
||||
use hyperswitch_constraint_graph as cgraph;
|
||||
|
||||
use super::*;
|
||||
use crate::{dirval, types::DummyOutput};
|
||||
use crate::{
|
||||
dirval,
|
||||
dssa::graph::{self, euclid_graph_prelude},
|
||||
types::DummyOutput,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_conflicting_assertion_detection() {
|
||||
@ -368,7 +377,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_negation_graph_analysis() {
|
||||
let graph = knowledge! {crate
|
||||
let graph = knowledge! {
|
||||
CaptureMethod(Automatic) ->> PaymentMethod(Card);
|
||||
};
|
||||
|
||||
@ -410,18 +419,18 @@ mod tests {
|
||||
.deref()
|
||||
.clone()
|
||||
{
|
||||
graph::AnalysisTrace::Value { predecessors, .. } => {
|
||||
let _value = graph::NodeValue::Value(dir::DirValue::PaymentMethod(
|
||||
cgraph::AnalysisTrace::Value { predecessors, .. } => {
|
||||
let _value = cgraph::NodeValue::Value(dir::DirValue::PaymentMethod(
|
||||
dir::enums::PaymentMethod::Card,
|
||||
));
|
||||
let _relation = graph::Relation::Positive;
|
||||
let _relation = cgraph::Relation::Positive;
|
||||
predecessors
|
||||
}
|
||||
_ => panic!("Expected Negation Trace for payment method = card"),
|
||||
};
|
||||
|
||||
let pred = match predecessor {
|
||||
Some(graph::ValueTracePredecessor::Mandatory(predecessor)) => predecessor,
|
||||
Some(cgraph::error::ValueTracePredecessor::Mandatory(predecessor)) => predecessor,
|
||||
_ => panic!("No predecessor found"),
|
||||
};
|
||||
assert_eq!(
|
||||
@ -433,11 +442,11 @@ mod tests {
|
||||
*Weak::upgrade(&pred)
|
||||
.expect("Expected Arc not found")
|
||||
.deref(),
|
||||
graph::AnalysisTrace::Value {
|
||||
value: graph::NodeValue::Value(dir::DirValue::CaptureMethod(
|
||||
cgraph::AnalysisTrace::Value {
|
||||
value: cgraph::NodeValue::Value(dir::DirValue::CaptureMethod(
|
||||
dir::enums::CaptureMethod::Automatic
|
||||
)),
|
||||
relation: graph::Relation::Positive,
|
||||
relation: cgraph::Relation::Positive,
|
||||
info: None,
|
||||
metadata: None,
|
||||
predecessors: None,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,29 +1,30 @@
|
||||
use euclid_macros::knowledge;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::dssa::graph;
|
||||
use crate::{dssa::graph::euclid_graph_prelude, frontend::dir};
|
||||
|
||||
pub static ANALYSIS_GRAPH: Lazy<graph::KnowledgeGraph<'_>> = Lazy::new(|| {
|
||||
knowledge! {crate
|
||||
// Payment Method should be `Card` for a CardType to be present
|
||||
PaymentMethod(Card) ->> CardType(any);
|
||||
pub static ANALYSIS_GRAPH: Lazy<hyperswitch_constraint_graph::ConstraintGraph<'_, dir::DirValue>> =
|
||||
Lazy::new(|| {
|
||||
knowledge! {
|
||||
// Payment Method should be `Card` for a CardType to be present
|
||||
PaymentMethod(Card) ->> CardType(any);
|
||||
|
||||
// Payment Method should be `PayLater` for a PayLaterType to be present
|
||||
PaymentMethod(PayLater) ->> PayLaterType(any);
|
||||
// Payment Method should be `PayLater` for a PayLaterType to be present
|
||||
PaymentMethod(PayLater) ->> PayLaterType(any);
|
||||
|
||||
// Payment Method should be `Wallet` for a WalletType to be present
|
||||
PaymentMethod(Wallet) ->> WalletType(any);
|
||||
// Payment Method should be `Wallet` for a WalletType to be present
|
||||
PaymentMethod(Wallet) ->> WalletType(any);
|
||||
|
||||
// Payment Method should be `BankRedirect` for a BankRedirectType to
|
||||
// be present
|
||||
PaymentMethod(BankRedirect) ->> BankRedirectType(any);
|
||||
// Payment Method should be `BankRedirect` for a BankRedirectType to
|
||||
// be present
|
||||
PaymentMethod(BankRedirect) ->> BankRedirectType(any);
|
||||
|
||||
// Payment Method should be `BankTransfer` for a BankTransferType to
|
||||
// be present
|
||||
PaymentMethod(BankTransfer) ->> BankTransferType(any);
|
||||
// Payment Method should be `BankTransfer` for a BankTransferType to
|
||||
// be present
|
||||
PaymentMethod(BankTransfer) ->> BankTransferType(any);
|
||||
|
||||
// Payment Method should be `GiftCard` for a GiftCardType to
|
||||
// be present
|
||||
PaymentMethod(GiftCard) ->> GiftCardType(any);
|
||||
}
|
||||
});
|
||||
// Payment Method should be `GiftCard` for a GiftCardType to
|
||||
// be present
|
||||
PaymentMethod(GiftCard) ->> GiftCardType(any);
|
||||
}
|
||||
});
|
||||
|
||||
@ -140,7 +140,10 @@ pub enum AnalysisErrorType {
|
||||
negation_metadata: Metadata,
|
||||
},
|
||||
#[error("Graph analysis error: {0:#?}")]
|
||||
GraphAnalysis(graph::AnalysisError, graph::Memoization),
|
||||
GraphAnalysis(
|
||||
graph::AnalysisError<dir::DirValue>,
|
||||
hyperswitch_constraint_graph::Memoization<dir::DirValue>,
|
||||
),
|
||||
#[error("State machine error")]
|
||||
StateMachine(dssa::state_machine::StateMachineError),
|
||||
#[error("Unsupported program key '{0}'")]
|
||||
|
||||
Reference in New Issue
Block a user