Analysis: add classes to manage constraints on symbolic dimensions
[scilab.git] / scilab / modules / ast / includes / analysis / gvn / InferenceConstraint.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifndef __INFERENCE_CONSTRAINT_HXX__
14 #define __INFERENCE_CONSTRAINT_HXX__
15
16 #include <cmath>
17 #include <unordered_set>
18 #include <vector>
19
20 #include "GVN.hxx"
21 #include "tools.hxx"
22
23 namespace analysis
24 {
25
26 struct MPolyConstraint;
27 struct MPolyConstraintSet;
28
29 struct InferenceConstraint
30 {
31     enum Result { TRUE, FALSE, DUNNO } ;
32
33     virtual Result check(const std::vector<GVN::Value *> & values) const = 0;
34     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const = 0;
35     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const { }
36
37     inline static std::vector<const MultivariatePolynomial *> getArgs(const std::vector<GVN::Value *> & values)
38     {
39         std::vector<const MultivariatePolynomial *> args;
40         args.reserve(values.size());
41         for (const auto value : values)
42         {
43             args.emplace_back(value->poly);
44         }
45         return args;
46     }
47
48     inline static void applyEquality(GVN::Value & x, GVN::Value & y)
49     {
50         if (x != y)
51         {
52             if (x.poly->polynomial.size() < y.poly->polynomial.size())
53             {
54                 y = x;
55             }
56             else
57             {
58                 x = y;
59             }
60         }
61     }
62 };
63
64 struct SameDimsConstraint : public InferenceConstraint
65 {
66     virtual Result check(const std::vector<GVN::Value *> & values) const override;
67     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
68     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
69 };
70
71 struct EqualConstraint : public InferenceConstraint
72 {
73     virtual Result check(const std::vector<GVN::Value *> & values) const override;
74     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
75     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
76 };
77
78 struct PositiveConstraint : public InferenceConstraint
79 {
80     virtual Result check(const std::vector<GVN::Value *> & values) const override;
81     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
82     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
83 };
84
85 struct GreaterConstraint : public InferenceConstraint
86 {
87     virtual Result check(const std::vector<GVN::Value *> & values) const override;
88     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
89     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
90 };
91
92 struct MPolyConstraint : public InferenceConstraint
93 {
94     enum Kind { EQ0, NEQ0, GT0, GEQ0 };
95
96     MultivariatePolynomial poly;
97     Kind kind;
98
99     MPolyConstraint(const MultivariatePolynomial & _poly, const Kind _kind) : poly(_poly), kind(_kind)
100     {
101         double common;
102         if (poly.getCommonCoeff(common) && common != 1 && common != 0)
103         {
104             if (kind == EQ0)
105             {
106                 poly /= common;
107             }
108             else
109             {
110                 poly /= std::abs(common);
111             }
112         }
113     }
114
115     virtual Result check(const std::vector<GVN::Value *> & values) const override;
116     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
117     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
118
119     struct Hash
120     {
121         inline std::size_t operator()(const MPolyConstraint & mpc) const
122         {
123             return tools::hash_combine(mpc.kind, mpc.poly.hash());
124         }
125     };
126
127     struct Eq
128     {
129         inline bool operator()(const MPolyConstraint & L, const MPolyConstraint & R) const
130         {
131             return L.kind == R.kind && L.poly == R.poly;
132         }
133     };
134 };
135
136 struct MPolyConstraintSet : public InferenceConstraint
137 {
138     std::unordered_set<MPolyConstraint, MPolyConstraint::Hash, MPolyConstraint::Eq> constraints;
139
140     MPolyConstraintSet() { }
141     MPolyConstraintSet(const unsigned int size)
142     {
143         constraints.reserve(size);
144     }
145
146     inline void add(MPolyConstraint && mpc)
147     {
148         constraints.emplace(std::move(mpc));
149     }
150
151     inline void add(MultivariatePolynomial && poly, MPolyConstraint::Kind kind)
152     {
153         constraints.emplace(std::move(poly), kind);
154     }
155
156     inline void add(const MultivariatePolynomial & poly, MPolyConstraint::Kind kind)
157     {
158         constraints.emplace(poly, kind);
159     }
160
161     inline void add(const MPolyConstraintSet & set)
162     {
163         constraints.insert(set.constraints.begin(), set.constraints.end());
164     }
165
166     virtual Result check(const std::vector<GVN::Value *> & values) const override;
167     virtual MPolyConstraintSet getMPConstraints(const std::vector<GVN::Value *> & values) const override;
168     virtual void applyConstraints(const std::vector<GVN::Value *> & values) const override;
169 };
170
171
172 } // namespace analysis
173
174 #endif // __INFERENCE_CONSTRAINT_HXX__