1 /*
2 
3  HyPhy - Hypothesis Testing Using Phylogenies.
4 
5  Copyright (C) 1997-now
6  Core Developers:
7  Sergei L Kosakovsky Pond (spond@ucsd.edu)
8  Art FY Poon    (apoon42@uwo.ca)
9  Steven Weaver (sweaver@ucsd.edu)
10 
11  Module Developers:
12  Lance Hepler (nlhepler@gmail.com)
13  Martin Smith (martin.audacis@gmail.com)
14 
15  Significant contributions from:
16  Spencer V Muse (muse@stat.ncsu.edu)
17  Simon DW Frost (sdf22@cam.ac.uk)
18 
19  Permission is hereby granted, free of charge, to any person obtaining a
20  copy of this software and associated documentation files (the
21  "Software"), to deal in the Software without restriction, including
22  without limitation the rights to use, copy, modify, merge, publish,
23  distribute, sublicense, and/or sell copies of the Software, and to
24  permit persons to whom the Software is furnished to do so, subject to
25  the following conditions:
26 
27  The above copyright notice and this permission notice shall be included
28  in all copies or substantial portions of the Software.
29 
30  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
31  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
34  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
35  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
36  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 
38  */
39 
40 #ifndef     __OPERATION__
41 #define     __OPERATION__
42 
43 #include "baseobj.h"
44 #include "list.h"
45 #include "trie.h"
46 #include "hy_strings.h"
47 #include "mathobj.h"
48 #include "global_things.h"
49 
50 extern  _List BuiltInFunctions;
51 
52 
53 class _Stack;
54 class _VariableContainer;
55 class _Variable;
56 class _Formula;
57 
58 _Variable * FetchVar (long, unsigned long = HY_ANY_OBJECT);
59 
60 //__________________________________________________________________________________
61 class   _Operation : public BaseObj
62 {
63 
64     friend class    _Formula;
65     friend class    _Variable;
66     friend class    _VariableContainer;
67 
68 protected:
69     long           opCode;         // internal operation code
70     long           numberOfTerms,  // 1 - unary, 2 - binary, etc
71                    theData;
72 
73     HBLObjectRef   theNumber,
74                    cachedResult;
75 
76 
77 public:
78     _Operation  (void);
79     _Operation  (_String const&, const long);
80     // construct the operation by its symbol and, if relevant -
81     // number of operands
82     _Operation  (const long,const long);
83     _Operation  (const _Operation&);
84 
85     _Operation  (bool, _String&, bool isG = false, _VariableContainer const*  = nil, bool take_a_reference = false);
86     // store a variable or a constant
87     _Operation  (HBLObjectRef);
88     // store a non-numeric constant
89     _Operation  (_Variable const&);
90     // create an operation that references a variable
91 
92 
93     virtual ~_Operation (void);
94 
95     virtual   BaseObj*      makeDynamic         (void) const;
96     virtual   void          Duplicate           (BaseRefConst);
97     void      operator = (_Operation const&);
98 
99     bool            Execute             (_Stack&, _VariableContainer const* = nil, _String* errMsg = nil, bool canCache = false); //execute this operation
100     // see the commend for _Formula::ExecuteFormula for the second argument
101     virtual   void          StackDepth          (long&);
102 
103     bool            ExecutePolynomial   (_Stack&,_VariableContainer* nameSpace = nil, _String* errMsg = nil);
104     virtual   BaseObj*      toStr               (unsigned long = 0UL);    //convert the op to string
105 
106     virtual   void          Initialize          (bool = true);
GetCode(void)107     const _String&    GetCode             (void) {
108         return (opCode>-1)&&(numberOfTerms>=0)?*(_String*)BuiltInFunctions(opCode): hy_global::kEmptyString;
109     }
TheCode(void)110     long&       TheCode             (void) {
111         return opCode;
112     }
113     virtual  bool           IsAVariable         (bool = true) ; // is this object a variable or not?
114     virtual  bool           IsConstant          (bool strict = false);         // does this object depend on any independent variables or not?
115     virtual  bool           IsHBLFunctionCall   (void) const;
116     virtual  long           GetHBLFunctionID    (void) const;
117 
UserFunctionID(void)118     virtual  long           UserFunctionID      (void) {
119         return numberOfTerms < 0 ? opCode : -1;
120     };
121     // return a non-neg number (function index) if this is a user function,
122     // otherwise, return -1
123 
GetAVariable(void)124     virtual  long           GetAVariable        (void) const{
125         if (theData >= -1) {
126             return theData;
127         }
128         if (theData < -2) {
129             return -theData - 3;
130         }
131         return -numberOfTerms-1;
132         // return the index of the variable
133     }
134 
IsValueSubstitution(void)135     virtual  long           IsValueSubstitution        (void) const{
136         return theData == -2;
137     }
138 
SetAVariable(long d)139     virtual  void           SetAVariable        (long d) {  // return the index of the variable
140         theData=d;
141     }
142 
RetrieveVar(void)143     _Variable *             RetrieveVar         (void) const {
144       if (theData != -1) {
145         long var_idx = GetAVariable();
146         if (var_idx >= 0) {
147             return FetchVar(var_idx);
148         } else {
149             if (var_idx == -2) {
150                 return FetchVar (-numberOfTerms-1);
151             }
152         }
153       }
154       return nil;
155     }
156 
AssignmentVariable(void)157     virtual  bool           AssignmentVariable  (void) {
158         return theData<-2;
159     }
160 
161     virtual  bool           HasChanged          (void);
162 
SetTerms(long d)163     virtual  void           SetTerms            (long d) {
164         numberOfTerms=d;
165     }
166 
167     long                    StackDepth          (void) const;
168 
GetANumber(void)169     virtual  HBLObjectRef      GetANumber          (void) {
170         return theNumber;
171     }
172 
SetNumber(HBLObjectRef d)173     virtual  void           SetNumber           (HBLObjectRef d) {
174         theNumber=d;
175     }
176 
GetNoTerms(void)177     long            GetNoTerms          (void) {
178         return numberOfTerms;
179     }
180     long            PrecedenceLevel     (void);
181 
182     bool            CanResultsBeCached (_Operation *, bool exp_only = false);
183 
184     bool            IsConstantOfType   (const long type) const;
185 
186 
187     virtual bool            EqualOp             (_Operation*);
188 
189     static  long            BinOpCode           (_String const &, long = -1);
190 
AreOpsInverse(long op_code1,long op_code2)191     static bool             AreOpsInverse       (long op_code1, long op_code2) {
192         long compose = op_code1 < op_code2 ? (op_code1 << 16) + (op_code2) : (op_code2 << 16) + (op_code1);
193         return ListOfInverseOps.Find (compose) != kNotFound;
194     }
195 
196     static      _SimpleList         ListOfInverseOps;
197 protected:
198 
199 
200     bool        ReportOperationExecutionError ( _String, _String*);
201 
202 };
203 
204 #endif
205