LogiXpr
Loading...
Searching...
No Matches
solver.cpp
Go to the documentation of this file.
1
6#include "../include/solver.h"
7
8std::unordered_map<EquivLaws::EquivLaw, std::string> equivalences = {};
9
10int MAX_QUEUE_SIZE = 2500;
12
13void preprocess(std::shared_ptr<Expression> lhs, std::shared_ptr<Expression> rhs)
14{
15 // include laws
16 equivalences.clear();
17 equivalences.insert(EquivLaws::laws.begin(), EquivLaws::laws.end());
18
19 // convert lhs and rhs to strings
20 std::string lhsString = lhs->toStringTree();
21 std::string rhsString = rhs->toStringTree();
22
23 if (lhsString.find("->") != std::string::npos || rhsString.find("->") != std::string::npos)
24 {
26 }
27
28 if (lhsString.find("<=>") != std::string::npos || rhsString.find("<=>") != std::string::npos)
29 {
31 }
32}
33
34std::vector<std::vector<std::string>> proveEquivalence(std::shared_ptr<Expression> lhs, std::shared_ptr<Expression> rhs)
35{
36 if (lhs->compare(rhs))
37 return {{"", "Given"}};
38
39 std::vector<std::vector<std::string>> steps;
40
41 std::queue<std::shared_ptr<Expression>> queue;
42 std::unordered_map<std::string, std::pair<std::string, std::string>> visited;
43
44 queue.push(lhs);
45 visited[lhs->toStringTree()] = {"", "Given"};
46
47 bool found = false;
48
49 while (!queue.empty())
50 {
51 // if queue is too long, stop
52 if (queue.size() > MAX_QUEUE_SIZE)
53 {
54 steps.push_back({"", "Too many steps :("});
55 return steps;
56 }
57 std::shared_ptr<Expression> expr = queue.front();
58 queue.pop();
59
60 if (expr->compare(rhs))
61 {
62 // found the rhs, now backtrack the visited map to get the steps
63 std::string currentExprString = expr->toStringTree();
64 while (currentExprString != "")
65 {
66 steps.push_back({currentExprString, visited[currentExprString].second});
67 currentExprString = visited[currentExprString].first;
68 }
69 std::reverse(steps.begin(), steps.end());
70 return steps;
71 }
72
73 generateNextSteps(expr, rhs, found, queue, visited);
74 }
75 return {{"", "Couldn't find a solution :("}};
76}
77
78void generateNextSteps(std::shared_ptr<Expression> expr, std::shared_ptr<Expression> end, bool &found, std::queue<std::shared_ptr<Expression>> &queue, std::unordered_map<std::string, std::pair<std::string, std::string>> &visited)
79{
80 for (auto equiv : equivalences)
81 {
82 if (found)
83 return;
84
85 auto funct = equiv.first;
86 auto lawName = equiv.second;
87
88 std::shared_ptr<Expression> newExpr = expr->cloneTree();
89
90 if (funct(newExpr))
91 {
92 std::string newExprString = newExpr->toStringTree();
93 if (newExprString.length() > MAX_EXPRESSION_LENGTH)
94 continue;
95 // ignore extremely long expressions
96
97 if (visited.find(newExprString) == visited.end())
98 {
99 visited[newExprString] = {expr->toStringTree(), lawName};
100 if (newExpr->compareTree(end))
101 found = true;
102 while (newExpr->getParent())
103 newExpr = newExpr->getParent();
104 queue.push(newExpr);
105 }
106 }
107 }
108
109 if (!found)
110 {
111 if (expr->getLeft() && !expr->getLeft()->isVar())
112 generateNextSteps(expr->getLeft(), end, found, queue, visited);
113 if (expr->getRight() && !expr->getRight()->isVar())
114 generateNextSteps(expr->getRight(), end, found, queue, visited);
115 }
116}
static std::unordered_map< EquivLaw, std::string > implications
Map of implication equivalences to their string representations.
Definition equivLaws.h:24
static std::unordered_map< EquivLaw, std::string > laws
Map of equivalence laws to their string representations.
Definition equivLaws.h:8
static std::unordered_map< EquivLaw, std::string > bidirectionalImplications
Map of biimplication equivalences to their string representations.
Definition equivLaws.h:46
int MAX_EXPRESSION_LENGTH
Maximum length of the expressions in the queue.
Definition solver.cpp:11
void generateNextSteps(std::shared_ptr< Expression > expr, std::shared_ptr< Expression > end, bool &found, std::queue< std::shared_ptr< Expression > > &queue, std::unordered_map< std::string, std::pair< std::string, std::string > > &visited)
Generate the next expressions from the current expression. Creates a new expression for each law that...
Definition solver.cpp:78
std::vector< std::vector< std::string > > proveEquivalence(std::shared_ptr< Expression > lhs, std::shared_ptr< Expression > rhs)
Prove the expressions are equivalence using equivalence laws by solving the left hand side to the rig...
Definition solver.cpp:34
std::unordered_map< EquivLaws::EquivLaw, std::string > equivalences
Map of equivalences to be applied to the expressions.
Definition solver.cpp:8
int MAX_QUEUE_SIZE
Maximum size of the queue of expressions to be processed.
Definition solver.cpp:10
void preprocess(std::shared_ptr< Expression > lhs, std::shared_ptr< Expression > rhs)
Fill the map of equivalences to be applied to the expressions. Must be called before any other functi...
Definition solver.cpp:13