Analysis: fix bug in listexp when in a vardec
[scilab.git] / scilab / modules / ast / src / cpp / analysis / ConstraintManager.cpp
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 #include "gvn/ConstraintManager.hxx"
14 #include "data/FunctionBlock.hxx"
15
16 namespace analysis
17 {
18 std::vector<std::shared_ptr<InferenceConstraint>> ConstraintManager::generalConstraints = init();
19
20 std::vector<std::shared_ptr<InferenceConstraint>> ConstraintManager::init()
21 {
22     std::vector<std::shared_ptr<InferenceConstraint>> v;
23     v.reserve(Kind::COUNT);
24     // Same dims => equality of 2 pairs of values
25     v.emplace_back(new SameDimsConstraint());
26     // Equality of values
27     v.emplace_back(new EqualConstraint());
28     // Positivity of a value
29     v.emplace_back(new PositiveConstraint());
30     // Strict positivity of a value
31     v.emplace_back(new StrictPositiveConstraint());
32     // Is a value greater than an other ?
33     v.emplace_back(new GreaterConstraint());
34     // Is a value strict greater than an other ?
35     v.emplace_back(new StrictGreaterConstraint());
36    // Valid index
37     v.emplace_back(new ValidIndexConstraint());
38     // Valid range
39     v.emplace_back(new ValidRangeConstraint());
40  
41     return v;
42 }
43
44 ConstraintManager::ConstraintManager(FunctionBlock * _function, FunctionBlock * _parent) : parent(_parent ? & _parent->getConstraintManager() : nullptr), function(_function) { }
45
46 bool ConstraintManager::check(const MPolyConstraintSet & set, const std::vector<GVN::Value *> & values)
47 {
48     /*std::wcerr << set.constraints.begin()->poly << "::" << set.constraints.begin()->kind << std::endl;
49     for (const auto & v : values)
50     {
51     std::wcerr << "DEBUG1=" << *v << std::endl;
52     }*/
53     InferenceConstraint::Result res = set.check((parent && parent->function) ? parent->function->getGVN() : function->getGVN(), values);
54     switch (res)
55     {
56         case InferenceConstraint::Result::RESULT_TRUE:
57         {
58             mpConstraints.add(set);
59             set.applyConstraints(values);
60             return true;
61         }
62         case InferenceConstraint::Result::RESULT_FALSE:
63             return false;
64         case InferenceConstraint::Result::RESULT_DUNNO:
65         {
66             if (parent && parent->function)
67             {
68                 const bool ret = parent->check(set.getMPConstraints(values), parent->function->getInValues());
69                 if (ret)
70                 {
71                     mpConstraints.add(set);
72                     set.applyConstraints(values);
73                 }
74                 return ret;
75             }
76             else
77             {
78                 return false;
79             }
80         }
81     }
82 }
83
84 bool ConstraintManager::check(Kind kind, const std::vector<GVN::Value *> & values)
85 {
86     const InferenceConstraint & ic = *generalConstraints[kind];
87     InferenceConstraint::Result res = ic.check(function->getGVN(), values);
88     //std::wcerr << "DEBUG2=" << res << std::endl;
89
90     switch (res)
91     {
92         case InferenceConstraint::Result::RESULT_TRUE:
93         {
94             mpConstraints.add(ic.getMPConstraints(values));
95             ic.applyConstraints(values);
96             return true;
97         }
98         case InferenceConstraint::Result::RESULT_FALSE:
99             return false;
100         case InferenceConstraint::Result::RESULT_DUNNO:
101         {
102             if (function)
103             {
104                 MPolyConstraintSet set = ic.getMPConstraints(values);
105                 const bool ret = check(set, function->getInValues());
106                 if (ret)
107                 {
108                     mpConstraints.add(set);
109                     ic.applyConstraints(values);
110                 }
111                 return ret;
112             }
113             return false;
114         }
115     }
116 }
117
118     bool ConstraintManager::checkGlobalConstant(const symbol::Symbol & sym)
119     {
120         if (constantConstraints.find(sym) == constantConstraints.end())
121         {
122             // TODO: fix that !!!
123             const bool ret = true; //symbol::Context::getInstance()->isOriginalSymbol(sym);
124             if (ret)
125             {
126                 ConstraintManager * cm = this;
127                 while (cm)
128                 {
129                     cm->constantConstraints.emplace(sym);
130                     cm = cm->parent;
131                 }
132             }
133             return ret;
134         }
135         else
136         {
137             return true;
138         }
139     }
140
141     bool ConstraintManager::checkGlobalConstants(const std::set<symbol::Symbol> & gc)
142         {
143             for (const auto sym : gc)
144             {
145                 if (!symbol::Context::getInstance()->isOriginalSymbol(sym))
146                 {
147                     return false;
148                 }
149             }
150             return true;
151         }
152 }