conjure_core/solver/adaptors/rustsat/
convs.rs
1use std::{collections::HashMap, env::Vars, io::Lines};
2
3use rustsat::{
4 clause,
5 instances::{BasicVarManager, Cnf, SatInstance},
6 solvers::{Solve, SolverResult},
7 types::{Lit, TernaryVal},
8};
9
10use rustsat_minisat::core::Minisat;
11
12use anyhow::{anyhow, Result};
13
14use crate::{ast::Expression, solver::Error};
15
16pub fn handle_lit(
17 l1: &Expression,
18 vars_added: &mut HashMap<String, Lit>,
19 inst: &mut SatInstance,
20) -> Lit {
21 match l1 {
22 Expression::Atomic(_, _) => handle_atom(l1.clone(), true, vars_added, inst),
25 Expression::Not(_, _) => handle_not(l1, vars_added, inst),
27
28 _ => panic!("Literal expected"),
29 }
30}
31
32pub fn handle_not(
33 expr: &Expression,
34 vars_added: &mut HashMap<String, Lit>,
35 inst: &mut SatInstance,
36) -> Lit {
37 match expr {
38 Expression::Not(_, ref_heap_a) => {
39 let a = ref_heap_a.clone();
41 handle_atom(*a, false, vars_added, inst)
43 }
44 _ => panic!("Not Expected"),
45 }
46}
47
48pub fn handle_atom(
49 a: Expression,
50 polarity: bool,
51 vars_added: &mut HashMap<String, Lit>,
52 inst: &mut SatInstance,
53) -> Lit {
54 match a {
56 Expression::Atomic(_, atom) => match atom {
57 conjure_core::ast::Atom::Literal(literal) => {
58 todo!("Not Sure if we are handling Lits as-is or not..")
59 }
60 conjure_core::ast::Atom::Reference(name) => match name {
61 conjure_core::ast::Name::UserName(n) => {
62 let lit_temp: Lit = fetch_lit(n, vars_added, inst);
65 if polarity {
66 lit_temp
67 } else {
68 !lit_temp
69 }
70 }
71 _ => {
72 todo!("Change Here for other types of vars")
73 }
74 },
75 },
76 _ => panic!("atomic expected"),
77 }
78}
79
80pub fn fetch_lit(
81 symbol: String,
82 vars_added: &mut HashMap<String, Lit>,
83 inst: &mut SatInstance,
84) -> Lit {
85 if !vars_added.contains_key(&symbol) {
86 vars_added.insert(symbol.to_string(), inst.new_lit());
87 }
88 *(vars_added.get(&symbol).unwrap())
89}
90
91pub fn handle_disjn(
92 disjn: &Expression,
93 vars_added: &mut HashMap<String, Lit>,
94 inst_in_use: &mut SatInstance,
95) {
96 let cl: &Vec<Expression> = match disjn {
97 Expression::Or(_, vec) => &vec.clone().unwrap_list().unwrap(),
98 _ => panic!(),
99 };
100 let l1 = &cl[0];
101 let l2 = &cl[1];
102
103 let lit1: Lit = handle_lit(l1, vars_added, inst_in_use);
105 let lit2: Lit = handle_lit(l2, vars_added, inst_in_use);
107
108 inst_in_use.add_binary(lit1, lit2);
109}
110
111pub fn handle_cnf(vec_cnf: &Vec<Expression>, vars_added: &mut HashMap<String, Lit>) -> SatInstance {
112 let mut inst = SatInstance::new();
113 for disjn in vec_cnf {
114 handle_disjn(disjn, vars_added, &mut inst);
115 }
116 inst
117}
118
119#[derive(Error, Debug)]
122pub enum CNFError {
123 #[error("Variable with name `{0}` not found")]
124 VariableNameNotFound(String),
125
126 #[error("Variable with name `{0}` not of right type")]
127 BadVariableType(String),
128
129 #[error("Unexpected Expression `{0}` inside Not(). Only Not(Reference) or Not(Not) allowed!")]
130 UnexpectedExpressionInsideNot(Expression),
131
132 #[error("Unexpected Expression `{0}` as literal. Only Not() or Reference() allowed!")]
133 UnexpectedLiteralExpression(Expression),
134
135 #[error("Unexpected Expression `{0}` inside And(). Only And(vec<Or>) allowed!")]
136 UnexpectedExpressionInsideAnd(Expression),
137
138 #[error("Unexpected Expression `{0}` inside Or(). Only Or(lit, lit) allowed!")]
139 UnexpectedExpressionInsideOr(Expression),
140
141 #[error("Unexpected Expression `{0}` found!")]
142 UnexpectedExpression(Expression),
143}