1 /*
2     Qalculate (library)
3 
4     Copyright (C) 2003-2007, 2008, 2016-2019  Hanna Knutsson (hanna.knutsson@protonmail.com)
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 */
11 
12 #include "support.h"
13 
14 #include "BuiltinFunctions.h"
15 #include "MathStructure.h"
16 #include "Calculator.h"
17 #include "Number.h"
18 #include "Function.h"
19 #include "Variable.h"
20 #include "MathStructure-support.h"
21 
22 using std::string;
23 using std::cout;
24 using std::vector;
25 using std::endl;
26 
27 /* Collects x degree, coefficient, degree zero term. By default only one x term (a single exponent) is allowed.
28 If radunit is true all coefficient must be a multiple of the radian unit. The unit is then removed. Used for trigonometric functions.
29 If mexp_as_x2 is true, reuire a second degree polynomial and return second degree coefficient in mexp.
30 If mexp_as_fx is true allow x multipliers of any form (e.g. e^x or sin(x)) and return the the whole x multiplier in mexp.
31 */
integrate_info(const MathStructure & mstruct,const MathStructure & x_var,MathStructure & madd,MathStructure & mmul,MathStructure & mexp,bool radunit=false,bool mexp_as_x2=false,bool mexp_as_fx=false)32 bool integrate_info(const MathStructure &mstruct, const MathStructure &x_var, MathStructure &madd, MathStructure &mmul, MathStructure &mexp, bool radunit = false, bool mexp_as_x2 = false, bool mexp_as_fx = false) {
33 	if(radunit && mstruct.isMultiplication() && mstruct.size() == 2 && mstruct[1] == CALCULATOR->getRadUnit()) return integrate_info(mstruct[0], x_var, madd, mmul, mexp, false, mexp_as_x2, mexp_as_fx);
34 	madd.clear();
35 	if(mexp_as_x2 || mexp_as_fx) mexp = m_zero;
36 	else mexp = m_one;
37 	mmul = m_zero;
38 	if(!mexp_as_fx && mstruct == x_var) {
39 		if(radunit) return false;
40 		mmul = m_one;
41 		return true;
42 	} else if(mexp_as_x2 && mstruct.isPower()) {
43 		if(radunit) return false;
44 		if(mstruct[1].isNumber() && mstruct[1].number().isTwo() && mstruct[0] == x_var) {
45 			mexp = m_one;
46 			return true;
47 		}
48 	} else if(!mexp_as_fx && !mexp_as_x2 && mstruct.isPower() && mstruct[1].containsRepresentativeOf(x_var, true, true) == 0) {
49 		if(radunit) return false;
50 		if(mstruct[0] == x_var) {
51 			mexp = mstruct[1];
52 			mmul = m_one;
53 			return true;
54 		}
55 	} else if(mstruct.isMultiplication() && mstruct.size() >= 2) {
56 		bool b_x = false;
57 		bool b_rad = false;
58 		bool b2 = false;
59 		size_t i_x = 0, i_rad = 0;
60 		for(size_t i = 0; i < mstruct.size(); i++) {
61 			if(!b_x && !mexp_as_fx && mstruct[i] == x_var) {
62 				b_x = true;
63 				i_x = i;
64 			} else if(!b_x && mexp_as_x2 && mstruct[i].isPower() && mstruct[i][1].isNumber() && mstruct[i][1].number().isTwo() && mstruct[i][0] == x_var) {
65 				b_x = true;
66 				b2 = true;
67 				i_x = i;
68 			} else if(!b_x && !mexp_as_fx && !mexp_as_x2 && mstruct[i].isPower() && mstruct[i][0] == x_var && mstruct[i][1].containsRepresentativeOf(x_var, true, true) == 0) {
69 				b_x = true;
70 				i_x = i;
71 				mexp = mstruct[i][1];
72 			} else if(mstruct[i].containsRepresentativeOf(x_var, true, true) != 0) {
73 				if(!b_x && mexp_as_fx && (mexp.isZero() || mexp == mstruct[i])) {
74 					mexp = mstruct[i];
75 					b_x = true;
76 					i_x = i;
77 				} else {
78 					return false;
79 				}
80 			} else if(!b_rad && radunit && mstruct[i] == CALCULATOR->getRadUnit()) {
81 				b_rad = true;
82 				i_rad = i;
83 			}
84 		}
85 		if(!b_x || (radunit && !b_rad)) return false;
86 		if(mstruct.size() == 1 || (radunit && mstruct.size() == 2)) {
87 			if(b2) mexp = m_one;
88 			else mmul = m_one;
89 		} else if(mstruct.size() == 2) {
90 			if(b2) {
91 				if(i_x == 1) mexp = mstruct[0];
92 				else mexp = mstruct[1];
93 			} else {
94 				if(i_x == 1) mmul = mstruct[0];
95 				else mmul = mstruct[1];
96 			}
97 		} else if(radunit && mstruct.size() == 3) {
98 			if((i_x == 1 && i_rad == 2) || (i_x == 2 && i_rad == 1)) {
99 				if(b2) mexp = mstruct[0];
100 				else mmul = mstruct[0];
101 			} else if((i_x == 0 && i_rad == 2) || (i_x == 2 && i_rad == 0)) {
102 				if(b2) mexp = mstruct[1];
103 				else mmul = mstruct[1];
104 			} else {
105 				if(b2) mexp = mstruct[2];
106 				else mmul = mstruct[2];
107 			}
108 		} else {
109 			if(b2) {
110 				mexp = mstruct;
111 				mexp.delChild(i_x + 1, true);
112 				if(radunit) {
113 					mexp.delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
114 				}
115 			} else {
116 				mmul = mstruct;
117 				mmul.delChild(i_x + 1, true);
118 				if(radunit) {
119 					mmul.delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
120 				}
121 			}
122 		}
123 		return true;
124 	} else if(mstruct.isAddition()) {
125 		mmul.setType(STRUCT_ADDITION);
126 		if(mexp_as_x2) mexp.setType(STRUCT_ADDITION);
127 		madd.setType(STRUCT_ADDITION);
128 		for(size_t i = 0; i < mstruct.size(); i++) {
129 			if(!mexp_as_fx && mstruct[i] == x_var) {
130 				if(mexp_as_x2 || mexp.isOne()) mmul.addChild(m_one);
131 				else return false;
132 			} else if(mexp_as_x2 && mstruct[i].isPower() && mstruct[i][1].isNumber() && mstruct[i][1].number().isTwo() && mstruct[i][0] == x_var) {
133 				mexp.addChild(m_one);
134 			} else if(!mexp_as_fx && !mexp_as_x2 && mstruct[i].isPower() && mstruct[i][0] == x_var && mstruct[i][1].containsRepresentativeOf(x_var, true, true) == 0) {
135 				if(mmul.size() == 0) {
136 					mexp = mstruct[i][1];
137 				} else if(mexp != mstruct[i][1]) {
138 					return false;
139 				}
140 				mmul.addChild(m_one);
141 			} else if(mstruct[i].isMultiplication()) {
142 				bool b_x = false;
143 				bool b_rad = false;
144 				bool b2 = false;
145 				size_t i_x = 0, i_rad = 0;
146 				for(size_t i2 = 0; i2 < mstruct[i].size(); i2++) {
147 					if(!b_x && !mexp_as_fx && mstruct[i][i2] == x_var) {
148 						if(!mexp_as_x2 && !mexp.isOne()) return false;
149 						i_x = i2;
150 						b_x = true;
151 					} else if(!b_x && mexp_as_x2 && mstruct[i][i2].isPower() && mstruct[i][i2][1].isNumber() && mstruct[i][i2][1].number().isTwo() && mstruct[i][i2][0] == x_var) {
152 						b2 = true;
153 						i_x = i2;
154 						b_x = true;
155 					} else if(!b_x && !mexp_as_fx && !mexp_as_x2 && mstruct[i][i2].isPower() && mstruct[i][i2][0] == x_var && mstruct[i][i2][1].containsRepresentativeOf(x_var, true, true) == 0) {
156 						if(mmul.size() == 0) {
157 							mexp = mstruct[i][i2][1];
158 						} else if(mexp != mstruct[i][i2][1]) {
159 							return false;
160 						}
161 						i_x = i2;
162 						b_x = true;
163 					} else if(mstruct[i][i2].containsRepresentativeOf(x_var, true, true) != 0) {
164 						if(!b_x && mexp_as_fx && (mexp.isZero() || mexp == mstruct[i][i2])) {
165 							mexp = mstruct[i][i2];
166 							i_x = i2;
167 							b_x = true;
168 						} else {
169 							return false;
170 						}
171 					} else if(!b_rad && radunit && mstruct[i][i2] == CALCULATOR->getRadUnit()) {
172 						b_rad = true;
173 						i_rad = i2;
174 					}
175 				}
176 				if(radunit && !b_rad) return false;
177 				if(b_x) {
178 					if(mstruct[i].size() == 1) {
179 						if(b2) mexp.addChild(m_one);
180 						else mmul.addChild(m_one);
181 					} else if(radunit && mstruct[i].size() == 2) {
182 						if(b2) mexp.addChild(m_one);
183 						else mmul.addChild(m_one);
184 					} else {
185 						if(b2) {
186 							mexp.addChild(mstruct[i]);
187 							mexp[mexp.size() - 1].delChild(i_x + 1, true);
188 							if(radunit) mexp[mexp.size() - 1].delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
189 							mexp.childUpdated(mexp.size());
190 						} else {
191 							mmul.addChild(mstruct[i]);
192 							mmul[mmul.size() - 1].delChild(i_x + 1, true);
193 							if(radunit) mmul[mmul.size() - 1].delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
194 							mmul.childUpdated(mmul.size());
195 						}
196 					}
197 				} else {
198 					madd.addChild(mstruct[i]);
199 					if(radunit) {
200 						madd[madd.size() - 1].delChild(i_rad + 1, true);
201 					}
202 				}
203 			} else if(radunit && mstruct[i] == CALCULATOR->getRadUnit()) {
204 				madd.addChild(mstruct[i]);
205 			} else if(radunit || mstruct[i].containsRepresentativeOf(x_var, true, true) != 0) {
206 				if(!radunit && mexp_as_fx && (mexp.isZero() || mexp == mstruct[i])) {
207 					mexp = mstruct[i];
208 					mmul.addChild(m_one);
209 				} else {
210 					return false;
211 				}
212 			} else {
213 				madd.addChild(mstruct[i]);
214 			}
215 		}
216 		if(mmul.size() == 0 && (!mexp_as_x2 || mexp.size() == 0)) {
217 			mmul.clear();
218 			if(mexp_as_x2) mexp.clear();
219 			return false;
220 		}
221 		if(mmul.size() == 0) mmul.clear();
222 		else if(mmul.size() == 1) mmul.setToChild(1);
223 		if(mexp_as_x2) {
224 			if(mexp.size() == 0) mexp.clear();
225 			else if(mexp.size() == 1) mexp.setToChild(1);
226 		}
227 		if(madd.size() == 0) madd.clear();
228 		else if(madd.size() == 1) madd.setToChild(1);
229 		return true;
230 	} else if(!radunit && mexp_as_fx && mstruct.contains(x_var, true)) {
231 		mexp = mstruct;
232 		mmul = m_one;
233 		return true;
234 	}
235 	return false;
236 }
237 
238 /*bool test_absln_comp_cmplx(const MathStructure &mstruct) {
239 	if(mstruct.number().isComplex() && (!mstruct.number().hasRealPart() || mstruct.number().hasPositiveSign()) && mstruct.number().internalImaginary()->isPositive()) return true;
240 	if(mstruct.isPower() && mstruct[1].isNumber() && mstruct[1].number().numeratorIsOne() && mstruct[0].representsNonComplex(true)) return true;
241 	if(mstruct.isMultiplication()) {
242 		for(size_t i = 0; i < mstruct.size(); i++) {
243 			if(!mstruct[i].representsNonNegative(true)) {
244 				if(!test_absln_comp_cmplx(mstruct[i])) {
245 					return false;
246 				}
247 			}
248 		}
249 		return true;
250 	} else if(mstruct.isAddition()) {
251 		for(size_t i = 0; i < mstruct.size(); i++) {
252 			if(!mstruct[i].representsNonNegative(true)) {
253 				if(!test_absln_comp_cmplx(mstruct[i])) {
254 					return false;
255 				}
256 			}
257 		}
258 		return true;
259 	}
260 	return false;
261 }*/
262 
263 /* Transform mstruct to logarithm (ln(mstruct)).
264 If use_abs != 0, logarithms of negative numbers are avoided. ln(abs(mstruct)) is used if signedness is unknown and mstruct is not complex. If abs > 0, mstruct is assumed real if it is not possible to determine if mstruct is complex or not.
265 */
transform_absln(MathStructure & mstruct,int use_abs,bool definite_integral,const MathStructure & x_var,const EvaluationOptions & eo)266 bool transform_absln(MathStructure &mstruct, int use_abs, bool definite_integral, const MathStructure &x_var, const EvaluationOptions &eo) {
267 	if(use_abs != 0 && mstruct.representsNonComplex(true)) {
268 		if(mstruct.representsNonPositive(true)) {
269 			mstruct.negate();
270 		} else if(!mstruct.representsNonNegative(true)) {
271 			mstruct.transformById(FUNCTION_ID_ABS);
272 		}
273 		mstruct.transformById(FUNCTION_ID_LOG);
274 	} else if(use_abs != 0 && !mstruct.representsComplex(true)) {
275 		if(definite_integral) use_abs = -1;
276 		CALCULATOR->beginTemporaryStopMessages();
277 		MathStructure mtest(mstruct);
278 		EvaluationOptions eo2 = eo;
279 		eo2.expand = true;
280 		eo2.approximation = APPROXIMATION_APPROXIMATE;
281 		eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
282 		mtest.eval(eo2);
283 		CALCULATOR->endTemporaryStopMessages();
284 		if(mtest.representsNonComplex(true)) {
285 			if(mstruct.representsNonPositive(true)) {
286 				mstruct.negate();
287 			} else if(!mtest.representsNonNegative(true)) {
288 				mstruct.transformById(FUNCTION_ID_ABS);
289 			}
290 			mstruct.transformById(FUNCTION_ID_LOG);
291 		} else if(mtest.representsComplex(true)) {
292 			mstruct.transformById(FUNCTION_ID_LOG);
293 		} else {
294 			if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
295 				CALCULATOR->beginTemporaryStopMessages();
296 				KnownVariable *var = new KnownVariable("", format_and_print(x_var), ((UnknownVariable*) x_var.variable())->interval());
297 				mtest.replace(x_var, var);
298 				mtest.eval(eo2);
299 				CALCULATOR->endTemporaryStopMessages();
300 				if(mtest.representsNonComplex(true)) {
301 					if(mstruct.representsNonPositive(true)) {
302 						mstruct.negate();
303 					} else if(!mtest.representsNonNegative(true)) {
304 						mstruct.transformById(FUNCTION_ID_ABS);
305 					}
306 					mstruct.transformById(FUNCTION_ID_LOG);
307 				} else if(use_abs > 0) {
308 					CALCULATOR->error(false, "Integral assumed real", NULL);
309 					mstruct.transformById(FUNCTION_ID_ABS);
310 					mstruct.transformById(FUNCTION_ID_LOG);
311 				} else {
312 					mstruct.transformById(FUNCTION_ID_LOG);
313 				}
314 				var->destroy();
315 			} else if(use_abs > 0) {
316 				CALCULATOR->error(false, "Integral assumed real", NULL);
317 				mstruct.transformById(FUNCTION_ID_ABS);
318 				mstruct.transformById(FUNCTION_ID_LOG);
319 			} else {
320 				mstruct.transformById(FUNCTION_ID_LOG);
321 			}
322 		}
323 	} else {
324 		mstruct.transformById(FUNCTION_ID_LOG);
325 	}
326 	return true;
327 }
328 
329 // Make sure that m does not contains division by zero. Used after differentiation.
check_zero_div(const MathStructure & m,const MathStructure & x_var,const EvaluationOptions & eo,bool top=true)330 bool check_zero_div(const MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo, bool top = true) {
331 	if(top && (!x_var.isVariable() || x_var.variable()->isKnown() || ((UnknownVariable*) x_var.variable())->interval().isUndefined())) return true;
332 	if(m.isPower() && m[1].compare(m_zero) == COMPARISON_RESULT_GREATER && m[0].contains(x_var, true) > 0 && COMPARISON_MIGHT_BE_EQUAL(m[0].compare(m_zero))) return false;
333 	for(size_t i = 0; i < m.size(); i++) {
334 		if(!check_zero_div(m[i], x_var, eo)) return false;
335 	}
336 	/*if(m.isFunction() && m.size() == 1 && (m.function()->id() == FUNCTION_ID_TAN || m.function()->id() == FUNCTION_ID_TANH) && m[0].contains(x_var, true) > 0) {
337 		EvaluationOptions eo2 = eo;
338 		eo2.approximation = APPROXIMATION_APPROXIMATE;
339 		eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
340 		eo2.assume_denominators_nonzero = false;
341 		CALCULATOR->beginTemporaryStopMessages();
342 		MathStructure mfunc(m);
343 		mfunc.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
344 		bool b = mfunc.calculateFunctions(eo2);
345 		CALCULATOR->endTemporaryStopMessages();
346 		if(!b) return false;
347 	}*/
348 	return true;
349 }
350 
351 // 1/(ln(x)+5)=1/(ln(x*e^5)) if x>0
combine_ln(MathStructure & m,const MathStructure & x_var,const EvaluationOptions & eo,int depth=0)352 bool combine_ln(MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo, int depth = 0) {
353 	if(m.isAddition() && depth > 0 && m.containsFunctionId(FUNCTION_ID_LOG)) {
354 		size_t i_log = 0, i_mul_log = 0;
355 		bool b = false;
356 		MathStructure *mi = NULL;
357 		for(size_t i = 0; i < m.size(); i++) {
358 			if(!b && m[i].isMultiplication() && m[i].containsFunctionId(FUNCTION_ID_LOG) && m[i].contains(x_var, true)) {
359 				for(size_t i2 = 0; i2 < m[i].size(); i2++) {
360 					if(!b && m[i][i2].isFunction() && m[i][i2].function()->id() == FUNCTION_ID_LOG && m[i][i2].size() == 1 && m[i][i2][0].contains(x_var)) {
361 						b = true;
362 						i_log = i;
363 						i_mul_log = i2;
364 					} else if(m[i][i2].containsRepresentativeOf(x_var, true, true) != 0 || !m[i][i2].representsReal(true)) {
365 						b = false;
366 						break;
367 					}
368 				}
369 				if(!b) break;
370 			} else if(!b && m[i].isFunction() && m[i].function()->id() == FUNCTION_ID_LOG && m[i].size() == 1 && m[i][0].contains(x_var)) {
371 				b = true;
372 				i_log = i;
373 				break;
374 			} else if(!mi && m[i].isMultiplication() && m[i].size() == 2 && m[i][1].isVariable() && m[i][1].variable()->id() == VARIABLE_ID_PI && m[i][0].isNumber() && m[i][0].number().hasImaginaryPart() && !m[i][0].number().hasRealPart() && m[i][0].number().internalImaginary()->isReal()) {
375 				mi = &m[i][0];
376 			} else if(m[i].containsRepresentativeOf(x_var, true, true) != 0 || !m[i].representsReal(true)) {
377 				b = false;
378 				break;
379 			}
380 		}
381 		if(b && ((m[i_log].isMultiplication() && m[i_log][i_mul_log][0].compare(m_zero) == COMPARISON_RESULT_LESS) || (m[i_log].isFunction() && m[i_log][0].compare(m_zero) == COMPARISON_RESULT_LESS))) {
382 			MathStructure mmul(1, 1, 0);
383 			if(mi) mmul = *mi->number().internalImaginary();
384 			MathStructure *m_e = new MathStructure(CALCULATOR->getVariableById(VARIABLE_ID_E));
385 			MathStructure *mpow = new MathStructure;
386 			mpow->set_nocopy(m);
387 			mpow->delChild(i_log + 1, true);
388 			if(!mmul.isOne()) mpow->calculateDivide(mmul, eo);
389 			m_e->raise_nocopy(mpow);
390 			m_e->calculateRaiseExponent(eo);
391 			m.setToChild(i_log + 1, true);
392 			if(m.isMultiplication()) {
393 				MathStructure *mexp = new MathStructure;
394 				mexp->set_nocopy(m);
395 				mexp->delChild(i_mul_log + 1, true);
396 				if(!mmul.isOne()) mexp->calculateDivide(mmul, eo);
397 				m.setToChild(i_mul_log + 1, true);
398 				m[0].raise_nocopy(mexp);
399 				m[0].calculateRaiseExponent(eo);
400 			} else if(!mmul.isOne()) {
401 				MathStructure *mexp = new MathStructure(mmul);
402 				mexp->calculateInverse(eo);
403 				m[0].raise_nocopy(mexp);
404 				m[0].calculateRaiseExponent(eo);
405 			}
406 			m[0].multiply_nocopy(m_e);
407 			m[0].calculateMultiplyLast(eo);
408 			m.childUpdated(1);
409 			if(!mmul.isOne()) {m.multiply(mmul); m.swapChildren(1, 2);}
410 			return true;
411 		}
412 	}
413 	bool b_ret = false;
414 	for(size_t i = 0; i < m.size(); i++) {
415 		if(combine_ln(m[i], x_var, eo, depth + 1)) {
416 			m.childUpdated(i + 1);
417 			b_ret = true;
418 		}
419 	}
420 	if(b_ret) {
421 		m.calculatesub(eo, eo, false);
422 	}
423 	return b_ret;
424 }
425 
426 /* Determines the integral of mfac * ((mpowmul * mstruct) + mpowadd)^mpow, where mstruct is a function with x_var in argument.
427 */
integrate_function(MathStructure & mstruct,const MathStructure & x_var,const EvaluationOptions & eo,const MathStructure & mpow,const MathStructure & mfac,const MathStructure & mpowadd,const MathStructure & mpowmul,int use_abs,bool definite_integral,int max_part_depth,vector<MathStructure * > * parent_parts)428 int integrate_function(MathStructure &mstruct, const MathStructure &x_var, const EvaluationOptions &eo, const MathStructure &mpow, const MathStructure &mfac, const MathStructure &mpowadd, const MathStructure &mpowmul, int use_abs, bool definite_integral, int max_part_depth, vector<MathStructure*> *parent_parts) {
429 	if(mpow.containsRepresentativeOf(x_var, true, true) != 0) return false;
430 	// mpow != x
431 	if(!mpowadd.isZero() || !mpowmul.isOne()) {
432 		if(!mfac.isOne() || !mpow.isMinusOne()) return false;
433 		// mpowadd != 0, mpowmul != 1, mfac = 1, mpow = -1: 1/((mpowmul*mstruct)+mpowadd)
434 		if((mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_COS || mstruct.function()->id() == FUNCTION_ID_SINH || mstruct.function()->id() == FUNCTION_ID_COSH || mstruct.function()->id() == FUNCTION_ID_LOG) && mstruct.size() == 1) {
435 			MathStructure mexp, mmul, madd;
436 			if(integrate_info(mstruct[0], x_var, madd, mmul, mexp, (mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_COS))) {
437 				if(mexp.isOne()) {
438 					bool neg_equals = false;
439 					if((mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_COS || mstruct.function()->id() == FUNCTION_ID_COSH) && mpowadd != mpowmul) {
440 						MathStructure mpowaddneg(mpowadd);
441 						mpowaddneg.calculateNegate(eo);
442 						neg_equals = (mpowaddneg == mpowmul);
443 					}
444 					if(mstruct.function()->id() == FUNCTION_ID_SIN) {
445 						if(mpowadd == mpowmul || neg_equals) {
446 							//1/(c*sin(ax+b)+c): 2*sin((a x + b)/2)*(sin((a x + b)/2)+cos((a x + b)/2))/(a*(c*sin((a x + b))+c))
447 							MathStructure mdiv(mstruct);
448 							mstruct[0] *= nr_half;
449 							MathStructure msin(mstruct);
450 							MathStructure mcos(mstruct);
451 							mcos.setFunctionId(FUNCTION_ID_COS);
452 							mstruct *= nr_two;
453 							if(mpowadd != mpowmul) msin.negate();
454 							msin += mcos;
455 							mstruct *= msin;
456 							mdiv *= mpowmul;
457 							mdiv += mpowadd;
458 							if(!mmul.isOne()) mdiv *= mmul;
459 							mstruct /= mdiv;
460 							return true;
461 						} else {
462 							//1/(d*sin(ax+b)+c): (2 atan((c*tan((a x + b)/2)+d)/sqrt(c^2-d^2)))/(a*sqrt(c^2-d^2))
463 							if(definite_integral && x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
464 								MathStructure mtest(mstruct[0]);
465 								mtest[0] /= CALCULATOR->getRadUnit();
466 								mtest[0] /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
467 								mtest[0] /= nr_two;
468 								mtest[0].transformById(FUNCTION_ID_ABS);
469 								mtest[0].transformById(FUNCTION_ID_FRAC);
470 								if(COMPARISON_MIGHT_BE_EQUAL(mtest.compare(nr_half))) return -1;
471 							}
472 							mstruct.setFunctionId(FUNCTION_ID_TAN);
473 							mstruct[0] *= nr_half;
474 							mstruct *= mpowadd;
475 							mstruct += mpowmul;
476 							MathStructure msqrtc2md2(mpowadd);
477 							if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
478 							MathStructure mmpowmul2(mpowmul);
479 							if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
480 							mmpowmul2.negate();
481 							msqrtc2md2 += mmpowmul2;
482 							msqrtc2md2 ^= Number(-1, 2, 0);
483 							mstruct *= msqrtc2md2;
484 							mstruct.transformById(FUNCTION_ID_ATAN);
485 							mstruct *= msqrtc2md2;
486 							if(!mmul.isOne()) mstruct /= mmul;
487 							mstruct *= nr_two;
488 							return true;
489 						}
490 					} else if(mstruct.function()->id() == FUNCTION_ID_COS) {
491 						if(mpowadd == mpowmul) {
492 							//1/(c*cos(ax+b)+c): tan((a x + b)/2)/(ac)
493 							mstruct[0] *= nr_half;
494 							mstruct.setFunctionId(FUNCTION_ID_TAN);
495 							if(!mpowadd.isOne()) mstruct /= mpowadd;
496 							if(!mmul.isOne()) mstruct /= mmul;
497 							return true;
498 						} else if(neg_equals) {
499 							//1/(c*cos(ax+b)-c): cos((a x + b)/2)/(ac*sin((a x + b)/2))
500 							mstruct[0] *= nr_half;
501 							MathStructure msin(mstruct);
502 							msin.setFunctionId(FUNCTION_ID_SIN);
503 							mstruct /= msin;
504 							if(!mpowmul.isOne()) mstruct /= mpowmul;
505 							if(!mmul.isOne()) mstruct /= mmul;
506 							return true;
507 						} else {
508 							//1/(d*cos(ax+b)+c): -(2*atanh(((c-d)*tan((a x + b)/2))/sqrt(d^2-c^2)))/(a*sqrt(d^2-c^2))
509 							if(definite_integral && x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
510 								MathStructure mtest(mstruct[0]);
511 								mtest[0] /= CALCULATOR->getRadUnit();
512 								mtest[0] /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
513 								mtest[0] /= nr_two;
514 								mtest[0].transformById(FUNCTION_ID_ABS);
515 								mtest[0].transformById(FUNCTION_ID_FRAC);
516 								if(COMPARISON_MIGHT_BE_EQUAL(mtest.compare(nr_half))) return -1;
517 							}
518 							mstruct.setFunctionId(FUNCTION_ID_TAN);
519 							mstruct[0] *= nr_half;
520 							mstruct *= mpowadd;
521 							mstruct.last() -= mpowmul;
522 							mstruct.childUpdated(mstruct.size());
523 							MathStructure msqrtc2md2(mpowadd);
524 							if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
525 							msqrtc2md2.negate();
526 							MathStructure mmpowmul2(mpowmul);
527 							if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
528 							msqrtc2md2 += mmpowmul2;
529 							msqrtc2md2 ^= Number(-1, 2, 0);
530 							mstruct *= msqrtc2md2;
531 							mstruct.transformById(FUNCTION_ID_ATANH);
532 							mstruct *= msqrtc2md2;
533 							if(!mmul.isOne()) mstruct /= mmul;
534 							mstruct *= Number(-2, 1);
535 							return true;
536 						}
537 					} else if(mstruct.function()->id() == FUNCTION_ID_SINH) {
538 						//1/(d*sinh(ax+b)+c): (2 atan((-c*tan((a x + b)/2)+d)/sqrt(-c^2-d^2)))/(a*sqrt(-c^2-d^2))
539 						mstruct.setFunctionId(FUNCTION_ID_TANH);
540 						mstruct[0] *= nr_half;
541 						mstruct *= mpowadd;
542 						mstruct.negate();
543 						mstruct += mpowmul;
544 						MathStructure msqrtc2md2(mpowadd);
545 						if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
546 						msqrtc2md2.negate();
547 						MathStructure mmpowmul2(mpowmul);
548 						if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
549 						mmpowmul2.negate();
550 						msqrtc2md2 += mmpowmul2;
551 						msqrtc2md2 ^= Number(-1, 2, 0);
552 						mstruct *= msqrtc2md2;
553 						mstruct.transformById(FUNCTION_ID_ATAN);
554 						mstruct *= msqrtc2md2;
555 						if(!mmul.isOne()) mstruct /= mmul;
556 						mstruct *= nr_two;
557 						return true;
558 					} else if(mstruct.function()->id() == FUNCTION_ID_COSH) {
559 						if(mpowadd == mpowmul) {
560 							//1/(c*cosh(ax+b)+c): tanh((a x + b)/2)/(ac)
561 							mstruct[0] *= nr_half;
562 							mstruct.setFunctionId(FUNCTION_ID_TANH);
563 							if(!mpowadd.isOne()) mstruct /= mpowadd;
564 							if(!mmul.isOne()) mstruct /= mmul;
565 							return true;
566 						} else if(neg_equals) {
567 							//1/(c*cosh(ax+b)-c): -cosh((a x + b)/2)/(ac*sinh((a x + b)/2))
568 							mstruct[0] *= nr_half;
569 							MathStructure msin(mstruct);
570 							msin.setFunctionId(FUNCTION_ID_SINH);
571 							mstruct.negate();
572 							mstruct /= msin;
573 							if(!mpowmul.isOne()) mstruct /= mpowmul;
574 							if(!mmul.isOne()) mstruct /= mmul;
575 							return true;
576 						} else {
577 							//1/(d*cos(ax+b)+c): -(2*atan(((c-d)*tanh((a x + b)/2))/sqrt(d^2-c^2)))/(a*sqrt(d^2-c^2))
578 							mstruct.setFunctionId(FUNCTION_ID_TANH);
579 							mstruct[0] *= nr_half;
580 							mstruct *= mpowadd;
581 							mstruct.last() -= mpowmul;
582 							mstruct.childUpdated(mstruct.size());
583 							MathStructure msqrtc2md2(mpowadd);
584 							if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
585 							msqrtc2md2.negate();
586 							MathStructure mmpowmul2(mpowmul);
587 							if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
588 							msqrtc2md2 += mmpowmul2;
589 							msqrtc2md2 ^= Number(-1, 2, 0);
590 							mstruct *= msqrtc2md2;
591 							mstruct.transformById(FUNCTION_ID_ATAN);
592 							mstruct *= msqrtc2md2;
593 							if(!mmul.isOne()) mstruct /= mmul;
594 							mstruct *= Number(-2, 1);
595 							return true;
596 						}
597 					} else if(mstruct.function()->id() == FUNCTION_ID_LOG) {
598 						//1/(d*ln(ax+b)+c): (e^(-c/d)*Ei(c/d+ln(ax+b)))/(a*d)
599 						MathStructure mpadm(mpowadd);
600 						if(!mpowmul.isOne()) mpadm /= mpowmul;
601 						mstruct += mpadm;
602 						mstruct.transformById(FUNCTION_ID_EXPINT);
603 						mpadm.negate();
604 						mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_E);
605 						mstruct.last() ^= mpadm;
606 						mstruct.childUpdated(mstruct.size());
607 						if(!mmul.isOne()) mstruct /= mmul;
608 						if(!mpowmul.isOne()) mstruct /= mpowmul;
609 						return true;
610 					}
611 				} else if(mstruct.function()->id() == FUNCTION_ID_LOG && madd.isZero()) {
612 					//1/(d*ln(ax^b)+c): (x*(ax^b)^(-1/b)*e^(-c/(bd))*Ei((c+d*ln(ax^b))/(bd)))/(bd)
613 					MathStructure mem(mexp);
614 					if(!mpowmul.isOne()) mem *= mpowmul;
615 					mem.inverse();
616 					MathStructure marg(mstruct[0]);
617 					mexp.inverse();
618 					mexp.negate();
619 					marg ^= mexp;
620 					MathStructure mexpe(CALCULATOR->getVariableById(VARIABLE_ID_E));
621 					if(!mpowadd.isZero()) {
622 						MathStructure mepow(mpowadd);
623 						mepow.negate();
624 						mepow *= mem;
625 						mexpe ^= mepow;
626 					}
627 					if(!mpowmul.isOne()) mstruct *= mpowmul;
628 					if(!mpowadd.isZero()) mstruct += mpowadd;
629 					mstruct *= mem;
630 					mstruct.transformById(FUNCTION_ID_EXPINT);
631 					if(!mpowadd.isZero()) mstruct *= mexpe;
632 					mstruct *= marg;
633 					mstruct *= x_var;
634 					mstruct *= mem;
635 					return true;
636 				}
637 			}
638 		}
639 		return false;
640 	}
641 	// mpowadd=0 and mpowmul=1: mfac*mstruct^mpow
642 
643 	if(mstruct.function()->id() == FUNCTION_ID_LOG && mstruct.size() == 1) {
644 		if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct[0]) && mpow.isOne() && mfac.isOne() && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
645 			MathStructure mexp, mmul, madd;
646 			if(integrate_info(mstruct[0][0], x_var, madd, mmul, mexp) && mexp.isOne()) {
647 				if(madd.isZero()) {
648 					if(mmul.isZero()) {
649 						mstruct *= x_var;
650 						mstruct += x_var;
651 						mstruct.last().divide(mstruct[0][1]);
652 						mstruct.childUpdated(mstruct.size());
653 						mstruct.last().negate();
654 						return true;
655 					}
656 					MathStructure mterm(mstruct[0]);
657 					mterm ^= nr_two;
658 					mterm *= mstruct[0];
659 					mterm.inverse();
660 					if(!mmul.isOne()) mterm *= mmul;
661 					mterm *= x_var;
662 					mterm.last() ^= nr_two;
663 					mterm *= Number(-1, 3);
664 					mstruct *= x_var;
665 					mstruct += mterm;
666 					return true;
667 				}
668 				MathStructure mterm1(x_var);
669 				if(!mmul.isOne()) mterm1 *= mmul;
670 				if(!madd.isOne()) mterm1 /= madd;
671 				mterm1 += m_one;
672 				if(!transform_absln(mterm1, use_abs, definite_integral, x_var, eo)) return -1;
673 				if(!mmul.isOne()) mterm1 /= mmul;
674 				if(!madd.isOne()) mterm1 *= madd;
675 				mterm1 /= mstruct[0][1];
676 				MathStructure mterm2(x_var);
677 				mterm2 /= mstruct[0][1];
678 				mstruct *= x_var;
679 				mstruct += mterm1;
680 				mstruct -= mterm2;
681 				return true;
682 			}
683 		}
684 		MathStructure mexp, mmul, madd;
685 		if(integrate_info(mstruct[0], x_var, madd, mmul, mexp, false, false, true) && (mexp == x_var || (mexp.isPower() && mexp[0] == x_var && ((mexp[1] == x_var && madd.isZero() && mpow.isOne() && (!definite_integral || x_var.representsNonNegative(true))) || mexp[1].containsRepresentativeOf(x_var, true, true) == 0)) || (mpow.isOne() && madd.isZero() && mexp.isFunction() && mexp.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mexp) && mexp[0] == x_var) || (mpow.isOne() && madd.isZero() && mexp.isPower() && mexp[1].isInteger() && mexp[0].isFunction() && mexp[0].function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mexp[0]) && mexp[0][0] == x_var))) {
686 			bool b_root =  false;
687 			if(mexp == x_var) mexp.set(1, 1, 0);
688 			else if(mexp.isPower() && mexp[0] == x_var) mexp.setToChild(2);
689 			else if(mexp.isPower()) {mexp[0].setToChild(2); mexp[0].number().recip(); mexp[0].number() *= mexp[1].number(); mexp.setToChild(1); b_root = true;}
690 			else {mexp.setToChild(2); mexp.number().recip(); b_root = true;}
691 			bool do_if = false;
692 			// if mstruct[0]=0 for lower or upper limit do if(mstruct[0]=0,0,f(x))
693 			if(definite_integral && x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
694 				MathStructure mtest(((UnknownVariable*) x_var.variable())->interval());
695 				mtest.eval(eo);
696 				if(mtest.isNumber()) {
697 					MathStructure mtest2(mstruct[0]);
698 					mtest2.replace(x_var, mtest.number().lowerEndPoint());
699 					mtest2.eval(eo);
700 					do_if = (mtest2.isNumber() && !mtest2.number().isNonZero());
701 					if(!do_if) {
702 						mtest2 = mstruct[0];
703 						mtest2.replace(x_var, mtest.number().upperEndPoint());
704 						mtest2.eval(eo);
705 						do_if = (mtest2.isNumber() && !mtest2.number().isNonZero());
706 					}
707 				}
708 			}
709 			MathStructure mif;
710 			MathStructure marg(mstruct[0]);
711 			bool b = false;
712 			if(mexp == x_var) {
713 				if(mfac.isOne()) {
714 					// ln(x^x): x*ln(x^x)-x^2*(ln(x)*2+1)/4
715 					mstruct *= x_var;
716 					MathStructure mterm(x_var);
717 					mterm.transformById(FUNCTION_ID_LOG);
718 					mterm *= nr_two;
719 					mterm += m_one;
720 					mterm *= x_var;
721 					mterm.last() ^= nr_two;
722 					mterm *= Number(-1, 4);
723 					mstruct += mterm;
724 					b = true;
725 				} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
726 					// ln(x^x)*x^a: -x(-(a+2)^2*ln(x^x)+(a+2)(x*ln(x))+(a+1)x)/((a+1)(a+2)^2)
727 					if(mfac == x_var) mexp.set(1, 1, 0);
728 					else mexp = mfac[1];
729 					MathStructure mexpp1(mexp);
730 					mexpp1 += m_one;
731 					MathStructure mexpp2(mexp);
732 					mexpp2 += nr_two;
733 					MathStructure mterm1(x_var);
734 					mterm1.transformById(FUNCTION_ID_LOG);
735 					mterm1 *= x_var;
736 					mterm1 *= mexpp2;
737 					MathStructure mterm2(x_var);
738 					mterm2 *= mexpp1;
739 					mstruct.negate();
740 					mexpp2 ^= nr_two;
741 					mstruct *= mexpp2;
742 					mstruct += mterm1;
743 					mstruct += mterm2;
744 					mstruct *= x_var;
745 					mstruct.last() ^= mexpp1;
746 					mexpp2 *= mexpp1;
747 					mstruct /= mexpp2;
748 					mstruct.negate();
749 					b = true;
750 				}
751 			} else if(mfac.isOne() && (mexp.isOne() || madd.isZero())) {
752 				if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-1)) {
753 					if(mpow.isOne()) {
754 						if(madd.isZero()) {
755 							// ln(ax^b): x(ln(ax^b)-b)
756 							mstruct -= mexp;
757 							mstruct.multiply(x_var);
758 							b = true;
759 						} else {
760 							// ln(ax+b): (ax+b)(ln(ax)-1)/a
761 							MathStructure marg(mstruct[0]);
762 							mstruct *= marg;
763 							mstruct -= marg;
764 							if(!mmul.isOne()) mstruct.divide(mmul);
765 							b = true;
766 						}
767 					} else if(mpow.number().isTwo()) {
768 						// ln(ax+b)^2: (ln(ax+b)^2-2*ln(ax+b)+2)(ax+b)/a
769 						// ln(ax^b)^2: x(ln(ax^b)^2-2*ln(ax^b)*b+2b^2)
770 						MathStructure marg(mstruct[0]);
771 						MathStructure mterm2(mstruct);
772 						mstruct ^= mpow;
773 						mterm2 *= Number(-2, 1);
774 						if(mexp.isOne()) {
775 							mterm2 += nr_two;
776 						} else {
777 							mterm2 *= mexp;
778 							mterm2 += mexp;
779 							mterm2.last() ^= nr_two;
780 							mterm2.last() *= nr_two;
781 						}
782 						mstruct += mterm2;
783 						if(madd.isZero()) {
784 							mstruct.multiply(x_var);
785 						} else {
786 							mstruct *= marg;
787 							if(!mmul.isOne()) mstruct /= mmul;
788 						}
789 						b = true;
790 					} else if(mpow.number().isMinusOne()) {
791 						if(mexp.isOne()) {
792 							// ln(ax+b)^-1: li(ax+b)/a
793 							if(!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0].compare(m_zero))) {
794 								mstruct.setFunctionId(FUNCTION_ID_LOGINT);
795 								if(!mmul.isOne()) mstruct /= mmul;
796 								b = true;
797 								do_if = false;
798 							}
799 						}
800 					} else {
801 						// ln(ax^b)^n: x*sum(ln(ax^b)^i*n!/i!*(-b)^(n-i), 0, n)
802 						// ln(ax+b)^n: (ax+b)/a*sum(ln(ax+b)^i*n!/i!*(-1)^(n-i), 0, n)
803 						unsigned long int n = mpow.number().uintValue();
804 						MathStructure marg(mstruct[0]);
805 						Number nfac(mpow.number());
806 						nfac.factorial();
807 						for(size_t i = 0; i <= n; i++) {
808 							MathStructure mterm(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &marg, NULL);
809 							mterm ^= Number(i);
810 							mterm *= nfac;
811 							Number ifac(i);
812 							ifac.factorial();
813 							mterm /= ifac;
814 							MathStructure m1pow(mexp);
815 							m1pow.negate();
816 							m1pow ^= Number(n - i);
817 							mterm *= m1pow;
818 							if(i == 0) mstruct = mterm;
819 							else mstruct += mterm;
820 						}
821 						if(madd.isZero()) {
822 							mstruct.multiply(x_var);
823 						} else {
824 							mstruct *= marg;
825 							if(!mmul.isOne()) mstruct /= mmul;
826 						}
827 						b = true;
828 					}
829 				}
830 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
831 				MathStructure mfacexp(1, 1, 0);
832 				if(mfac != x_var) mfacexp = mfac[1];
833 				if(mfacexp.isMinusOne()) {
834 					if(mpow.isMinusOne()) {
835 						if(mexp.isOne() && madd.isZero()) {
836 							mstruct.transformById(FUNCTION_ID_LOG);
837 							b = true;
838 						}
839 					} else if(madd.isZero()) {
840 						MathStructure mpowp1(mpow);
841 						mpowp1 += m_one;
842 						mstruct ^= mpowp1;
843 						mstruct /= mpowp1;
844 						if(!mexp.isOne()) mstruct /= mexp;
845 						b = true;
846 					} else if(mpow.isOne()) {
847 						MathStructure m_axcb(x_var);
848 						if(!mexp.isOne()) m_axcb ^= mexp;
849 						if(!mmul.isOne()) m_axcb *= mmul;
850 						if(!madd.isZero()) m_axcb /= madd;
851 						mstruct *= m_axcb;
852 						mstruct.last().negate();
853 						mstruct.last().transformById(FUNCTION_ID_LOG);
854 						MathStructure mterm2(m_axcb);
855 						mterm2 += m_one;
856 						mterm2.transformById(FUNCTION_ID_POLYLOG);
857 						mterm2.insertChild(nr_two, 1);
858 						mstruct += mterm2;
859 						if(!mexp.isOne()) mstruct /= mexp;
860 						b = true;
861 					}
862 					do_if = do_if && !madd.isZero();
863 				} else if(madd.isZero()) {
864 					if(mpow.isOne()) {
865 						mfacexp += m_one;
866 						mstruct *= mfacexp;
867 						mstruct -= mexp;
868 						mstruct *= x_var;
869 						mstruct.last() ^= mfacexp;
870 						mfacexp ^= Number(-2, 1);
871 						mstruct *= mfacexp;
872 						mstruct.childrenUpdated();
873 						b = true;
874 					} else if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100)) {
875 						if(mpow.isMinusOne()) {
876 							if(!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0].compare(m_zero))) {
877 								if(mexp.isOne()) {
878 									MathStructure mmulfac(mmul);
879 									if(!mmul.isOne()) {
880 										mmulfac *= x_var;
881 										mmulfac ^= mfacexp;
882 										mmulfac[1].negate();
883 										mmulfac *= x_var;
884 										mmulfac.last() ^= mfacexp;
885 										mmulfac.childrenUpdated(true);
886 									}
887 									mfacexp += m_one;
888 									mstruct *= mfacexp;
889 									mstruct.transformById(FUNCTION_ID_EXPINT);
890 									if(!mmul.isOne()) {
891 										mstruct *= mmulfac;
892 										mstruct /= mmul;
893 									}
894 									b = true;
895 								} else {
896 									MathStructure mepow(mstruct);
897 									mfacexp += m_one;
898 									mstruct *= mfacexp;
899 									mstruct /= mexp;
900 									mstruct.transformById(FUNCTION_ID_EXPINT);
901 									mepow.negate();
902 									mepow += x_var;
903 									mepow.last().transformById(FUNCTION_ID_LOG);
904 									mepow.last() *= mexp;
905 									mepow *= mfacexp;
906 									mepow /= mexp;
907 									MathStructure memul(CALCULATOR->getVariableById(VARIABLE_ID_E));
908 									memul ^= mepow;
909 									mstruct *= memul;
910 									mstruct /= mexp;
911 									b = true;
912 								}
913 							}
914 						} else if(mpow.number().isNegative()) {
915 							if(mexp.isOne()) {
916 								MathStructure mpowp1(mpow);
917 								mpowp1 += m_one;
918 								MathStructure mpowp1n(mpowp1);
919 								mpowp1n.negate();
920 								MathStructure mterm(mstruct);
921 								mstruct ^= mpowp1;
922 								mstruct *= x_var;
923 								mstruct.last() ^= mfacexp;
924 								if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
925 								mfacexp += m_one;
926 								mstruct *= mfacexp;
927 								mstruct /= mpowp1n;
928 								mterm ^= mpowp1;
929 								mterm *= x_var;
930 								mterm.last() ^= mfacexp;
931 								mterm /= mpowp1n;
932 								mstruct -= mterm;
933 								mstruct.childrenUpdated(true);
934 								b = true;
935 							}
936 						} else {
937 							MathStructure mterm(mstruct);
938 							mstruct ^= mpow;
939 							mstruct.last() += nr_minus_one;
940 							mstruct *= x_var;
941 							mstruct.last() ^= mfacexp;
942 							if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
943 							mstruct *= mpow;
944 							mfacexp += m_one;
945 							mstruct /= mfacexp;
946 							mstruct.negate();
947 							mstruct *= mexp;
948 							mterm ^= mpow;
949 							mterm *= x_var;
950 							mterm.last() ^= mfacexp;
951 							mterm /= mfacexp;
952 							mstruct += mterm;
953 							mstruct.childrenUpdated(true);
954 							b = true;
955 						}
956 					}
957 				} else if(mfac == x_var && mexp.isOne()) {
958 					if(mpow.isOne()) {
959 						MathStructure mterm2(x_var);
960 						if(!mmul.isOne()) mterm2 *= mmul;
961 						mterm2 += madd;
962 						mterm2.last() *= Number(-2, 1);
963 						mterm2 *= x_var;
964 						if(!mmul.isOne()) mterm2 /= mmul;
965 						mterm2 *= Number(-1, 4);
966 						MathStructure marg(x_var);
967 						if(!mmul.isOne()) marg *= mmul;
968 						marg += madd;
969 						mstruct *= marg;
970 						marg.last() *= nr_minus_one;
971 						mstruct *= marg;
972 						if(!mmul.isOne()) {
973 							mstruct *= mmul;
974 							mstruct.last() ^= Number(-2, 1);
975 						}
976 						mstruct *= nr_half;
977 						mstruct += mterm2;
978 						mstruct.childrenUpdated(true);
979 						b = true;
980 						if(do_if) mif = mterm2;
981 					}
982 				}
983 			} else if(!b_root && mfac.isFunction() && mfac.function()->id() == FUNCTION_ID_LOG && mfac.size() == 1 && madd.isZero() && mpow.isOne()) {
984 				MathStructure mexp2, mmul2, madd2;
985 				if(integrate_info(mfac[0], x_var, madd2, mmul2, mexp2) && madd2.isZero()) {
986 					MathStructure mterm2(mfac);
987 					mterm2.negate();
988 					mterm2 += nr_two;
989 					if(!mexp2.isOne()) {
990 						mterm2.last() *= mexp2;
991 						mterm2.childUpdated(mterm2.size());
992 					}
993 					if(!mexp.isOne()) mterm2 *= mexp;
994 					mstruct *= mfac;
995 					mstruct.last() -= mexp2;
996 					mstruct.childUpdated(mstruct.size());
997 					mstruct += mterm2;
998 					mstruct *= x_var;
999 					b = true;
1000 				}
1001 			}
1002 			if(b) {
1003 				if(do_if) {
1004 					mstruct.transformById(FUNCTION_ID_IF);
1005 					mstruct.insertChild(mif, 1);
1006 					mstruct.insertChild(marg, 1);
1007 					mstruct.addChild(m_zero);
1008 					mstruct[0].transform(COMPARISON_EQUALS, m_zero);
1009 				}
1010 				return true;
1011 			}
1012 		}
1013 	} else if(mstruct.function()->id() == FUNCTION_ID_LAMBERT_W && mstruct.size() >= 1) {
1014 		if(mfac == x_var && mpow.isOne() && mstruct[0] == x_var) {
1015 			MathStructure mthis(mstruct);
1016 			mstruct ^= nr_two;
1017 			mstruct *= nr_two;
1018 			mstruct += nr_one;
1019 			mstruct *= mthis;
1020 			mstruct.last() *= nr_two;
1021 			mstruct.last() += nr_minus_one;
1022 			mstruct *= x_var;
1023 			mstruct.last() ^= nr_two;
1024 			mstruct *= mthis;
1025 			mstruct.last() ^= Number(-2, 1);
1026 			mstruct *= Number(1, 8);
1027 			return true;
1028 		} else if(mfac.isPower() && mfac[0] == x_var && mfac[1].isMinusOne() && mpow.isOne() && mstruct[0] == x_var) {
1029 			MathStructure mthis(mstruct);
1030 			mstruct += nr_two;
1031 			mstruct *= mthis;
1032 			mstruct *= nr_half;
1033 			return true;
1034 		} else if((mpow.isOne() || (mpow.isNumber() && mpow.number().isTwo())) && mfac.isOne()) {
1035 			MathStructure mexp, mmul, madd;
1036 			if(integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1037 				if(mpow.isOne()) {
1038 					MathStructure mthis(mstruct);
1039 					mstruct ^= nr_two;
1040 					mstruct -= mthis;
1041 					mstruct += m_one;
1042 					mstruct *= mthis[0];
1043 					mstruct /= mthis;
1044 					if(!mmul.isOne()) mstruct /= mmul;
1045 					return true;
1046 				} else {
1047 					MathStructure mthis(mstruct);
1048 					mstruct ^= nr_three;
1049 					mstruct += mthis;
1050 					mstruct.last() ^= nr_two;
1051 					mstruct.last() *= Number(-2, 1);
1052 					mstruct += mthis;
1053 					mstruct.last() *= Number(4, 1);
1054 					mstruct += Number(-4, 1);
1055 					mstruct *= mthis[0];
1056 					mstruct /= mthis;
1057 					if(!mmul.isOne()) mstruct /= mmul;
1058 					return true;
1059 				}
1060 			}
1061 		}
1062 		return false;
1063 	} else if(mstruct.function()->id() == FUNCTION_ID_SIGNUM && mstruct.size() == 2) {
1064 		if(mstruct[0].representsNonComplex(true) && mpow.isNumber() && mpow.number().isRational() && mpow.number().isPositive()) {
1065 			MathStructure minteg(x_var);
1066 			if(!mfac.isOne()) {
1067 				minteg = mfac;
1068 				if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1069 			}
1070 			if(!mpow.number().isInteger()) {
1071 				MathStructure mmul(-1, 1, 0);
1072 				Number nr_frac(mpow.number());
1073 				Number nr_int(mpow.number());
1074 				nr_frac.frac();
1075 				nr_int.trunc();
1076 				mmul ^= nr_frac;
1077 				if(nr_int.isEven()) mmul += nr_minus_one;
1078 				else mmul += m_one;
1079 				mstruct *= mmul;
1080 				mstruct -= mmul[0];
1081 				if(nr_int.isEven()) mstruct += nr_minus_one;
1082 				else mstruct += m_one;
1083 				if(nr_int.isEven()) mstruct.negate();
1084 				mstruct /= nr_two;
1085 			} else if(mpow.number().isEven()) {
1086 				mstruct ^= nr_two;
1087 				mstruct += nr_three;
1088 				mstruct *= Number(1, 4);
1089 			}
1090 			mstruct *= minteg;
1091 			return true;
1092 		}
1093 	} else if(mstruct.function()->id() == FUNCTION_ID_DIRAC && mstruct.size() == 1 && mstruct[0].representsNonComplex(true)) {
1094 		MathStructure mexp, mmul, madd;
1095 		if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1096 			if(mfac == x_var && madd.representsNonZero()) {
1097 				mstruct.setFunctionId(FUNCTION_ID_HEAVISIDE);
1098 				if(!mmul.isOne()) {
1099 					mmul ^= nr_two;
1100 					mstruct /= mmul;
1101 				}
1102 				mstruct *= madd;
1103 				mstruct.negate();
1104 				return true;
1105 			} else if(mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0 && madd.representsNonZero()) {
1106 				mstruct.setFunctionId(FUNCTION_ID_HEAVISIDE);
1107 				madd.negate();
1108 				madd ^= mfac[1];
1109 				mstruct *= madd;
1110 				if(mmul.isOne()) {
1111 					mexp = mfac[1];
1112 					mexp += m_one;
1113 					mexp.negate();
1114 					mmul ^= mexp;
1115 					mstruct *= mmul;
1116 				}
1117 				return true;
1118 			} else if(mfac.isOne()) {
1119 				mstruct.setFunctionId(FUNCTION_ID_HEAVISIDE);
1120 				if(!mmul.isOne()) mstruct /= mmul;
1121 				return true;
1122 			}
1123 		}
1124 		return false;
1125 	} else if(mstruct.function()->id() == FUNCTION_ID_ARG && mstruct.size() == 1 && mstruct[0].representsNonComplex(true)) {
1126 		MathStructure mexp, mmul, madd;
1127 		if(mpow.representsPositive() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
1128 			MathStructure minteg(x_var);
1129 			if(!mfac.isOne()) {
1130 				minteg = mfac;
1131 				if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1132 			}
1133 			mstruct.setFunctionId(FUNCTION_ID_SIGNUM);
1134 			mstruct += nr_minus_one;
1135 			mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1136 			if(!mpow.isOne()) {
1137 				mstruct.last() ^= mpow;
1138 				mstruct.childUpdated(mstruct.size());
1139 			}
1140 			mstruct *= Number(-1, 2);
1141 			mstruct *= minteg;
1142 			return true;
1143 		}
1144 		return false;
1145 	} else if(mstruct.function()->id() == FUNCTION_ID_HEAVISIDE && mstruct.size() == 1) {
1146 		MathStructure mexp, mmul, madd;
1147 		if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1148 			if(mfac.isOne()) {
1149 				if(mmul.representsNonNegative()) {
1150 					MathStructure mfacn(x_var);
1151 					if(!madd.isZero()) {
1152 						if(!mmul.isOne()) madd /= mmul;
1153 						mfacn += madd;
1154 					}
1155 					mstruct *= mfacn;
1156 					return true;
1157 				} else if(mmul.representsNegative()) {
1158 					if(madd.isZero()) {
1159 						mstruct[0] = x_var;
1160 						mstruct *= x_var;
1161 						mstruct.negate();
1162 						mstruct += x_var;
1163 						return true;
1164 					}
1165 					mstruct.setToChild(1);
1166 					mmul.negate();
1167 					madd.negate();
1168 					mstruct /= mmul;
1169 					MathStructure mfacn(x_var);
1170 					mfacn *= mmul;
1171 					mfacn += madd;
1172 					mfacn.transformById(FUNCTION_ID_HEAVISIDE);
1173 					mstruct *= mfacn;
1174 					mstruct += x_var;
1175 					return true;
1176 				}
1177 			}
1178 		}
1179 		return false;
1180 	} else if(mstruct.function()->id() == FUNCTION_ID_SINC && mstruct.size() == 1) {
1181 		MathStructure mexp, mmul, madd;
1182 		if(mfac.isOne() && mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-2) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1183 			if(mpow.isOne()) {
1184 				mstruct.setFunctionId(FUNCTION_ID_SININT);
1185 				if(!mmul.isOne()) mstruct.divide(mmul);
1186 				return true;
1187 			}
1188 		}
1189 	} else if(mstruct.function()->id() == FUNCTION_ID_SIN && mstruct.size() == 1) {
1190 		MathStructure mexp, mmul, madd;
1191 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp, true)) {
1192 			if(mfac.isOne()) {
1193 				if(mexp.isOne()) {
1194 					if(mpow.isOne()) {
1195 						mstruct.setFunctionId(FUNCTION_ID_COS);
1196 						mstruct.multiply(m_minus_one);
1197 						if(!mmul.isOne()) mstruct.divide(mmul);
1198 					} else if(mpow.number().isTwo()) {
1199 						if(!madd.isZero()) {
1200 							mstruct[0] = x_var;
1201 							mstruct[0] *= CALCULATOR->getRadUnit();
1202 						}
1203 						mstruct[0] *= nr_two;
1204 						mstruct /= 4;
1205 						if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
1206 						mstruct.negate();
1207 						MathStructure xhalf(x_var);
1208 						xhalf *= nr_half;
1209 						mstruct += xhalf;
1210 						if(!madd.isZero()) {
1211 							MathStructure marg(x_var);
1212 							if(!mmul.isOne()) marg *= mmul;
1213 							marg += madd;
1214 							mstruct.replace(x_var, marg);
1215 							if(!mmul.isOne()) mstruct.divide(mmul);
1216 						}
1217 					} else if(mpow.number().isMinusOne()) {
1218 						MathStructure mcot(mstruct);
1219 						mcot.setFunctionId(FUNCTION_ID_TAN);
1220 						mcot.inverse();
1221 						mstruct.inverse();
1222 						mstruct += mcot;
1223 						if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1224 						if(!mmul.isOne()) mstruct.divide(mmul);
1225 						mstruct.negate();
1226 					} else if(mpow.number() == -2) {
1227 						mstruct.setFunctionId(FUNCTION_ID_TAN);
1228 						mstruct.inverse();
1229 						mstruct.negate();
1230 						if(!mmul.isOne()) mstruct.divide(mmul);
1231 					} else if(mpow.number().isPositive()) {
1232 						MathStructure mbak(mstruct);
1233 						MathStructure nm1(mpow);
1234 						nm1 += nr_minus_one;
1235 						mstruct ^= nm1;
1236 						MathStructure mcos(mbak);
1237 						mcos.setFunctionId(FUNCTION_ID_COS);
1238 						mstruct *= mcos;
1239 						mstruct.negate();
1240 						mmul *= mpow;
1241 						mstruct /= mmul;
1242 						MathStructure minteg(mbak);
1243 						MathStructure nm2(mpow);
1244 						nm2 += Number(-2, 1);
1245 						minteg ^= nm2;
1246 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1247 						minteg *= nm1;
1248 						minteg /= mpow;
1249 						mstruct += minteg;
1250 					} else {
1251 						MathStructure mbak(mstruct);
1252 						MathStructure np1(mpow);
1253 						np1 += m_one;
1254 						mstruct ^= np1;
1255 						MathStructure mcos(mbak);
1256 						mcos.setFunctionId(FUNCTION_ID_COS);
1257 						mstruct *= mcos;
1258 						mstruct /= np1;
1259 						mstruct /= mmul;
1260 						MathStructure minteg(mbak);
1261 						MathStructure np2(mpow);
1262 						np2 += nr_two;
1263 						minteg ^= np2;
1264 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1265 						minteg *= np2;
1266 						minteg /= np1;
1267 						mstruct += minteg;
1268 					}
1269 					return true;
1270 				} else if(mexp.isNumber() && mexp.number().isTwo() && madd.isZero() && mpow.isOne()) {
1271 					mstruct = nr_two;
1272 					mstruct /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1273 					mstruct ^= nr_half;
1274 					mstruct *= x_var;
1275 					mstruct *= mmul;
1276 					mstruct.last() ^= nr_half;
1277 					mstruct.transformById(FUNCTION_ID_FRESNEL_S);
1278 					mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1279 					mstruct.last() *= nr_half;
1280 					mstruct.last() ^= nr_half;
1281 					mstruct *= mmul;
1282 					mstruct.last() ^= Number(-1, 2);
1283 					return true;
1284 				}
1285 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
1286 				MathStructure mfacexp(1, 1, 0);
1287 				if(mfac != x_var) mfacexp = mfac[1];
1288 				if(mfacexp.isMinusOne() && !mexp.isZero()) {
1289 					if(madd.isZero()) {
1290 						if(mpow.isOne()) {
1291 							mstruct[0] /= CALCULATOR->getRadUnit();
1292 							mstruct.setFunctionId(FUNCTION_ID_SININT);
1293 							if(!mexp.isOne()) mstruct /= mexp;
1294 							return true;
1295 						} else if(mpow.number().isTwo()) {
1296 							mstruct[0] *= nr_two;
1297 							mstruct[0] /= CALCULATOR->getRadUnit();
1298 							mstruct.setFunctionId(FUNCTION_ID_COSINT);
1299 							if(!mexp.isOne()) mstruct /= mexp;
1300 							mstruct.negate();
1301 							mstruct += x_var;
1302 							if(!transform_absln(mstruct.last(), use_abs, definite_integral, x_var, eo)) return -1;
1303 							mstruct *= nr_half;
1304 							return true;
1305 						} else if(mpow.number() == 3) {
1306 							mstruct[0] /= CALCULATOR->getRadUnit();
1307 							mstruct.setFunctionId(FUNCTION_ID_SININT);
1308 							MathStructure mterm2(mstruct);
1309 							mstruct[0] *= nr_three;
1310 							mterm2 *= Number(-3, 1);
1311 							mstruct += mterm2;
1312 							if(!mexp.isOne()) mstruct /= mexp;
1313 							mstruct *= Number(-1, 4);
1314 							return true;
1315 						}
1316 					} else if(mpow.isOne()) {
1317 						MathStructure mterm2;
1318 						mstruct = x_var;
1319 						if(!mexp.isOne()) mstruct ^= mexp;
1320 						if(!mmul.isOne()) mstruct *= mmul;
1321 						mstruct.transformById(FUNCTION_ID_SININT);
1322 						if(CALCULATOR->getRadUnit()) madd *= CALCULATOR->getRadUnit();
1323 						mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COS), &madd, NULL);
1324 						mterm2 = x_var;
1325 						if(!mexp.isOne()) mterm2 ^= mexp;
1326 						if(!mmul.isOne()) mterm2 *= mmul;
1327 						mterm2.transformById(FUNCTION_ID_COSINT);
1328 						mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIN), &madd, NULL);
1329 						mstruct += mterm2;
1330 						if(!mexp.isOne()) mstruct /= mexp;
1331 						return true;
1332 					}
1333 				} else if(mexp.isOne() && mpow.isOne()) {
1334 					if(mfacexp.isOne()) {
1335 						MathStructure mterm2(mstruct);
1336 						mterm2.setFunctionId(FUNCTION_ID_COS);
1337 						mterm2 *= x_var;
1338 						if(!mmul.isOne()) {
1339 							mterm2 /= mmul;
1340 							mmul ^= nr_two;
1341 							mstruct /= mmul;
1342 						}
1343 						mstruct -= mterm2;
1344 						return true;
1345 					} else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
1346 						mstruct.setFunctionId(FUNCTION_ID_COS);
1347 						MathStructure mterm2(mstruct);
1348 						mterm2 *= x_var;
1349 						mterm2.last() ^= mfacexp;
1350 						mterm2.childUpdated(mterm2.size());
1351 						if(!mmul.isOne()) mterm2 /= mmul;
1352 						mstruct *= x_var;
1353 						mstruct.last() ^= mfacexp;
1354 						mstruct.childUpdated(mstruct.size());
1355 						mstruct.last().last() += nr_minus_one;
1356 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1357 						mstruct *= mfacexp;
1358 						if(!mmul.isOne()) mstruct /= mmul;
1359 						mstruct -= mterm2;
1360 						return true;
1361 					} else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
1362 						mfacexp += m_one;
1363 						MathStructure mterm2(mstruct);
1364 						mterm2 *= x_var;
1365 						mterm2.last() ^= mfacexp;
1366 						mterm2.childUpdated(mterm2.size());
1367 						mterm2 /= mfacexp;
1368 						mstruct.setFunctionId(FUNCTION_ID_COS);
1369 						mstruct *= x_var;
1370 						mstruct.last() ^= mfacexp;
1371 						mstruct.childUpdated(mstruct.size());
1372 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1373 						mstruct /= mfacexp;
1374 						mstruct.negate();
1375 						if(!mmul.isOne()) mstruct *= mmul;
1376 						mstruct += mterm2;
1377 						return true;
1378 					}
1379 				} else if(mexp.isOne() && mpow.number().isTwo()) {
1380 					if(mfacexp.isOne()) {
1381 						MathStructure mterm2(mstruct);
1382 						MathStructure mterm3(x_var);
1383 						mterm3 ^= nr_two;
1384 						mterm3 *= Number(1, 4);
1385 						mterm2[0] *= nr_two;
1386 						mterm2 *= x_var;
1387 						if(!mmul.isOne()) mterm2 /= mmul;
1388 						mterm2 *= Number(-1, 4);
1389 						mstruct.setFunctionId(FUNCTION_ID_COS);
1390 						mstruct[0] *= nr_two;
1391 						if(!mmul.isOne()) {
1392 							mmul ^= nr_two;
1393 							mstruct /= mmul;
1394 						}
1395 						mstruct *= Number(-1, 8);
1396 						mstruct += mterm2;
1397 						mstruct += mterm3;
1398 						mstruct.childrenUpdated(true);
1399 						return true;
1400 					} else if(mfacexp.number().isTwo()) {
1401 						MathStructure mterm2(mstruct);
1402 						MathStructure mterm3(x_var);
1403 						mterm3 ^= nr_three;
1404 						mterm3 *= Number(1, 6);
1405 						mterm2[0] *= nr_two;
1406 						MathStructure mterm21(1, 8, 0);
1407 						if(!mmul.isOne()) {
1408 							mterm21 *= mmul;
1409 							mterm21.last() ^= Number(-3, 1);
1410 						}
1411 						MathStructure mterm22(x_var);
1412 						mterm22 ^= 2;
1413 						if(!mmul.isOne()) mterm22 /= mmul;
1414 						mterm22 *= Number(-1, 4);
1415 						mterm21 += mterm22;
1416 						mterm2 *= mterm21;
1417 						mstruct.setFunctionId(FUNCTION_ID_COS);
1418 						mstruct[0] *= nr_two;
1419 						mstruct *= x_var;
1420 						if(!mmul.isOne()) {
1421 							mmul ^= nr_two;
1422 							mstruct /= mmul;
1423 						}
1424 						mstruct *= Number(-1, 4);
1425 						mstruct += mterm2;
1426 						mstruct += mterm3;
1427 						mstruct.childrenUpdated(true);
1428 						return true;
1429 					}
1430 				}
1431 			} else if(mexp.isOne() && mfac.isFunction()) {
1432 				if(mfac.function()->id() == FUNCTION_ID_SIN && mfac.size() == 1 && mpow.isOne()) {
1433 					MathStructure mexpf, mmulf, maddf;
1434 					if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf, true) && mexpf.isOne() && mmul != mmulf) {
1435 						MathStructure mterm2(mstruct);
1436 						mterm2[0] += mfac[0];
1437 						mstruct[0] -= mfac[0];
1438 						MathStructure mden1(mmul);
1439 						mden1 -= mmulf;
1440 						mden1 *= nr_two;
1441 						MathStructure mden2(mmul);
1442 						mden2 += mmulf;
1443 						mden2 *= nr_two;
1444 						mterm2 /= mden2;
1445 						mstruct /= mden1;
1446 						mstruct -= mterm2;
1447 						return true;
1448 					}
1449 				} else if(mfac.function()->id() == FUNCTION_ID_COS && mfac.size() == 1) {
1450 					if(mstruct[0] == mfac[0]) {
1451 						UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
1452 						MathStructure mtest(var);
1453 						if(!mpow.isOne()) mtest ^= mpow;
1454 						CALCULATOR->beginTemporaryStopMessages();
1455 						if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
1456 							MathStructure m_interval(mstruct);
1457 							m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
1458 							var->setInterval(m_interval);
1459 						} else {
1460 							var->setInterval(mstruct);
1461 						}
1462 						if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
1463 							CALCULATOR->endTemporaryStopMessages(true);
1464 							mtest.replace(var, mstruct);
1465 							var->destroy();
1466 							mstruct = mtest;
1467 							if(!mmul.isOne()) mstruct /= mmul;
1468 							return true;
1469 						}
1470 						CALCULATOR->endTemporaryStopMessages();
1471 						var->destroy();
1472 					} else if(mpow.isOne()) {
1473 						MathStructure mexpf, mmulf, maddf;
1474 						if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf, true) && mexpf.isOne()) {
1475 							if(mmul != mmulf) {
1476 								mstruct.setFunctionId(FUNCTION_ID_COS);
1477 								MathStructure mterm2(mstruct);
1478 								mterm2[0] += mfac[0];
1479 								mstruct[0] -= mfac[0];
1480 								MathStructure mden1(mmul);
1481 								mden1 -= mmulf;
1482 								mden1 *= nr_two;
1483 								MathStructure mden2(mmul);
1484 								mden2 += mmulf;
1485 								mden2 *= nr_two;
1486 								mterm2 /= mden2;
1487 								mstruct /= mden1;
1488 								mstruct.negate();
1489 								mstruct -= mterm2;
1490 								return true;
1491 							} else if(madd == maddf) {
1492 								mstruct ^= nr_two;
1493 								if(!mmul.isOne()) mstruct /= mmul;
1494 								mstruct *= nr_half;
1495 								return true;
1496 							} else {
1497 								MathStructure mterm2(mfac);
1498 								mterm2[0].add(mstruct[0]);
1499 								mterm2.childUpdated(1);
1500 								if(!mmul.isOne()) mterm2 /= mmul;
1501 								mterm2 *= Number(-1, 4);
1502 								mstruct[0] = maddf;
1503 								mstruct[0] -= madd;
1504 								mstruct[0] *= CALCULATOR->getRadUnit();
1505 								mstruct.childUpdated(1);
1506 								mstruct *= x_var;
1507 								mstruct *= Number(-1, 2);
1508 								mstruct += mterm2;
1509 								return true;
1510 							}
1511 						}
1512 					}
1513 				}
1514 			}
1515 		}
1516 	} else if(mstruct.function()->id() == FUNCTION_ID_COS && mstruct.size() == 1) {
1517 		MathStructure mexp, mmul, madd;
1518 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp, true)) {
1519 			if(mfac.isOne()) {
1520 				if(mexp.isOne()) {
1521 					if(mpow.isOne()) {
1522 						mstruct.setFunctionId(FUNCTION_ID_SIN);
1523 						if(!mmul.isOne()) mstruct.divide(mmul);
1524 					} else if(mpow.number().isTwo()) {
1525 						mstruct.setFunctionId(FUNCTION_ID_SIN);
1526 						if(!madd.isZero()) {
1527 							mstruct[0] = x_var;
1528 							mstruct[0] *= CALCULATOR->getRadUnit();
1529 						}
1530 						mstruct[0] *= nr_two;
1531 						mstruct /= 4;
1532 						if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
1533 						MathStructure xhalf(x_var);
1534 						xhalf *= nr_half;
1535 						mstruct += xhalf;
1536 						if(!madd.isZero()) {
1537 							MathStructure marg(x_var);
1538 							if(!mmul.isOne()) marg *= mmul;
1539 							marg += madd;
1540 							mstruct.replace(x_var, marg);
1541 							if(!mmul.isOne()) mstruct.divide(mmul);
1542 						}
1543 					} else if(mpow.number().isMinusOne()) {
1544 						MathStructure mtan(mstruct);
1545 						mtan.setFunctionId(FUNCTION_ID_TAN);
1546 						mstruct.inverse();
1547 						mstruct += mtan;
1548 						if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1549 						if(!mmul.isOne()) mstruct.divide(mmul);
1550 					} else if(mpow.number() == -2) {
1551 						mstruct.setFunctionId(FUNCTION_ID_TAN);
1552 						if(!mmul.isOne()) mstruct.divide(mmul);
1553 					} else if(mpow.number().isPositive()) {
1554 						MathStructure mbak(mstruct);
1555 						MathStructure nm1(mpow);
1556 						nm1 += nr_minus_one;
1557 						mstruct ^= nm1;
1558 						MathStructure msin(mbak);
1559 						msin.setFunctionId(FUNCTION_ID_SIN);
1560 						mstruct *= msin;
1561 						mmul *= mpow;
1562 						mstruct /= mmul;
1563 						MathStructure minteg(mbak);
1564 						MathStructure nm2(mpow);
1565 						nm2 += Number(-2, 1);
1566 						minteg ^= nm2;
1567 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1568 						minteg *= nm1;
1569 						minteg /= mpow;
1570 						mstruct += minteg;
1571 					} else {
1572 						MathStructure mbak(mstruct);
1573 						MathStructure np1(mpow);
1574 						np1 += m_one;
1575 						mstruct ^= np1;
1576 						MathStructure mcos(mbak);
1577 						mcos.setFunctionId(FUNCTION_ID_SIN);
1578 						mstruct *= mcos;
1579 						mstruct /= np1;
1580 						mstruct /= mmul;
1581 						mstruct.negate();
1582 						MathStructure minteg(mbak);
1583 						MathStructure np2(mpow);
1584 						np2 += nr_two;
1585 						minteg ^= np2;
1586 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1587 						minteg *= np2;
1588 						minteg /= np1;
1589 						mstruct += minteg;
1590 					}
1591 					return true;
1592 				} else if(mexp.isNumber() && mexp.number().isTwo() && madd.isZero() && mpow.isOne()) {
1593 					mstruct = nr_two;
1594 					mstruct /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1595 					mstruct ^= nr_half;
1596 					mstruct *= x_var;
1597 					mstruct *= mmul;
1598 					mstruct.last() ^= nr_half;
1599 					mstruct.transformById(FUNCTION_ID_FRESNEL_C);
1600 					mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1601 					mstruct.last() *= nr_half;
1602 					mstruct.last() ^= nr_half;
1603 					mstruct *= mmul;
1604 					mstruct.last() ^= Number(-1, 2);
1605 					return true;
1606 				}
1607 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
1608 				MathStructure mfacexp(1, 1, 0);
1609 				if(mfac != x_var) mfacexp = mfac[1];
1610 				if(mfacexp.isMinusOne() && !mexp.isZero()) {
1611 					if(madd.isZero()) {
1612 						if(mpow.isOne()) {
1613 							mstruct[0] /= CALCULATOR->getRadUnit();
1614 							mstruct.setFunctionId(FUNCTION_ID_COSINT);
1615 							if(!mexp.isOne()) mstruct /= mexp;
1616 							return true;
1617 						} else if(mpow.number().isTwo()) {
1618 							mstruct[0] *= nr_two;
1619 							mstruct[0] /= CALCULATOR->getRadUnit();
1620 							mstruct.setFunctionId(FUNCTION_ID_COSINT);
1621 							if(!mexp.isOne()) mstruct /= mexp;
1622 							mstruct += x_var;
1623 							mstruct.last().transformById(FUNCTION_ID_LOG);
1624 							mstruct *= nr_half;
1625 							return true;
1626 						} else if(mpow.number() == 3) {
1627 							mstruct[0] /= CALCULATOR->getRadUnit();
1628 							mstruct.setFunctionId(FUNCTION_ID_COSINT);
1629 							MathStructure mterm2(mstruct);
1630 							mstruct[0] *= nr_three;
1631 							mterm2 *= Number(3, 1);
1632 							mstruct += mterm2;
1633 							if(!mexp.isOne()) mstruct /= mexp;
1634 							mstruct *= Number(1, 4);
1635 							return true;
1636 						}
1637 					} else if(mpow.isOne()) {
1638 						MathStructure mterm2;
1639 						mstruct = x_var;
1640 						if(!mexp.isOne()) mstruct ^= mexp;
1641 						if(!mmul.isOne()) mstruct *= mmul;
1642 						mstruct.transformById(FUNCTION_ID_COSINT);
1643 						if(CALCULATOR->getRadUnit()) madd *= CALCULATOR->getRadUnit();
1644 						mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COS), &madd, NULL);
1645 						mterm2 = x_var;
1646 						if(!mexp.isOne()) mterm2 ^= mexp;
1647 						if(!mmul.isOne()) mterm2 *= mmul;
1648 						mterm2.transformById(FUNCTION_ID_SININT);
1649 						mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIN), &madd, NULL);
1650 						mstruct -= mterm2;
1651 						if(!mexp.isOne()) mstruct /= mexp;
1652 						return true;
1653 					}
1654 				} else if(mexp.isOne() && mpow.isOne()) {
1655 					if(mfacexp.isOne()) {
1656 						MathStructure mterm2(mstruct);
1657 						mterm2.setFunctionId(FUNCTION_ID_SIN);
1658 						mterm2 *= x_var;
1659 						if(!mmul.isOne()) {
1660 							mterm2 /= mmul;
1661 							mmul ^= nr_two;
1662 							mstruct /= mmul;
1663 						}
1664 						mstruct += mterm2;
1665 						return true;
1666 					} else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
1667 						mstruct.setFunctionId(FUNCTION_ID_SIN);
1668 						MathStructure mterm2(mstruct);
1669 						mterm2 *= x_var;
1670 						mterm2.last() ^= mfacexp;
1671 						if(!mmul.isOne()) mterm2 /= mmul;
1672 						mstruct *= x_var;
1673 						mstruct.last() ^= mfacexp;
1674 						mstruct.last().last() += nr_minus_one;
1675 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1676 						mstruct *= mfacexp;
1677 						if(!mmul.isOne()) mstruct /= mmul;
1678 						mstruct.negate();
1679 						mstruct += mterm2;
1680 						mstruct.childrenUpdated(true);
1681 						return true;
1682 					} else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
1683 						mfacexp += m_one;
1684 						MathStructure mterm2(mstruct);
1685 						mterm2 *= x_var;
1686 						mterm2.last() ^= mfacexp;
1687 						mterm2.childUpdated(mterm2.size());
1688 						mterm2 /= mfacexp;
1689 						mstruct.setFunctionId(FUNCTION_ID_SIN);
1690 						mstruct *= x_var;
1691 						mstruct.last() ^= mfacexp;
1692 						mstruct.childUpdated(mstruct.size());
1693 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1694 						mstruct /= mfacexp;
1695 						if(!mmul.isOne()) mstruct *= mmul;
1696 						mstruct += mterm2;
1697 						return true;
1698 					}
1699 				} else if(mexp.isOne() && mpow.number().isTwo()) {
1700 					if(mfacexp.isOne()) {
1701 						MathStructure mterm2(mstruct);
1702 						mterm2.setFunctionId(FUNCTION_ID_SIN);
1703 						MathStructure mterm3(x_var);
1704 						mterm3 ^= nr_two;
1705 						mterm3 *= Number(1, 4);
1706 						mterm2[0] *= nr_two;
1707 						mterm2 *= x_var;
1708 						if(!mmul.isOne()) mterm2 /= mmul;
1709 						mterm2 *= Number(1, 4);
1710 						mstruct[0] *= nr_two;
1711 						if(!mmul.isOne()) {
1712 							mmul ^= nr_two;
1713 							mstruct /= mmul;
1714 						}
1715 						mstruct *= Number(1, 8);
1716 						mstruct += mterm2;
1717 						mstruct += mterm3;
1718 						return true;
1719 					} else if(mfacexp.number().isTwo()) {
1720 						MathStructure mterm2(mstruct);
1721 						mterm2.setFunctionId(FUNCTION_ID_SIN);
1722 						MathStructure mterm3(x_var);
1723 						mterm3 ^= nr_three;
1724 						mterm3 *= Number(1, 6);
1725 						mterm2[0] *= nr_two;
1726 						MathStructure mterm21(-1, 8, 0);
1727 						if(!mmul.isOne()) {
1728 							mterm21 *= mmul;
1729 							mterm21.last() ^= Number(-3, 1);
1730 						}
1731 						MathStructure mterm22(x_var);
1732 						mterm22 ^= 2;
1733 						if(!mmul.isOne()) mterm22 /= mmul;
1734 						mterm22 *= Number(1, 4);
1735 						mterm21 += mterm22;
1736 						mterm2 *= mterm21;
1737 						mstruct[0] *= nr_two;
1738 						mstruct *= x_var;
1739 						if(!mmul.isOne()) {
1740 							mmul ^= nr_two;
1741 							mstruct /= mmul;
1742 						}
1743 						mstruct *= Number(1, 4);
1744 						mstruct += mterm2;
1745 						mstruct += mterm3;
1746 						mstruct.childrenUpdated(true);
1747 						return true;
1748 					}
1749 				}
1750 			} else if(mexp.isOne() && mfac.isFunction()) {
1751 				if(mfac.function()->id() == FUNCTION_ID_COS && mfac.size() == 1 && mpow.isOne()) {
1752 					MathStructure mexpf, mmulf, maddf;
1753 					if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf, true) && mexpf.isOne() && mmulf != mmul) {
1754 						mstruct.setFunctionId(FUNCTION_ID_SIN);
1755 						MathStructure mterm2(mstruct);
1756 						mterm2[0] += mfac[0];
1757 						mstruct[0] -= mfac[0];
1758 						MathStructure mden1(mmul);
1759 						mden1 -= mmulf;
1760 						mden1 *= nr_two;
1761 						MathStructure mden2(mmul);
1762 						mden2 += mmulf;
1763 						mden2 *= nr_two;
1764 						mterm2 /= mden2;
1765 						mstruct /= mden1;
1766 						mstruct += mterm2;
1767 						mstruct.childrenUpdated(true);
1768 						return true;
1769 					}
1770 				} else if(mfac.function()->id() == FUNCTION_ID_SIN && mfac.size() == 1) {
1771 					if(mstruct[0] == mfac[0]) {
1772 						UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
1773 						MathStructure mtest(var);
1774 						if(!mpow.isOne()) mtest ^= mpow;
1775 						mtest.negate();
1776 						CALCULATOR->beginTemporaryStopMessages();
1777 						if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
1778 							MathStructure m_interval(mstruct);
1779 							m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
1780 							var->setInterval(m_interval);
1781 						} else {
1782 							var->setInterval(mstruct);
1783 						}
1784 						if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
1785 							CALCULATOR->endTemporaryStopMessages(true);
1786 							mtest.replace(var, mstruct);
1787 							var->destroy();
1788 							mstruct = mtest;
1789 							if(!mmul.isOne()) mstruct /= mmul;
1790 							return true;
1791 						}
1792 						CALCULATOR->endTemporaryStopMessages();
1793 						var->destroy();
1794 					}
1795 				}
1796 			}
1797 		}
1798 	} else if(mstruct.function()->id() == FUNCTION_ID_TAN && mstruct.size() == 1) {
1799 		MathStructure mexp, mmul, madd;
1800 		if(mfac.isOne() && mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-1) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp, true) && mexp.isOne() && (!definite_integral || mstruct[0].representsNonComplex(true))) {
1801 			if(mpow.isOne()) {
1802 				mstruct.setFunctionId(FUNCTION_ID_COS);
1803 				if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1804 				mstruct.negate();
1805 				if(!mmul.isOne()) mstruct.divide(mmul);
1806 			} else if(mpow.number().isMinusOne()) {
1807 				mstruct.setFunctionId(FUNCTION_ID_SIN);
1808 				if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1809 				if(!mmul.isOne()) mstruct.divide(mmul);
1810 			} else if(mpow.number().isTwo()) {
1811 				MathStructure marg(x_var);
1812 				if(!mmul.isOne()) marg *= mmul;
1813 				marg += madd;
1814 				mstruct -= marg;
1815 				if(!mmul.isOne()) mstruct.divide(mmul);
1816 			} else {
1817 				MathStructure minteg(mstruct);
1818 				MathStructure nm1(mpow);
1819 				nm1 += nr_minus_one;
1820 				mstruct ^= nm1;
1821 				mmul *= nm1;
1822 				mstruct /= mmul;
1823 				MathStructure nm2(mpow);
1824 				nm2 += Number(-2, 1);
1825 				minteg ^= nm2;
1826 				if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1827 				mstruct -= minteg;
1828 			}
1829 			return true;
1830 		}
1831 	} else if(mstruct.function()->id() == FUNCTION_ID_ASIN && mstruct.size() == 1) {
1832 		MathStructure mexp, mmul, madd;
1833 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
1834 			if(definite_integral && !madd.isZero() && (!mmul.representsNonComplex(true) || !mexp.representsInteger()) && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero))) return false;
1835 			if(mexp.isOne() && mfac.isOne()) {
1836 				if(mpow.isOne()) {
1837 					MathStructure marg(mstruct[0]);
1838 					if(!madd.isZero()) mstruct[0] = x_var;
1839 					mstruct.multiply(x_var);
1840 					MathStructure mterm(x_var);
1841 					mterm ^= nr_two;
1842 					if(madd.isZero() && !mmul.isOne()) {
1843 						MathStructure mmul2(mmul);
1844 						mmul2 ^= nr_two;
1845 						mterm *= mmul2;
1846 					}
1847 					mterm.negate();
1848 					mterm += m_one;
1849 					mterm ^= nr_half;
1850 					if(madd.isZero() && !mmul.isOne()) mterm /= mmul;
1851 					mstruct.add(mterm);
1852 					if(!madd.isZero()) {
1853 						mstruct.replace(x_var, marg);
1854 						if(!mmul.isOne()) mstruct.divide(mmul);
1855 					}
1856 					return true;
1857 				} else if(mpow.isMinusOne()) {
1858 					mstruct.transformById(FUNCTION_ID_COSINT);
1859 					if(!mmul.isOne()) mstruct /= mmul;
1860 					return true;
1861 				} else if(mpow.number() == -2) {
1862 					MathStructure mterm(mstruct[0]);
1863 					mterm ^= nr_two;
1864 					mterm.negate();
1865 					mterm += m_one;
1866 					mterm ^= nr_half;
1867 					mterm /= mstruct;
1868 					mstruct.transformById(FUNCTION_ID_SININT);
1869 					mstruct += mterm;
1870 					if(!mmul.isOne()) mstruct /= mmul;
1871 					mstruct.negate();
1872 					return true;
1873 				} else if(mpow.number().isPositive() && madd.isZero()) {
1874 					MathStructure mpowm1(mpow);
1875 					if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
1876 					else mpowm1 += nr_minus_one;
1877 					MathStructure mterm(x_var);
1878 					mterm ^= nr_two;
1879 					if(!mmul.isOne()) {
1880 						mterm *= mmul;
1881 						mterm.last() ^= nr_two;
1882 					}
1883 					mterm.negate();
1884 					mterm += m_one;
1885 					mterm ^= nr_half;
1886 					mterm *= mstruct;
1887 					if(!mpowm1.isOne()) mterm.last() ^= mpowm1;
1888 					mterm *= mpow;
1889 					if(!mmul.isOne()) mterm /= mmul;
1890 					MathStructure minteg;
1891 					if(mpowm1.isOne()) {
1892 						minteg = x_var;
1893 					} else {
1894 						minteg = mstruct;
1895 						minteg ^= mpow;
1896 						minteg.last() += Number(-2, 1);
1897 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1898 					}
1899 					minteg *= mpow;
1900 					if(!mpowm1.isOne()) minteg *= mpowm1;
1901 					mstruct ^= mpow;
1902 					mstruct *= x_var;
1903 					mstruct += mterm;
1904 					mstruct -= minteg;
1905 					return true;
1906 				} else if(madd.isZero()) {
1907 					MathStructure mpowp1(mpow);
1908 					mpowp1 += m_one;
1909 					MathStructure mpowp2(mpow);
1910 					mpowp2 += nr_two;
1911 					MathStructure mterm(x_var);
1912 					mterm ^= nr_two;
1913 					if(!mmul.isOne()) {
1914 						mterm *= mmul;
1915 						mterm.last() ^= nr_two;
1916 					}
1917 					mterm.negate();
1918 					mterm += m_one;
1919 					mterm ^= nr_half;
1920 					mterm *= mstruct;
1921 					mterm.last() ^= mpowp1;
1922 					mterm /= mpowp1;
1923 					if(!mmul.isOne()) mterm /= mmul;
1924 					MathStructure minteg(mstruct);
1925 					minteg ^= mpowp2;
1926 					if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1927 					minteg /= mpowp1;
1928 					minteg /= mpowp2;
1929 					mstruct ^= mpowp2;
1930 					mstruct *= x_var;
1931 					mstruct /= mpowp1;
1932 					mstruct /= mpowp2;
1933 					mstruct += mterm;
1934 					mstruct -= minteg;
1935 					return true;
1936 				}
1937 			} else if(mexp.isOne() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0))) {
1938 				MathStructure mfacexp(1, 1, 0);
1939 				if(mfac != x_var) mfacexp = mfac[1];
1940 				if(mpow.isOne()) {
1941 					if(mfacexp.isOne()) {
1942 						MathStructure mterm2(mstruct[0]);
1943 						mterm2 ^= nr_two;
1944 						mterm2.negate();
1945 						mterm2 += m_one;
1946 						mterm2 ^= nr_half;
1947 						MathStructure mfac2(x_var);
1948 						if(!mmul.isOne()) mfac2 *= mmul;
1949 						if(!madd.isZero()) {
1950 							mfac2 += madd;
1951 							mfac2.last() *= Number(-3, 1);
1952 						}
1953 						mterm2 *= mfac2;
1954 						MathStructure mfac1(x_var);
1955 						mfac1 ^= nr_two;
1956 						if(!mmul.isOne()) {
1957 							mfac1 *= mmul;
1958 							mfac1.last() ^= nr_two;
1959 						}
1960 						mfac1 *= nr_two;
1961 						if(!madd.isZero()) {
1962 							mfac1 += madd;
1963 							mfac1.last() ^= nr_two;
1964 							mfac1.last() *= Number(-2, 1);
1965 						}
1966 						mfac1 += nr_minus_one;
1967 						mstruct *= mfac1;
1968 						mstruct += mterm2;
1969 						if(!mmul.isOne()) {
1970 							mstruct *= mmul;
1971 							mstruct.last() ^= Number(-2, 1);
1972 						}
1973 						mstruct *= Number(1, 4);
1974 						return true;
1975 					} else if(mfacexp == nr_two && madd.isZero()) {
1976 						mstruct *= x_var;
1977 						mstruct.last() ^= nr_three;
1978 						mstruct *= Number(1, 3);
1979 						MathStructure mterm(x_var);
1980 						mterm ^= nr_two;
1981 						if(!mmul.isOne()) {
1982 							mterm *= mmul;
1983 							mterm.last() ^= nr_two;
1984 						}
1985 						MathStructure mfac1(mterm);
1986 						mfac1 += nr_two;
1987 						mterm.negate();
1988 						mterm += m_one;
1989 						mterm ^= nr_half;
1990 						mterm *= mfac1;
1991 						if(!mmul.isOne()) {
1992 							mmul ^= Number(-3, 1);
1993 							mterm *= mmul;
1994 						}
1995 						mterm *= Number(1, 9);
1996 						mstruct += mterm;
1997 						return true;
1998 					} else if(!mfacexp.isMinusOne() && madd.isZero()) {
1999 						mfacexp += m_one;
2000 						MathStructure minteg(x_var);
2001 						minteg ^= nr_two;
2002 						if(!mmul.isOne()) {
2003 							minteg *= mmul;
2004 							minteg.last() ^= nr_two;
2005 						}
2006 						minteg.negate();
2007 						minteg += m_one;
2008 						minteg ^= Number(-1, 2);
2009 						minteg *= x_var;
2010 						minteg.last() ^= mfacexp;
2011 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2012 						if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2013 							if(!mmul.isOne()) minteg *= mmul;
2014 							minteg /= mfacexp;
2015 							mstruct *= x_var;
2016 							mstruct.last() ^= mfacexp;
2017 							mstruct /= mfacexp;
2018 							mstruct -= minteg;
2019 							return true;
2020 						}
2021 					}
2022 				}
2023 			}
2024 		}
2025 	} else if(mstruct.function()->id() == FUNCTION_ID_ACOS && mstruct.size() == 1) {
2026 		MathStructure mexp, mmul, madd;
2027 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
2028 			if(definite_integral && !madd.isZero() && (!mmul.representsNonComplex(true) || !mexp.representsInteger()) && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero))) return false;
2029 			if(mexp.isOne() && mfac.isOne()) {
2030 				if(mpow.isOne()) {
2031 					MathStructure marg(mstruct[0]);
2032 					if(!madd.isZero()) mstruct[0] = x_var;
2033 					mstruct.multiply(x_var);
2034 					MathStructure mterm(x_var);
2035 					mterm ^= nr_two;
2036 					if(madd.isZero() && !mmul.isOne()) {
2037 						MathStructure mmul2(mmul);
2038 						mmul2 ^= nr_two;
2039 						mterm *= mmul2;
2040 					}
2041 					mterm.negate();
2042 					mterm += m_one;
2043 					mterm ^= nr_half;
2044 					if(madd.isZero() && !mmul.isOne()) mterm /= mmul;
2045 					mstruct.subtract(mterm);
2046 					if(!madd.isZero()) {
2047 						mstruct.replace(x_var, marg);
2048 						if(!mmul.isOne()) mstruct.divide(mmul);
2049 					}
2050 					return true;
2051 				} else if(mpow.isMinusOne()) {
2052 					mstruct.transformById(FUNCTION_ID_SININT);
2053 					mstruct.negate();
2054 					if(!mmul.isOne()) mstruct /= mmul;
2055 					return true;
2056 				} else if(mpow.number() == -2) {
2057 					MathStructure mterm(mstruct[0]);
2058 					mterm ^= nr_two;
2059 					mterm.negate();
2060 					mterm += m_one;
2061 					mterm ^= nr_half;
2062 					mterm /= mstruct;
2063 					mstruct.transformById(FUNCTION_ID_COSINT);
2064 					mstruct.negate();
2065 					mstruct += mterm;
2066 					if(!mmul.isOne()) mstruct /= mmul;
2067 					return true;
2068 				} else if(mpow.number().isPositive() && madd.isZero()) {
2069 					MathStructure mpowm1(mpow);
2070 					if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
2071 					else mpowm1 += nr_minus_one;
2072 					MathStructure mterm(x_var);
2073 					mterm ^= nr_two;
2074 					if(!mmul.isOne()) {
2075 						mterm *= mmul;
2076 						mterm.last() ^= nr_two;
2077 					}
2078 					mterm.negate();
2079 					mterm += m_one;
2080 					mterm ^= nr_half;
2081 					mterm *= mstruct;
2082 					if(!mpowm1.isOne()) mterm.last() ^= mpowm1;
2083 					mterm *= mpow;
2084 					if(!mmul.isOne()) mterm /= mmul;
2085 					MathStructure minteg;
2086 					if(mpowm1.isOne()) {
2087 						minteg = x_var;
2088 					} else {
2089 						minteg = mstruct;
2090 						minteg ^= mpow;
2091 						minteg.last() += Number(-2, 1);
2092 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2093 					}
2094 					minteg *= mpow;
2095 					if(!mpowm1.isOne()) minteg *= mpowm1;
2096 					mstruct ^= mpow;
2097 					mstruct *= x_var;
2098 					mstruct -= mterm;
2099 					mstruct -= minteg;
2100 					return true;
2101 				} else if(madd.isZero()) {
2102 					MathStructure mpowp1(mpow);
2103 					mpowp1 += m_one;
2104 					MathStructure mpowp2(mpow);
2105 					mpowp2 += nr_two;
2106 					MathStructure mterm(x_var);
2107 					mterm ^= nr_two;
2108 					if(!mmul.isOne()) {
2109 						mterm *= mmul;
2110 						mterm.last() ^= nr_two;
2111 					}
2112 					mterm.negate();
2113 					mterm += m_one;
2114 					mterm ^= nr_half;
2115 					mterm *= mstruct;
2116 					mterm.last() ^= mpowp1;
2117 					mterm /= mpowp1;
2118 					if(!mmul.isOne()) mterm /= mmul;
2119 					MathStructure minteg(mstruct);
2120 					minteg ^= mpowp2;
2121 					if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2122 					minteg /= mpowp1;
2123 					minteg /= mpowp2;
2124 					mstruct ^= mpowp2;
2125 					mstruct *= x_var;
2126 					mstruct /= mpowp1;
2127 					mstruct /= mpowp2;
2128 					mstruct -= mterm;
2129 					mstruct -= minteg;
2130 					return true;
2131 				}
2132 			} else if(mexp.isOne() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0))) {
2133 				MathStructure mfacexp(1, 1, 0);
2134 				if(mfac != x_var) mfacexp = mfac[1];
2135 				if(mpow.isOne()) {
2136 					if(mfacexp.isOne()) {
2137 						MathStructure mterm2(mstruct[0]);
2138 						MathStructure mterm3(mstruct);
2139 						mterm2 ^= nr_two;
2140 						mterm2.negate();
2141 						mterm2 += m_one;
2142 						mterm2 ^= nr_half;
2143 						MathStructure mfac2(x_var);
2144 						if(!mmul.isOne()) {
2145 							mfac2 *= mmul;
2146 						}
2147 						mfac2.negate();
2148 						if(!madd.isZero()) {
2149 							mfac2 += madd;
2150 							mfac2.last() *= nr_three;
2151 						}
2152 						mterm2 *= mfac2;
2153 						mterm3.setFunctionId(FUNCTION_ID_ASIN);
2154 						MathStructure mfac3(1, 1, 0);
2155 						if(!madd.isZero()) {
2156 							mfac3 += madd;
2157 							mfac3.last() ^= nr_two;
2158 							mfac3.last() *= nr_two;
2159 						}
2160 						mterm3 *= mfac3;
2161 						mstruct *= x_var;
2162 						mstruct.last() ^= nr_two;
2163 						if(!mmul.isOne()) {
2164 							mstruct *= mmul;
2165 							mstruct.last() ^= nr_two;
2166 						}
2167 						mstruct *= nr_two;
2168 						mstruct += mterm2;
2169 						mstruct += mterm3;
2170 						if(!mmul.isOne()) {
2171 							mstruct *= mmul;
2172 							mstruct.last() ^= Number(-2, 1);
2173 						}
2174 						mstruct *= Number(1, 4);
2175 						return true;
2176 					} else if(mfacexp == nr_two && madd.isZero()) {
2177 						mstruct *= x_var;
2178 						mstruct.last() ^= nr_three;
2179 						mstruct *= Number(1, 3);
2180 						MathStructure mterm(x_var);
2181 						mterm ^= nr_two;
2182 						if(!mmul.isOne()) {
2183 							mterm *= mmul;
2184 							mterm.last() ^= nr_two;
2185 						}
2186 						MathStructure mfac1(mterm);
2187 						mfac1 += nr_two;
2188 						mterm.negate();
2189 						mterm += m_one;
2190 						mterm ^= nr_half;
2191 						mterm *= mfac1;
2192 						if(!mmul.isOne()) {
2193 							mmul ^= Number(-3, 1);
2194 							mterm *= mmul;
2195 						}
2196 						mterm *= Number(-1, 9);
2197 						mstruct += mterm;
2198 						return true;
2199 					} else if(!mfacexp.isMinusOne() && madd.isZero()) {
2200 						mfacexp += m_one;
2201 						MathStructure minteg(x_var);
2202 						minteg ^= nr_two;
2203 						if(!mmul.isOne()) {
2204 							minteg *= mmul;
2205 							minteg.last() ^= nr_two;
2206 						}
2207 						minteg.negate();
2208 						minteg += m_one;
2209 						minteg ^= Number(-1, 2);
2210 						minteg *= x_var;
2211 						minteg.last() ^= mfacexp;
2212 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2213 						if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2214 							if(!mmul.isOne()) minteg *= mmul;
2215 							minteg /= mfacexp;
2216 							mstruct *= x_var;
2217 							mstruct.last() ^= mfacexp;
2218 							mstruct /= mfacexp;
2219 							mstruct += minteg;
2220 							return true;
2221 						}
2222 					}
2223 				}
2224 			}
2225 		}
2226 	} else if(mstruct.function()->id() == FUNCTION_ID_ATAN && mstruct.size() == 1) {
2227 		MathStructure mexp, mmul, madd;
2228 		if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && (!definite_integral || x_var.representsNonZero(true) || madd.representsReal(true))) {
2229 			if(!mexp.isOne()) {
2230 				if(mexp.isMinusOne() && mfac.isOne() && madd.isZero()) {
2231 					mstruct *= x_var;
2232 					MathStructure mterm(x_var);
2233 					mterm ^= nr_two;
2234 					mterm += mmul;
2235 					if(!mmul.isOne()) mterm.last() ^= nr_two;
2236 					mterm.transformById(FUNCTION_ID_LOG);
2237 					if(!mmul.isOne()) mterm *= mmul;
2238 					mterm *= nr_half;
2239 					mstruct += mterm;
2240 					return true;
2241 				}
2242 			} else if(mfac.isOne()) {
2243 				MathStructure marg(mstruct[0]);
2244 				mstruct.multiply(marg);
2245 				MathStructure mterm(marg);
2246 				mterm ^= nr_two;
2247 				mterm += m_one;
2248 				if(!transform_absln(mterm, use_abs, definite_integral, x_var, eo)) return -1;
2249 				mterm *= Number(-1, 2);
2250 				mstruct += mterm;
2251 				if(!mmul.isOne()) mstruct.divide(mmul);
2252 				return true;
2253 			} else if(madd.isZero() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0))) {
2254 				MathStructure mfacexp(1, 1, 0);
2255 				if(mfac != x_var) mfacexp = mfac[1];
2256 				if(mfacexp.isMinusOne()) {
2257 					mstruct.setFunctionId(FUNCTION_ID_POLYLOG);
2258 					mstruct.insertChild(nr_two, 1);
2259 					MathStructure mterm(mstruct);
2260 					mstruct[1] *= nr_minus_i;
2261 					mterm[1] *= nr_one_i;
2262 					mterm.negate();
2263 					mstruct += mterm;
2264 					mstruct *= nr_one_i;
2265 					mstruct *= nr_half;
2266 					return true;
2267 				} else if(mfacexp.isOne()) {
2268 					MathStructure mterm1(x_var);
2269 					mterm1 ^= nr_two;
2270 					mterm1 *= mstruct;
2271 					mterm1 *= nr_half;
2272 					MathStructure mterm2(x_var);
2273 					if(!mmul.isOne()) mterm2 /= mmul;
2274 					mterm2 *= nr_minus_half;
2275 					if(!mmul.isOne()) {mstruct *= mmul; mstruct.last() ^= Number(-2, 1);}
2276 					mstruct *= nr_half;
2277 					mstruct += mterm1;
2278 					mstruct += mterm2;
2279 					return true;
2280 				} else {
2281 					mfacexp += m_one;
2282 					MathStructure mxexp(x_var);
2283 					mxexp ^= mfacexp;
2284 					MathStructure minteg(x_var);
2285 					minteg ^= nr_two;
2286 					if(!mmul.isOne()) {minteg *= mmul; minteg.last() ^= nr_two;}
2287 					minteg += m_one;
2288 					if(!definite_integral || COMPARISON_IS_NOT_EQUAL(minteg.compare(m_zero))) {
2289 						minteg ^= nr_minus_one;
2290 						minteg *= mxexp;
2291 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2292 						minteg /= mfacexp;
2293 						if(!mmul.isOne()) minteg *= mmul;
2294 						mstruct *= mxexp;
2295 						mstruct /= mfacexp;
2296 						mstruct -= minteg;
2297 						return true;
2298 					}
2299 				}
2300 			}
2301 		}
2302 	} else if(mstruct.function()->id() == FUNCTION_ID_SINH && mstruct.size() == 1) {
2303 		if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_LOG && mstruct[0].size() == 1 && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
2304 			MathStructure mtest(mstruct[0][0]);
2305 			mtest *= Number(-2, 1);
2306 			mtest.inverse();
2307 			mtest.add(mstruct[0][0]);
2308 			mtest.last() *= nr_half;
2309 			if(!mpow.isOne()) mtest ^= mpow;
2310 			if(!mfac.isOne()) mtest *= mfac;
2311 			CALCULATOR->beginTemporaryStopMessages();
2312 			if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2313 				CALCULATOR->endTemporaryStopMessages(true);
2314 				mstruct.set(mtest, true);
2315 				return true;
2316 			}
2317 			CALCULATOR->endTemporaryStopMessages();
2318 		}
2319 		MathStructure mexp, mmul, madd;
2320 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
2321 			if(mfac.isOne() && mexp.isOne()) {
2322 				if(mpow.isOne()) {
2323 					mstruct.setFunctionId(FUNCTION_ID_COSH);
2324 					if(!mmul.isOne()) mstruct.divide(mmul);
2325 				} else if(mpow.number().isTwo()) {
2326 					MathStructure marg(mstruct[0]);
2327 					if(!madd.isZero()) mstruct[0] = x_var;
2328 					mstruct[0] *= nr_two;
2329 					mstruct /= 4;
2330 					if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
2331 					MathStructure xhalf(x_var);
2332 					xhalf *= nr_half;
2333 					mstruct -= xhalf;
2334 					if(!madd.isZero()) {
2335 						mstruct.replace(x_var, marg);
2336 						if(!mmul.isOne()) mstruct.divide(mmul);
2337 					}
2338 				} else if(mpow.number().isMinusOne()) {
2339 					mstruct.setFunctionId(FUNCTION_ID_TANH);
2340 					mstruct[0] *= nr_half;
2341 					if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
2342 					if(!mmul.isOne()) mstruct.divide(mmul);
2343 				} else if(mpow.number().isPositive()) {
2344 					MathStructure mbak(mstruct);
2345 					MathStructure nm1(mpow);
2346 					nm1 += nr_minus_one;
2347 					mstruct ^= nm1;
2348 					MathStructure mcos(mbak);
2349 					mcos.setFunctionId(FUNCTION_ID_COSH);
2350 					mstruct *= mcos;
2351 					mmul *= mpow;
2352 					mstruct /= mmul;
2353 					MathStructure minteg(mbak);
2354 					MathStructure nm2(mpow);
2355 					nm2 += Number(-2, 1);
2356 					minteg ^= nm2;
2357 					if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2358 					minteg *= nm1;
2359 					minteg /= mpow;
2360 					mstruct -= minteg;
2361 				} else {
2362 					MathStructure mbak(mstruct);
2363 					MathStructure np1(mpow);
2364 					np1 += m_one;
2365 					MathStructure np2(mpow);
2366 					np2 += nr_two;
2367 					mstruct ^= np1;
2368 					MathStructure mcos(mbak);
2369 					mcos.setFunctionId(FUNCTION_ID_COSH);
2370 					mstruct *= mcos;
2371 					mstruct /= np1;
2372 					if(!mmul.isOne()) mstruct /= mmul;
2373 					MathStructure minteg(mbak);
2374 					minteg ^= np2;
2375 					if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2376 					minteg *= np2;
2377 					minteg /= np1;
2378 					mstruct -= minteg;
2379 				}
2380 				return true;
2381 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
2382 				MathStructure mfacexp(1, 1, 0);
2383 				if(mfac != x_var) mfacexp = mfac[1];
2384 				if(mfacexp.isMinusOne() && !mexp.isZero()) {
2385 					if(madd.isZero()) {
2386 						if(mpow.isOne()) {
2387 							mstruct.setFunctionId(FUNCTION_ID_SINHINT);
2388 							if(!mexp.isOne()) mstruct /= mexp;
2389 							return true;
2390 						} else if(mpow.number().isTwo()) {
2391 							mstruct[0] *= nr_two;
2392 							mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2393 							if(!mexp.isOne()) mstruct /= mexp;
2394 							mstruct += x_var;
2395 							mstruct.last().transformById(FUNCTION_ID_LOG);
2396 							mstruct.last().negate();
2397 							mstruct *= nr_half;
2398 							return true;
2399 						} else if(mpow.number() == 3) {
2400 							mstruct.setFunctionId(FUNCTION_ID_SINHINT);
2401 							MathStructure mterm2(mstruct);
2402 							mstruct[0] *= nr_three;
2403 							mterm2 *= Number(-3, 1);
2404 							mstruct += mterm2;
2405 							if(!mexp.isOne()) mstruct /= mexp;
2406 							mstruct *= Number(1, 4);
2407 							return true;
2408 						}
2409 					} else if(mpow.isOne()) {
2410 						MathStructure mterm2;
2411 						mstruct = x_var;
2412 						if(!mexp.isOne()) mstruct ^= mexp;
2413 						if(!mmul.isOne()) mstruct *= mmul;
2414 						mstruct.transformById(FUNCTION_ID_SINHINT);
2415 						mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COSH), &madd, NULL);
2416 						mterm2 = x_var;
2417 						if(!mexp.isOne()) mterm2 ^= mexp;
2418 						if(!mmul.isOne()) mterm2 *= mmul;
2419 						mterm2.transformById(FUNCTION_ID_COSHINT);
2420 						mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SINH), &madd, NULL);
2421 						mstruct += mterm2;
2422 						if(!mexp.isOne()) mstruct /= mexp;
2423 						return true;
2424 					}
2425 				} else if(mexp.isOne() && mpow.isOne()) {
2426 					if(mfacexp.isOne()) {
2427 						MathStructure mterm2(mstruct);
2428 						mterm2.setFunctionId(FUNCTION_ID_COSH);
2429 						mterm2 *= x_var;
2430 						if(!mmul.isOne()) {
2431 							mterm2 /= mmul;
2432 							mmul ^= nr_two;
2433 							mstruct /= mmul;
2434 						}
2435 						mstruct.negate();
2436 						mstruct += mterm2;
2437 						return true;
2438 					} else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
2439 						mstruct.setFunctionId(FUNCTION_ID_COSH);
2440 						MathStructure mterm2(mstruct);
2441 						mterm2 *= x_var;
2442 						mterm2.last() ^= mfacexp;
2443 						if(!mmul.isOne()) mterm2 /= mmul;
2444 						mstruct *= x_var;
2445 						mstruct.last() ^= mfacexp;
2446 						mstruct.last().last() += nr_minus_one;
2447 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2448 						mstruct *= mfacexp;
2449 						if(!mmul.isOne()) mstruct /= mmul;
2450 						mstruct.negate();
2451 						mstruct += mterm2;
2452 						mstruct.childrenUpdated(true);
2453 						return true;
2454 					} else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
2455 						mfacexp += m_one;
2456 						MathStructure mterm2(mstruct);
2457 						mterm2 *= x_var;
2458 						mterm2.last() ^= mfacexp;
2459 						mterm2.childUpdated(mterm2.size());
2460 						mterm2 /= mfacexp;
2461 						mstruct.setFunctionId(FUNCTION_ID_COSH);
2462 						mstruct *= x_var;
2463 						mstruct.last() ^= mfacexp;
2464 						mstruct.childUpdated(mstruct.size());
2465 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2466 						mstruct /= mfacexp;
2467 						mstruct.negate();
2468 						if(!mmul.isOne()) mstruct *= mmul;
2469 						mstruct += mterm2;
2470 						return true;
2471 					}
2472 				}
2473 			} else if(mfac.isFunction() && mexp.isOne()) {
2474 				if(mfac.function()->id() == FUNCTION_ID_SINH && mfac.size() == 1 && mpow.isOne()) {
2475 					MathStructure mexpf, mmulf, maddf;
2476 					if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf) && mexpf.isOne() && mmul != mmulf) {
2477 						MathStructure mterm2(mstruct);
2478 						mterm2[0] += mfac[0];
2479 						mstruct[0] -= mfac[0];
2480 						MathStructure mden1(mmul);
2481 						mden1 -= mmulf;
2482 						mden1 *= nr_two;
2483 						MathStructure mden2(mmul);
2484 						mden2 += mmulf;
2485 						mden2 *= nr_two;
2486 						mterm2 /= mden2;
2487 						mstruct /= mden1;
2488 						mstruct.negate();
2489 						mstruct += mterm2;
2490 						return true;
2491 					}
2492 				} else if(mfac.function()->id() == FUNCTION_ID_COSH && mfac.size() == 1) {
2493 					if(mstruct[0] == mfac[0]) {
2494 						UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
2495 						MathStructure mtest(var);
2496 						if(!mpow.isOne()) mtest ^= mpow;
2497 						CALCULATOR->beginTemporaryStopMessages();
2498 						if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
2499 							MathStructure m_interval(mstruct);
2500 							m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
2501 							var->setInterval(m_interval);
2502 						} else {
2503 							var->setInterval(mstruct);
2504 						}
2505 						if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2506 							CALCULATOR->endTemporaryStopMessages(true);
2507 							mtest.replace(var, mstruct);
2508 							var->destroy();
2509 							mstruct = mtest;
2510 							if(!mmul.isOne()) mstruct /= mmul;
2511 							return true;
2512 						}
2513 						CALCULATOR->endTemporaryStopMessages();
2514 						var->destroy();
2515 					}
2516 				}
2517 			}
2518 		}
2519 	} else if(mstruct.function()->id() == FUNCTION_ID_COSH && mstruct.size() == 1) {
2520 		if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_LOG && mstruct[0].size() == 1 && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
2521 			MathStructure mtest(mstruct[0][0]);
2522 			mtest *= nr_two;
2523 			mtest.inverse();
2524 			mtest.add(mstruct[0][0]);
2525 			mtest.last() *= nr_half;
2526 			if(!mpow.isOne()) mtest ^= mpow;
2527 			if(!mfac.isOne()) mtest *= mfac;
2528 			CALCULATOR->beginTemporaryStopMessages();
2529 			if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2530 				CALCULATOR->endTemporaryStopMessages(true);
2531 				mstruct.set(mtest, true);
2532 				return true;
2533 			}
2534 			CALCULATOR->endTemporaryStopMessages();
2535 		}
2536 		MathStructure mexp, mmul, madd;
2537 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
2538 			if(mfac.isOne() && mexp.isOne()) {
2539 				if(mpow.isOne()) {
2540 					mstruct.setFunctionId(FUNCTION_ID_SINH);
2541 					if(!mmul.isOne()) mstruct.divide(mmul);
2542 					return true;
2543 				} else if(mpow.number().isTwo()) {
2544 					MathStructure marg(mstruct[0]);
2545 					if(!madd.isZero()) mstruct[0] = x_var;
2546 					mstruct.setFunctionId(FUNCTION_ID_SINH);
2547 					mstruct[0] *= nr_two;
2548 					mstruct /= 4;
2549 					if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
2550 					MathStructure xhalf(x_var);
2551 					xhalf *= nr_half;
2552 					mstruct += xhalf;
2553 					if(!madd.isZero()) {
2554 						mstruct.replace(x_var, marg);
2555 						if(!mmul.isOne()) mstruct.divide(mmul);
2556 					}
2557 					return true;
2558 				} else if(mpow.number().isMinusOne()) {
2559 					mstruct.setFunctionId(FUNCTION_ID_SINH);
2560 					mstruct.transformById(FUNCTION_ID_ATAN);
2561 					if(!mmul.isOne()) mstruct.divide(mmul);
2562 					return true;
2563 				} else if(mpow.number().isPositive()) {
2564 					MathStructure mbak(mstruct);
2565 					MathStructure nm1(mpow);
2566 					nm1 += nr_minus_one;
2567 					mstruct ^= nm1;
2568 					MathStructure msin(mbak);
2569 					msin.setFunctionId(FUNCTION_ID_SINH);
2570 					mstruct *= msin;
2571 					mmul *= mpow;
2572 					mstruct /= mmul;
2573 					MathStructure minteg(mbak);
2574 					MathStructure nm2(mpow);
2575 					nm2 += Number(-2, 1);
2576 					minteg ^= nm2;
2577 					if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2578 					minteg *= nm1;
2579 					minteg /= mpow;
2580 					mstruct += minteg;
2581 					return true;
2582 				} else {
2583 					MathStructure mbak(mstruct);
2584 					MathStructure np1(mpow);
2585 					np1 += m_one;
2586 					MathStructure np2(mpow);
2587 					np2 += nr_two;
2588 					mstruct ^= np1;
2589 					MathStructure mcos(mbak);
2590 					mcos.setFunctionId(FUNCTION_ID_SINH);
2591 					mstruct *= mcos;
2592 					mstruct /= np1;
2593 					if(!mmul.isOne()) mstruct /= mmul;
2594 					mstruct.negate();
2595 					MathStructure minteg(mbak);
2596 					minteg ^= np2;
2597 					if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2598 					minteg *= np2;
2599 					minteg /= np1;
2600 					mstruct += minteg;
2601 					return true;
2602 				}
2603 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
2604 				MathStructure mfacexp(1, 1, 0);
2605 				if(mfac != x_var) mfacexp = mfac[1];
2606 				if(mfacexp.isMinusOne() && !mexp.isZero()) {
2607 					if(madd.isZero()) {
2608 						if(mpow.isOne()) {
2609 							mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2610 							if(!mexp.isOne()) mstruct /= mexp;
2611 							return true;
2612 						} else if(mpow.number().isTwo()) {
2613 							mstruct[0] *= nr_two;
2614 							mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2615 							if(!mexp.isOne()) mstruct /= mexp;
2616 							mstruct += x_var;
2617 							mstruct.last().transformById(FUNCTION_ID_LOG);
2618 							mstruct *= nr_half;
2619 							return true;
2620 						} else if(mpow.number() == 3) {
2621 							mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2622 							MathStructure mterm2(mstruct);
2623 							mstruct[0] *= nr_three;
2624 							mterm2 *= nr_three;
2625 							mstruct += mterm2;
2626 							if(!mexp.isOne()) mstruct /= mexp;
2627 							mstruct *= Number(1, 4);
2628 							return true;
2629 						}
2630 					} else if(mpow.isOne()) {
2631 						MathStructure mterm2;
2632 						mstruct = x_var;
2633 						if(!mexp.isOne()) mstruct ^= mexp;
2634 						if(!mmul.isOne()) mstruct *= mmul;
2635 						mstruct.transformById(FUNCTION_ID_SINHINT);
2636 						mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SINH), &madd, NULL);
2637 						mterm2 = x_var;
2638 						if(!mexp.isOne()) mterm2 ^= mexp;
2639 						if(!mmul.isOne()) mterm2 *= mmul;
2640 						mterm2.transformById(FUNCTION_ID_COSHINT);
2641 						mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COSH), &madd, NULL);
2642 						mstruct += mterm2;
2643 						if(!mexp.isOne()) mstruct /= mexp;
2644 						return true;
2645 					}
2646 				} else if(mexp.isOne() && mpow.isOne()) {
2647 					if(mfacexp.isOne()) {
2648 						MathStructure mterm2(mstruct);
2649 						mterm2.setFunctionId(FUNCTION_ID_SINH);
2650 						mterm2 *= x_var;
2651 						if(!mmul.isOne()) {
2652 							mterm2 /= mmul;
2653 							mmul ^= nr_two;
2654 							mstruct /= mmul;
2655 						}
2656 						mstruct.negate();
2657 						mstruct += mterm2;
2658 						return true;
2659 					} else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
2660 						mstruct.setFunctionId(FUNCTION_ID_SINH);
2661 						MathStructure mterm2(mstruct);
2662 						mterm2 *= x_var;
2663 						mterm2.last() ^= mfacexp;
2664 						if(!mmul.isOne()) mterm2 /= mmul;
2665 						mstruct *= x_var;
2666 						mstruct.last() ^= mfacexp;
2667 						mstruct.last().last() += nr_minus_one;
2668 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2669 						mstruct *= mfacexp;
2670 						if(!mmul.isOne()) mstruct /= mmul;
2671 						mstruct.negate();
2672 						mstruct += mterm2;
2673 						mstruct.childrenUpdated(true);
2674 						return true;
2675 					} else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
2676 						mfacexp += m_one;
2677 						MathStructure mterm2(mstruct);
2678 						mterm2 *= x_var;
2679 						mterm2.last() ^= mfacexp;
2680 						mterm2.childUpdated(mterm2.size());
2681 						mterm2 /= mfacexp;
2682 						mstruct.setFunctionId(FUNCTION_ID_SINH);
2683 						mstruct *= x_var;
2684 						mstruct.last() ^= mfacexp;
2685 						mstruct.childUpdated(mstruct.size());
2686 						if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2687 						mstruct /= mfacexp;
2688 						mstruct.negate();
2689 						if(!mmul.isOne()) mstruct *= mmul;
2690 						mstruct += mterm2;
2691 						return true;
2692 					}
2693 				}
2694 			} else if(mfac.isFunction() && mexp.isOne()) {
2695 				if(mfac.function()->id() == FUNCTION_ID_COSH && mfac.size() == 1 && mpow.isOne()) {
2696 					MathStructure mexpf, mmulf, maddf;
2697 					if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf) && mexpf.isOne() && mmulf != mmul) {
2698 						mstruct.setFunctionId(FUNCTION_ID_SINH);
2699 						MathStructure mterm2(mstruct);
2700 						mterm2[0] += mfac[0];
2701 						mstruct[0] -= mfac[0];
2702 						MathStructure mden1(mmul);
2703 						mden1 -= mmulf;
2704 						mden1 *= nr_two;
2705 						MathStructure mden2(mmul);
2706 						mden2 += mmulf;
2707 						mden2 *= nr_two;
2708 						mterm2 /= mden2;
2709 						mstruct /= mden1;
2710 						mstruct += mterm2;
2711 						mstruct.childrenUpdated(true);
2712 						return true;
2713 					}
2714 				} else if(mfac.function()->id() == FUNCTION_ID_SINH && mfac.size() == 1) {
2715 					if(mstruct[0] == mfac[0]) {
2716 						UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
2717 						MathStructure mtest(var);
2718 						if(!mpow.isOne()) mtest ^= mpow;
2719 						CALCULATOR->beginTemporaryStopMessages();
2720 						if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
2721 							MathStructure m_interval(mstruct);
2722 							m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
2723 							var->setInterval(m_interval);
2724 						} else {
2725 							var->setInterval(mstruct);
2726 						}
2727 						if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2728 							CALCULATOR->endTemporaryStopMessages(true);
2729 							mtest.replace(var, mstruct);
2730 							var->destroy();
2731 							mstruct = mtest;
2732 							if(!mmul.isOne()) mstruct /= mmul;
2733 							return true;
2734 						}
2735 						CALCULATOR->endTemporaryStopMessages();
2736 						var->destroy();
2737 					}
2738 				}
2739 			}
2740 		}
2741 	} else if(mstruct.function()->id() == FUNCTION_ID_TANH && mstruct.size() == 1) {
2742 		if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_LOG && mstruct[0].size() == 1 && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
2743 			MathStructure mtest(mstruct[0][0]);
2744 			mtest ^= nr_two;
2745 			mtest += m_one;
2746 			mtest.inverse();
2747 			mtest *= Number(-2, 1);
2748 			mtest += m_one;
2749 			if(!mpow.isOne()) mtest ^= mpow;
2750 			if(!mfac.isOne()) mtest *= mfac;
2751 			CALCULATOR->beginTemporaryStopMessages();
2752 			if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2753 				CALCULATOR->endTemporaryStopMessages(true);
2754 				mstruct.set(mtest, true);
2755 				return true;
2756 			}
2757 			CALCULATOR->endTemporaryStopMessages();
2758 		}
2759 		MathStructure mexp, mmul, madd;
2760 		if(mfac.isOne() && mpow.isInteger() && mpow.number().isLessThanOrEqualTo(10) && mpow.number().isGreaterThanOrEqualTo(-1) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne() && (!definite_integral || madd.representsNonComplex(true) || x_var.representsNonZero())) {
2761 			if(mpow.isOne()) {
2762 				mstruct.setFunctionId(FUNCTION_ID_COSH);
2763 				mstruct.transformById(FUNCTION_ID_LOG);
2764 				if(!mmul.isOne()) mstruct.divide(mmul);
2765 			} else if(mpow.number().isTwo()) {
2766 				MathStructure marg(mstruct[0]);
2767 				if(!madd.isZero()) mstruct[0] = x_var;
2768 				if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
2769 				mstruct.negate();
2770 				mstruct += x_var;
2771 				if(!madd.isZero()) {
2772 					mstruct.replace(x_var, marg);
2773 					if(!mmul.isOne()) mstruct.divide(mmul);
2774 				}
2775 			} else if(mpow.number().isMinusOne()) {
2776 				mstruct.setFunctionId(FUNCTION_ID_SINH);
2777 				if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
2778 				if(!mmul.isOne()) mstruct.divide(mmul);
2779 			} else {
2780 				MathStructure minteg(mstruct);
2781 				MathStructure nm1(mpow);
2782 				nm1 += nr_minus_one;
2783 				mstruct ^= nm1;
2784 				mmul *= nm1;
2785 				mstruct /= mmul;
2786 				mstruct.negate();
2787 				MathStructure nm2(mpow);
2788 				nm2 += Number(-2, 1);
2789 				minteg ^= nm2;
2790 				if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2791 				mstruct += minteg;
2792 			}
2793 			return true;
2794 		}
2795 	} else if(mstruct.function()->id() == FUNCTION_ID_ASINH && mstruct.size() == 1) {
2796 		MathStructure mexp, mmul, madd;
2797 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
2798 			if(definite_integral && !madd.representsNonComplex(true) && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero))) return false;
2799 			if(mfac.isOne()) {
2800 				if(mpow.isOne()) {
2801 					MathStructure marg(mstruct[0]);
2802 					if(!madd.isZero()) mstruct[0] = x_var;
2803 					mstruct.multiply(x_var);
2804 					MathStructure mterm(x_var);
2805 					mterm ^= nr_two;
2806 					if(madd.isZero() && !mmul.isOne()) {
2807 						MathStructure mmul2(mmul);
2808 						mmul2 ^= nr_two;
2809 						mterm *= mmul2;
2810 					}
2811 					mterm += m_one;
2812 					mterm ^= nr_half;
2813 					if(madd.isZero() && !mmul.isOne()) mterm /= mmul;
2814 					mstruct.subtract(mterm);
2815 					if(!madd.isZero()) {
2816 						mstruct.replace(x_var, marg);
2817 						if(!mmul.isOne()) mstruct.divide(mmul);
2818 					}
2819 					return true;
2820 				} else if(mpow.isMinusOne()) {
2821 					mstruct.transformById(FUNCTION_ID_COSHINT);
2822 					if(!mmul.isOne()) mstruct /= mmul;
2823 					return true;
2824 				} else if(mpow.number() == -2) {
2825 					MathStructure mterm(mstruct[0]);
2826 					mterm ^= nr_two;
2827 					mterm += m_one;
2828 					mterm ^= nr_half;
2829 					mterm /= mstruct;
2830 					mstruct.transformById(FUNCTION_ID_SINHINT);
2831 					mstruct -= mterm;
2832 					if(!mmul.isOne()) mstruct /= mmul;
2833 					return true;
2834 				} else if(madd.isZero()) {
2835 					if(mpow.number().isPositive()) {
2836 						MathStructure mpowm1(mpow);
2837 						if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
2838 						else mpowm1 += nr_minus_one;
2839 						MathStructure mterm(mstruct);
2840 						if(!mpowm1.isOne()) mterm ^= mpowm1;
2841 						MathStructure mfac1(x_var);
2842 						mfac1 ^= nr_two;
2843 						if(!mmul.isOne()) {
2844 							mfac1 *= mmul;
2845 							mfac1.last() ^= nr_two;
2846 						}
2847 						mfac1 += m_one;
2848 						mfac1 ^= nr_half;
2849 						mterm *= mfac1;
2850 						mterm *= mpow;
2851 						if(!mmul.isOne()) mterm /= mmul;
2852 						MathStructure minteg;
2853 						if(mpowm1.isOne()) {
2854 							minteg = x_var;
2855 						} else {
2856 							minteg = mstruct;
2857 							minteg ^= mpow;
2858 							minteg.last() += Number(-2, 1);
2859 							if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2860 						}
2861 						minteg *= mpow;
2862 						if(!mpowm1.isOne()) minteg *= mpowm1;
2863 						mstruct ^= mpow;
2864 						mstruct *= x_var;
2865 						mstruct -= mterm;
2866 						mstruct += minteg;
2867 						return true;
2868 					} else {
2869 						MathStructure mpowp1(mpow);
2870 						mpowp1 += m_one;
2871 						MathStructure mpowp2(mpow);
2872 						mpowp2 += nr_two;
2873 						MathStructure mterm(mstruct);
2874 						mterm ^= mpowp1;
2875 						MathStructure mfac1(x_var);
2876 						mfac1 ^= nr_two;
2877 						if(!mmul.isOne()) {
2878 							mfac1 *= mmul;
2879 							mfac1.last() ^= nr_two;
2880 						}
2881 						mfac1 += m_one;
2882 						mfac1 ^= nr_half;
2883 						mterm *= mfac1;
2884 						if(!mmul.isOne()) mterm /= mmul;
2885 						mterm /= mpowp1;
2886 						MathStructure minteg(mstruct);
2887 						minteg ^= mpowp2;
2888 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2889 						minteg /= mpowp1;
2890 						minteg /= mpowp2;
2891 						mstruct ^= mpowp2;
2892 						mstruct *= x_var;
2893 						mstruct /= mpowp1;
2894 						mstruct /= mpowp2;
2895 						mstruct.negate();
2896 						mstruct += mterm;
2897 						mstruct += minteg;
2898 						return true;
2899 					}
2900 				}
2901 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
2902 				MathStructure mfacexp(1, 1, 0);
2903 				if(mfac != x_var) mfacexp = mfac[1];
2904 				if(mpow.isOne()) {
2905 					if(mfacexp.isOne()) {
2906 						MathStructure mterm2(mstruct[0]);
2907 						mterm2 ^= nr_two;
2908 						mterm2 += m_one;
2909 						mterm2 ^= nr_half;
2910 						MathStructure mfac2(x_var);
2911 						if(!mmul.isOne()) mfac2 *= mmul;
2912 						mfac2.negate();
2913 						if(!madd.isZero()) {
2914 							mfac2 += madd;
2915 							mfac2.last() *= nr_three;
2916 						}
2917 						mterm2 *= mfac2;
2918 						MathStructure mfac1(x_var);
2919 						mfac1 ^= nr_two;
2920 						if(!mmul.isOne()) {
2921 							mfac1 *= mmul;
2922 							mfac1.last() ^= nr_two;
2923 						}
2924 						mfac1 *= nr_two;
2925 						if(!madd.isZero()) {
2926 							mfac1 += madd;
2927 							mfac1.last() ^= nr_two;
2928 							mfac1.last() *= Number(-2, 1);
2929 						}
2930 						mfac1 += m_one;
2931 						mstruct *= mfac1;
2932 						mstruct += mterm2;
2933 						if(!mmul.isOne()) {
2934 							mstruct *= mmul;
2935 							mstruct.last() ^= Number(-2, 1);
2936 						}
2937 						mstruct *= Number(1, 4);
2938 						return true;
2939 					} else if(mfacexp == nr_two && madd.isZero()) {
2940 						mstruct *= x_var;
2941 						mstruct.last() ^= nr_three;
2942 						mstruct *= Number(1, 3);
2943 						MathStructure mterm(x_var);
2944 						mterm ^= nr_two;
2945 						if(!mmul.isOne()) {
2946 							mterm *= mmul;
2947 							mterm.last() ^= nr_two;
2948 						}
2949 						MathStructure mfac1(mterm);
2950 						mfac1 += Number(-2, 1);
2951 						mterm += m_one;
2952 						mterm ^= nr_half;
2953 						mterm *= mfac1;
2954 						if(!mmul.isOne()) {
2955 							mmul ^= Number(-3, 1);
2956 							mterm *= mmul;
2957 						}
2958 						mterm *= Number(-1, 9);
2959 						mstruct += mterm;
2960 						return true;
2961 					} else if(!mfacexp.isMinusOne() && madd.isZero()) {
2962 						mfacexp += m_one;
2963 						MathStructure minteg(x_var);
2964 						minteg ^= nr_two;
2965 						if(!mmul.isOne()) {
2966 							minteg *= mmul;
2967 							minteg.last() ^= nr_two;
2968 						}
2969 						minteg += m_one;
2970 						minteg ^= Number(-1, 2);
2971 						minteg *= x_var;
2972 						minteg.last() ^= mfacexp;
2973 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2974 						if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2975 							if(!mmul.isOne()) minteg *= mmul;
2976 							minteg /= mfacexp;
2977 							mstruct *= x_var;
2978 							mstruct.last() ^= mfacexp;
2979 							mstruct /= mfacexp;
2980 							mstruct -= minteg;
2981 							return true;
2982 						}
2983 					}
2984 				}
2985 			}
2986 		}
2987 	} else if(mstruct.function()->id() == FUNCTION_ID_ACOSH && mstruct.size() == 1) {
2988 		MathStructure mexp, mmul, madd;
2989 		if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
2990 			if(definite_integral && (!mmul.representsNonComplex(true) || !x_var.representsNonComplex(true))) return false;
2991 			if(mfac.isOne()) {
2992 				if(mpow.isOne()) {
2993 					MathStructure marg(mstruct[0]);
2994 					if(!madd.isZero()) mstruct[0] = x_var;
2995 					MathStructure mterm(mstruct[0]);
2996 					MathStructure msqrt2(mstruct[0]);
2997 					mstruct.multiply(x_var);
2998 					mterm += m_one;
2999 					mterm ^= nr_half;
3000 					msqrt2 += m_minus_one;
3001 					msqrt2 ^= nr_half;
3002 					mterm *= msqrt2;
3003 					if(madd.isZero() && !mmul.isOne()) {
3004 						mterm /= mmul;
3005 					}
3006 					mstruct.subtract(mterm);
3007 					if(!madd.isZero()) {
3008 						mstruct.replace(x_var, marg);
3009 						if(!mmul.isOne()) mstruct.divide(mmul);
3010 					}
3011 					return true;
3012 				} else if(mpow.isMinusOne()) {
3013 					mstruct.transformById(FUNCTION_ID_SINHINT);
3014 					if(!mmul.isOne()) mstruct /= mmul;
3015 					return true;
3016 				} else if(mpow.number() == -2) {
3017 					MathStructure msqrt(mstruct[0]);
3018 					msqrt += m_one;
3019 					msqrt.inverse();
3020 					msqrt *= mstruct[0];
3021 					msqrt.last() += nr_minus_one;
3022 					msqrt ^= nr_half;
3023 					MathStructure macosh(mstruct);
3024 					mstruct.transformById(FUNCTION_ID_COSHINT);
3025 					mstruct *= macosh;
3026 					mstruct *= msqrt;
3027 					mstruct += x_var;
3028 					if(!mmul.isOne()) mstruct.last() *= mmul;
3029 					mstruct.last().negate();
3030 					if(!madd.isZero()) mstruct -= madd;
3031 					mstruct += m_one;
3032 					mstruct /= macosh;
3033 					mstruct /= msqrt;
3034 					if(!mmul.isOne()) mstruct /= mmul;
3035 					return true;
3036 				} else if(madd.isZero()) {
3037 					if(mpow.number().isPositive()) {
3038 						MathStructure mpowm1(mpow);
3039 						if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
3040 						else mpowm1 += nr_minus_one;
3041 						MathStructure mterm(mstruct);
3042 						if(!mpowm1.isOne()) mterm ^= mpowm1;
3043 						MathStructure mfac1(x_var);
3044 						if(!mmul.isOne()) mfac1 *= mmul;
3045 						mfac1 += m_one;
3046 						mfac1 ^= nr_half;
3047 						MathStructure mfac2(x_var);
3048 						if(!mmul.isOne()) mfac2 *= mmul;
3049 						mfac2 += nr_minus_one;
3050 						mfac2 ^= nr_half;
3051 						mterm *= mfac1;
3052 						mterm *= mfac2;
3053 						mterm *= mpow;
3054 						if(!mmul.isOne()) mterm /= mmul;
3055 						MathStructure minteg;
3056 						if(mpowm1.isOne()) {
3057 							minteg = x_var;
3058 						} else {
3059 							minteg = mstruct;
3060 							minteg ^= mpow;
3061 							minteg.last() += Number(-2, 1);
3062 							if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3063 						}
3064 						minteg *= mpow;
3065 						if(!mpowm1.isOne()) minteg *= mpowm1;
3066 						mstruct ^= mpow;
3067 						mstruct *= x_var;
3068 						mstruct -= mterm;
3069 						mstruct += minteg;
3070 						return true;
3071 					} else {
3072 						MathStructure mpowp1(mpow);
3073 						mpowp1 += m_one;
3074 						MathStructure mpowp2(mpow);
3075 						mpowp2 += nr_two;
3076 						MathStructure mterm(mstruct);
3077 						mterm ^= mpowp1;
3078 						MathStructure mfac1(x_var);
3079 						if(!mmul.isOne()) mfac1 *= mmul;
3080 						mfac1 += m_one;
3081 						mfac1 ^= nr_half;
3082 						MathStructure mfac2(x_var);
3083 						if(!mmul.isOne()) mfac2 *= mmul;
3084 						mfac2 += nr_minus_one;
3085 						mfac2 ^= nr_half;
3086 						mterm *= mfac1;
3087 						mterm *= mfac2;
3088 						if(!mmul.isOne()) mterm /= mmul;
3089 						mterm /= mpowp1;
3090 						MathStructure minteg(mstruct);
3091 						minteg ^= mpowp2;
3092 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3093 						minteg /= mpowp1;
3094 						minteg /= mpowp2;
3095 						mstruct ^= mpowp2;
3096 						mstruct *= x_var;
3097 						mstruct /= mpowp1;
3098 						mstruct /= mpowp2;
3099 						mstruct.negate();
3100 						mstruct += mterm;
3101 						mstruct += minteg;
3102 						return true;
3103 					}
3104 				}
3105 			} else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
3106 				MathStructure mfacexp(1, 1, 0);
3107 				if(mfac != x_var) mfacexp = mfac[1];
3108 				if(mpow.isOne()) {
3109 					if(mfacexp.isOne()) {
3110 						MathStructure mterm2(mstruct[0]);
3111 						MathStructure mterm2b(mstruct[0]);
3112 						mterm2 += nr_minus_one;
3113 						mterm2 ^= nr_half;
3114 						mterm2b += m_one;
3115 						mterm2b ^= nr_half;
3116 						mterm2 *= mterm2b;
3117 						MathStructure mfac2(x_var);
3118 						if(!mmul.isOne()) {
3119 							mfac2 *= mmul;
3120 						}
3121 						mfac2.negate();
3122 						if(!madd.isZero()) {
3123 							mfac2 += madd;
3124 							mfac2.last() *= nr_three;
3125 						}
3126 						mterm2 *= mfac2;
3127 						MathStructure mfac1(x_var);
3128 						mfac1 ^= nr_two;
3129 						if(!mmul.isOne()) {
3130 							mfac1 *= mmul;
3131 							mfac1.last() ^= nr_two;
3132 						}
3133 						mfac1 *= nr_two;
3134 						if(!madd.isZero()) {
3135 							mfac1 += madd;
3136 							mfac1.last() ^= nr_two;
3137 							mfac1.last() *= Number(-2, 1);
3138 						}
3139 						mfac1 += nr_minus_one;
3140 						mstruct *= mfac1;
3141 						mstruct += mterm2;
3142 						if(!mmul.isOne()) {
3143 							mstruct *= mmul;
3144 							mstruct.last() ^= Number(-2, 1);
3145 						}
3146 						mstruct *= Number(1, 4);
3147 						return true;
3148 					} else if(mfacexp == nr_two && madd.isZero()) {
3149 						mstruct *= x_var;
3150 						mstruct.last() ^= nr_three;
3151 						mstruct *= Number(1, 3);
3152 						MathStructure mterm(x_var);
3153 						if(!mmul.isOne()) mterm *= mmul;
3154 						mterm += m_one;
3155 						mterm ^= nr_half;
3156 						MathStructure mfac1(x_var);
3157 						if(!mmul.isOne()) mfac1 *= mmul;
3158 						mfac1 += nr_minus_one;
3159 						mfac1 ^= nr_half;
3160 						mterm *= mfac1;
3161 						MathStructure mfac2(x_var);
3162 						mfac2 ^= nr_two;
3163 						if(!mmul.isOne()) {
3164 							mfac2 *= mmul;
3165 							mfac2.last() ^= nr_two;
3166 						}
3167 						mfac2 += nr_two;
3168 						mterm *= mfac2;
3169 						if(!mmul.isOne()) {
3170 							mmul ^= Number(-3, 1);
3171 							mterm *= mmul;
3172 						}
3173 						mterm *= Number(-1, 9);
3174 						mstruct += mterm;
3175 						return true;
3176 					} else if(!mfacexp.isMinusOne() && madd.isZero()) {
3177 						mfacexp += m_one;
3178 						MathStructure minteg(x_var);
3179 						if(!mmul.isOne()) minteg *= mmul;
3180 						minteg += m_one;
3181 						minteg ^= Number(-1, 2);
3182 						MathStructure mfac1(x_var);
3183 						if(!mmul.isOne()) mfac1 *= mmul;
3184 						mfac1 += nr_minus_one;
3185 						mfac1 ^= Number(-1, 2);
3186 						minteg *= mfac1;
3187 						minteg *= x_var;
3188 						minteg.last() ^= mfacexp;
3189 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3190 						if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3191 							if(!mmul.isOne()) minteg *= mmul;
3192 							minteg /= mfacexp;
3193 							mstruct *= x_var;
3194 							mstruct.last() ^= mfacexp;
3195 							mstruct /= mfacexp;
3196 							mstruct -= minteg;
3197 							return true;
3198 						}
3199 					}
3200 				}
3201 			}
3202 		}
3203 	} else if(mstruct.function()->id() == FUNCTION_ID_ATANH && mstruct.size() == 1) {
3204 		MathStructure mexp, mmul, madd;
3205 		if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
3206 			if(!mexp.isOne()) {
3207 				if(mexp.isMinusOne() && mfac.isOne() && madd.isZero()) {
3208 					mstruct *= x_var;
3209 					if(madd.isZero()) {
3210 						MathStructure mterm(mmul);
3211 						if(!mmul.isOne()) mterm ^= nr_two;
3212 						mterm.negate();
3213 						mterm += x_var;
3214 						mterm.last() ^= nr_two;
3215 						mterm.transformById(FUNCTION_ID_LOG);
3216 						if(!mmul.isOne()) mterm *= mmul;
3217 						mterm *= nr_half;
3218 						mstruct += mterm;
3219 					} else {
3220 						MathStructure mterm1(x_var);
3221 						mterm1 *= madd;
3222 						mterm1 += mmul;
3223 						MathStructure mterm2(mterm1);
3224 						mterm1 += x_var;
3225 						mterm2 -= x_var;
3226 						mterm1.transformById(FUNCTION_ID_LOG);
3227 						mterm2.transformById(FUNCTION_ID_LOG);
3228 						mterm1 *= mmul;
3229 						mterm2 *= mmul;
3230 						madd *= nr_two;
3231 						madd += nr_two;
3232 						mterm1 /= madd;
3233 						madd[0].negate();
3234 						mterm2 /= madd;
3235 						mstruct += mterm1;
3236 						mstruct += mterm2;
3237 					}
3238 					return true;
3239 				}
3240 			} else if(mfac.isOne()) {
3241 				MathStructure marg(mstruct[0]);
3242 				mstruct.multiply(marg);
3243 				MathStructure mterm(marg);
3244 				mterm ^= nr_two;
3245 				mterm.negate();
3246 				mterm += m_one;
3247 				mterm.transformById(FUNCTION_ID_LOG);
3248 				mterm *= nr_half;
3249 				mstruct.add(mterm);
3250 				if(!mmul.isOne()) mstruct.divide(mmul);
3251 				return true;
3252 			} else if(madd.isZero() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].isInteger()))) {
3253 				MathStructure mfacexp(1, 1, 0);
3254 				if(mfac != x_var) mfacexp = mfac[1];
3255 				if(mfacexp.isMinusOne()) {
3256 					mstruct.setFunctionId(FUNCTION_ID_POLYLOG);
3257 					mstruct.insertChild(nr_two, 1);
3258 					MathStructure mterm(mstruct);
3259 					mterm[1].negate();
3260 					mterm.negate();
3261 					mstruct += mterm;
3262 					mstruct *= nr_half;
3263 					return true;
3264 				} else if(mfacexp.isOne()) {
3265 					MathStructure mterm1(x_var);
3266 					mterm1 ^= nr_two;
3267 					mterm1 *= mstruct;
3268 					mterm1 *= nr_half;
3269 					MathStructure mterm2(x_var);
3270 					if(!mmul.isOne()) mterm2 /= mmul;
3271 					mterm2 *= nr_half;
3272 					if(!mmul.isOne()) {mstruct *= mmul; mstruct.last() ^= Number(-2, 1);}
3273 					mstruct *= nr_minus_half;
3274 					mstruct += mterm1;
3275 					mstruct += mterm2;
3276 					return true;
3277 				} else {
3278 					mfacexp += m_one;
3279 					MathStructure mxexp(x_var);
3280 					mxexp ^= mfacexp;
3281 					MathStructure minteg(x_var);
3282 					minteg ^= nr_two;
3283 					if(!mmul.isOne()) {minteg *= mmul; minteg.last() ^= nr_two;}
3284 					minteg.negate();
3285 					minteg += m_one;
3286 					if(!definite_integral || COMPARISON_IS_NOT_EQUAL(minteg.compare(m_zero))) {
3287 						minteg ^= nr_minus_one;
3288 						minteg *= mxexp;
3289 						if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3290 						minteg /= mfacexp;
3291 						if(!mmul.isOne()) minteg *= mmul;
3292 						mstruct *= mxexp;
3293 						mstruct /= mfacexp;
3294 						mstruct -= minteg;
3295 						return true;
3296 					}
3297 				}
3298 			}
3299 		}
3300 	} else if(mstruct.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct)) {
3301 		MathStructure madd, mmul, mexp;
3302 		if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3303 			if(mfac.isOne()) {
3304 				MathStructure np1(mstruct[1]);
3305 				mstruct.multiply(mstruct[0]);
3306 				np1.inverse();
3307 				np1 += m_one;
3308 				if(!mmul.isOne()) np1 *= mmul;
3309 				mstruct.divide(np1);
3310 				return true;
3311 			} else if(mfac == x_var) {
3312 				MathStructure nm1(mstruct[1]);
3313 				nm1.inverse();
3314 				nm1 += m_one;
3315 				MathStructure mnum(x_var);
3316 				mnum *= nm1;
3317 				if(!mmul.isOne()) mnum *= mmul;
3318 				if(!madd.isZero()) mnum -= madd;
3319 				MathStructure mden(mstruct[1]);
3320 				mden.inverse();
3321 				mden += nr_two;
3322 				mden *= nm1;
3323 				if(!mmul.isOne()) {
3324 					mden *= mmul;
3325 					mden.last() ^= nr_two;
3326 				}
3327 				mstruct.multiply(mstruct[0]);
3328 				mstruct *= mnum;
3329 				mstruct /= mden;
3330 				return true;
3331 			}
3332 		}
3333 	} else if(mstruct.function()->id() == FUNCTION_ID_ERFC && mstruct.size() == 1) {
3334 		MathStructure mtest(mstruct);
3335 		mtest.setFunctionId(FUNCTION_ID_ERF);
3336 		mtest.negate();
3337 		mtest += m_one;
3338 		if(!mpow.isOne()) mtest ^= mpow;
3339 		if(!mfac.isOne()) mtest *= mfac;
3340 		CALCULATOR->beginTemporaryStopMessages();
3341 		if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0) {
3342 			CALCULATOR->endTemporaryStopMessages(true);
3343 			mstruct = mtest;
3344 			return true;
3345 		}
3346 		CALCULATOR->endTemporaryStopMessages();
3347 	} else if(mstruct.function()->id() == FUNCTION_ID_ERF && mstruct.size() == 1) {
3348 		MathStructure madd, mmul, mexp;
3349 		if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3350 			MathStructure mterm2(CALCULATOR->getVariableById(VARIABLE_ID_E));
3351 			mterm2 ^= mstruct[0];
3352 			mterm2.last() ^= nr_two;
3353 			mterm2.last().negate();
3354 			mterm2 *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3355 			mterm2.last() ^= Number(-1, 2);
3356 			if(!mmul.isOne()) mterm2 /= mmul;
3357 			if(madd.isZero()) {
3358 				mstruct *= x_var;
3359 			} else {
3360 				mstruct *= madd;
3361 				if(!mmul.isOne()) {
3362 					mstruct.last() /= mmul;
3363 					mstruct.childrenUpdated();
3364 				}
3365 				mstruct.last() += x_var;
3366 			}
3367 			mstruct += mterm2;
3368 			return true;
3369 		}
3370 	} else if(mstruct.function()->id() == FUNCTION_ID_ERFI && mstruct.size() == 1) {
3371 		MathStructure madd, mmul, mexp;
3372 		if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3373 			MathStructure mterm2(CALCULATOR->getVariableById(VARIABLE_ID_E));
3374 			mterm2 ^= mstruct[0];
3375 			mterm2.last() ^= nr_two;
3376 			mterm2 *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3377 			mterm2.last() ^= Number(-1, 2);
3378 			if(!mmul.isOne()) mterm2 /= mmul;
3379 			if(madd.isZero()) {
3380 				mstruct *= x_var;
3381 			} else {
3382 				mstruct *= madd;
3383 				if(!mmul.isOne()) {
3384 					mstruct.last() /= mmul;
3385 					mstruct.childrenUpdated();
3386 				}
3387 				mstruct.last() += x_var;
3388 			}
3389 			mstruct -= mterm2;
3390 			return true;
3391 		}
3392 	} else if(mstruct.function()->id() == FUNCTION_ID_FRESNEL_S && mstruct.size() == 1) {
3393 		MathStructure madd, mmul, mexp;
3394 		if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne() && madd.isOne()) {
3395 			MathStructure mterm(x_var);
3396 			mterm ^= nr_two;
3397 			if(!mmul.isOne()) {
3398 				mmul ^= nr_two;
3399 				mterm *= mmul;
3400 			}
3401 			mterm *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3402 			mterm *= nr_half;
3403 			mterm *= CALCULATOR->getRadUnit();
3404 			mterm.transformById(FUNCTION_ID_COS);
3405 			if(!mmul.isOne()) mterm /= mmul;
3406 			mterm /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3407 			mstruct *= x_var;
3408 			mstruct += mterm;
3409 			return true;
3410 		}
3411 	} else if(mstruct.function()->id() == FUNCTION_ID_FRESNEL_C && mstruct.size() == 1) {
3412 		MathStructure madd, mmul, mexp;
3413 		if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne() && madd.isOne()) {
3414 			MathStructure mterm(x_var);
3415 			mterm ^= nr_two;
3416 			if(!mmul.isOne()) {
3417 				mmul ^= nr_two;
3418 				mterm *= mmul;
3419 			}
3420 			mterm *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3421 			mterm *= nr_half;
3422 			mterm *= CALCULATOR->getRadUnit();
3423 			mterm.transformById(FUNCTION_ID_SIN);
3424 			if(!mmul.isOne()) mterm /= mmul;
3425 			mterm /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3426 			mstruct *= x_var;
3427 			mstruct -= mterm;
3428 			return true;
3429 		}
3430 	} else if(mstruct.function()->id() == FUNCTION_ID_DIGAMMA && mstruct.size() == 1) {
3431 		MathStructure madd, mmul, mexp;
3432 		if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3433 			mstruct.setFunctionId(FUNCTION_ID_GAMMA);
3434 			mstruct.transformById(FUNCTION_ID_LOG);
3435 			if(!mmul.isOne()) mstruct /= mmul;
3436 			return true;
3437 		}
3438 	} else if(mstruct.function()->id() == FUNCTION_ID_LOGINT && mstruct.size() == 1) {
3439 		MathStructure madd, mmul, mexp;
3440 		if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3441 			if(mfac.isOne()) {
3442 				MathStructure mEi(mstruct);
3443 				mstruct *= mEi[0];
3444 				mEi.setFunctionId(FUNCTION_ID_LOG);
3445 				mEi *= nr_two;
3446 				mEi.transformById(FUNCTION_ID_EXPINT);
3447 				mstruct -= mEi;
3448 				if(!mmul.isOne()) mstruct /= mmul;
3449 				return true;
3450 			} else if(madd.isZero() && mfac.isPower() && mfac[0] == x_var && mfac[1].isMinusOne()) {
3451 				MathStructure mln(mstruct);
3452 				mln.setFunctionId(FUNCTION_ID_LOG);
3453 				mstruct *= mln;
3454 				mstruct -= mln[0];
3455 				return true;
3456 			}
3457 		}
3458 	} else if(mstruct.function()->id() == FUNCTION_ID_DIFFERENTIATE && (mstruct.size() == 3 || (mstruct.size() == 4 && mstruct[3].isUndefined())) && mstruct[1] == x_var) {
3459 		if(!mpow.isOne() || !mfac.isOne()) return false;
3460 		if(mstruct[2].isOne()) {
3461 			mstruct.setToChild(1, true);
3462 		} else {
3463 			mstruct[2] += m_minus_one;
3464 		}
3465 		return true;
3466 	} else if(mstruct.function()->id() == FUNCTION_ID_DIFFERENTIATE && mstruct.size() == 2 && mstruct[1] == x_var) {
3467 		if(!mpow.isOne() || !mfac.isOne()) return false;
3468 		mstruct.setToChild(1, true);
3469 		return true;
3470 	} else {
3471 		return false;
3472 	}
3473 	if(mstruct.size() == 0) return false;
3474 	bool by_parts_tested = false;
3475 
3476 	if(mfac.isOne() && (mstruct.function()->id() == FUNCTION_ID_LOG || mstruct.function()->id() == FUNCTION_ID_ASIN || mstruct.function()->id() == FUNCTION_ID_ACOS || mstruct.function()->id() == FUNCTION_ID_ATAN || mstruct.function()->id() == FUNCTION_ID_ASINH || mstruct.function()->id() == FUNCTION_ID_ACOSH || mstruct.function()->id() == FUNCTION_ID_ATANH)) {
3477 		by_parts_tested = true;
3478 		//integrate by parts
3479 		if(max_part_depth > 0) {
3480 			MathStructure minteg(mstruct);
3481 			if(!mpow.isOne()) minteg ^= mpow;
3482 			CALCULATOR->beginTemporaryStopMessages();
3483 			if(minteg.differentiate(x_var, eo) && minteg.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) <= 0 && (!definite_integral || check_zero_div(minteg, x_var, eo))) {
3484 				minteg *= x_var;
3485 				EvaluationOptions eo2 = eo;
3486 				eo2.expand = true;
3487 				eo2.combine_divisions = false;
3488 				eo2.sync_units = false;
3489 				minteg.evalSort(true);
3490 				minteg.calculateFunctions(eo);
3491 				minteg.calculatesub(eo2, eo2, true);
3492 				combine_ln(minteg, x_var, eo2);
3493 				do_simplification(minteg, eo2, true, false, false, true, true);
3494 				if(minteg.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0 && minteg.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0) {
3495 					CALCULATOR->endTemporaryStopMessages(true);
3496 					if(!mpow.isOne()) mstruct ^= mpow;
3497 					mstruct.multiply(x_var);
3498 					mstruct.subtract(minteg);
3499 					return true;
3500 				}
3501 			}
3502 			CALCULATOR->endTemporaryStopMessages();
3503 		}
3504 	}
3505 
3506 	MathStructure madd, mmul, mexp;
3507 	if(integrate_info(mstruct[0], x_var, madd, mmul, mexp, false, false, true) && !mexp.isZero()) {
3508 		if(mexp.isPower() && (mexp[1] == x_var || (mexp[1].isMultiplication() && mexp[1].size() >= 2 && mexp[1].last() == x_var)) && mfac.isPower() && (mfac[1] == x_var || (mfac[1].isMultiplication() && mfac[1].size() >= 2 && mfac[1].last() == x_var)) && (mfac[0] == mexp[0] || (mfac[0].isNumber() && mfac[0].number().isRational() && mexp[0].isNumber() && mexp[0].number().isRational() && mexp[1] == mfac[1])) && mexp[0].containsRepresentativeOf(x_var, true, true) == 0) {
3509 			Number pow1(1, 1), pow2;
3510 			MathStructure morig(mexp);
3511 			bool b = true;
3512 			if(mfac[1].isMultiplication()) {
3513 				if(!mexp[1].isMultiplication()) {
3514 					if(mfac[1].size() != 2 || !mfac[1][0].isNumber()) b = false;
3515 					else {pow2 = mfac[1][0].number(); pow2--;}
3516 				} else {
3517 					for(size_t i = 0; i < mexp[1].size() - 1; i++) {
3518 						if(i == 0 && mexp[1][i].isNumber()) {
3519 							pow1 = mexp[1][i].number();
3520 						} else if(mfac[1][i].containsRepresentativeOf(x_var, true, true) != 0) {
3521 							b = false;
3522 							break;
3523 						}
3524 					}
3525 					if(b) {
3526 						if(mexp[1] == mfac[1]) {
3527 							pow1.set(1, 1);
3528 						} else if(mfac[1].size() - (mfac[1][0].isNumber() ? 1 : 0) != mexp[1].size() - (mexp[1][0].isNumber() ? 1 : 0)) {
3529 							b = false;
3530 						} else if(b) {
3531 							for(size_t i = 0; i < mfac[1].size() - 1; i++) {
3532 								if(i == 0 && mfac[1][i].isNumber()) {
3533 									pow2 = mfac[1][i].number();
3534 									pow2--;
3535 								} else if(mfac[1][i] != mexp[1][i + (mexp[1][0].isNumber() ? 1 : 0) - (mfac[1][0].isNumber() ? 1 : 0)]) {
3536 									b = false;
3537 									break;
3538 								}
3539 							}
3540 						}
3541 					}
3542 				}
3543 			} else if(mexp[1].isMultiplication()) {
3544 				if(mexp[1].size() != 2 || !mexp[1][0].isNumber()) b = false;
3545 				else pow1 = mexp[1][0].number();
3546 			}
3547 			if(b && !pow1.isOne()) morig[1].delChild(1, true);
3548 			if(b && mfac[0] != mexp[0]) {
3549 				bool b1 = mfac[0].number() < mexp[0].number();
3550 				if(mfac[0].number().isFraction() || mexp[0].number().isFraction()) b1 = !b1;
3551 				Number nlog(b1 ? mexp[0].number() : mfac[0].number());
3552 				nlog.log(b1 ? mfac[0].number() : mexp[0].number());
3553 				if(!nlog.isInteger()) {
3554 					nlog.round();
3555 					b = nlog.isInteger() && (b1 ? ((mfac[0].number() ^ nlog) == mexp[0].number()) : ((mfac[0].number() ^ nlog) == mexp[0].number()));
3556 				}
3557 				if(b) {
3558 					if(b1) {
3559 						pow1 = nlog;
3560 						morig = mfac;
3561 					} else {
3562 						pow2 = nlog;
3563 						pow2--;
3564 					}
3565 				}
3566 			}
3567 			if(b) {
3568 				UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
3569 				MathStructure mtest(var);
3570 				if(!pow1.isOne()) mtest ^= pow1;
3571 				if(!mmul.isOne()) mtest *= mmul;
3572 				if(!madd.isZero()) mtest += madd;
3573 				mtest.transform(mstruct.function());
3574 				if(!mpow.isOne()) mtest ^= mpow;
3575 				if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3576 					MathStructure m_interval(morig);
3577 					m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3578 					var->setInterval(m_interval);
3579 				} else {
3580 					var->setInterval(morig);
3581 				}
3582 				if(!pow2.isZero()) {
3583 					mtest *= var;
3584 					if(!pow2.isOne()) mtest.last() ^= pow2;
3585 					mtest.swapChildren(1, 2);
3586 				}
3587 				CALCULATOR->beginTemporaryStopMessages();
3588 				if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3589 					CALCULATOR->endTemporaryStopMessages(true);
3590 					mstruct.set(mtest, true);
3591 					mstruct.replace(var, morig);
3592 					if(!morig[0].isVariable() || morig[0].variable()->id() != VARIABLE_ID_E) mstruct.divide_nocopy(new MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &morig[0], NULL));
3593 					if(morig[1].isMultiplication()) {
3594 						morig[1].delChild(morig[1].size(), true);
3595 						mstruct /= morig[1];
3596 					}
3597 					var->destroy();
3598 					return true;
3599 				}
3600 				CALCULATOR->endTemporaryStopMessages();
3601 				var->destroy();
3602 			}
3603 		} else if(mexp == x_var && !madd.isZero() && (mfac.isOne() || mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].isInteger()))) {
3604 			MathStructure morig(x_var);
3605 			if(!mmul.isOne()) morig *= mmul;
3606 			morig += madd;
3607 			UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
3608 			MathStructure mtest(var);
3609 			mtest.transform(mstruct.function());
3610 			if(!mpow.isOne()) mtest ^= mpow;
3611 			if(!mfac.isOne()) {
3612 				MathStructure mrepl(var);
3613 				mrepl -= madd;
3614 				mrepl /= mmul;
3615 				MathStructure mfacnew(mfac);
3616 				mfacnew.replace(x_var, mrepl);
3617 				mtest *= mfacnew;
3618 			}
3619 			if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3620 				MathStructure m_interval(morig);
3621 				m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3622 				var->setInterval(m_interval);
3623 			} else {
3624 				var->setInterval(morig);
3625 			}
3626 			CALCULATOR->beginTemporaryStopMessages();
3627 			if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3628 				CALCULATOR->endTemporaryStopMessages(true);
3629 				mstruct.set(mtest, true);
3630 				mstruct.replace(var, morig);
3631 				if(!mmul.isOne()) mstruct /= mmul;
3632 				var->destroy();
3633 				return true;
3634 			}
3635 			CALCULATOR->endTemporaryStopMessages();
3636 			var->destroy();
3637 		} else if(mfac.isOne() && (mexp.isPower() && mexp[0] == x_var && mexp[1].isNumber() && !mexp[1].number().isInteger() && mexp[1].number().isRational())) {
3638 			Number num(mexp[1].number().numerator());
3639 			Number den(mexp[1].number().denominator());
3640 			if(num.isPositive() || num.isMinusOne()) {
3641 				MathStructure morig(x_var);
3642 				if(num.isNegative()) den.negate();
3643 				Number den_inv(den);
3644 				den_inv.recip();
3645 				morig ^= den_inv;
3646 				UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
3647 				Number den_m1(den);
3648 				den_m1--;
3649 				MathStructure mtest(var);
3650 				if(!num.isOne() && !num.isMinusOne()) mtest ^= num;
3651 				if(!mmul.isOne()) mtest *= mmul;
3652 				if(!madd.isZero()) mtest += madd;
3653 				mtest.transform(mstruct.function());
3654 				if(!mpow.isOne()) mtest ^= mpow;
3655 				mtest *= var;
3656 				if(!den_m1.isOne()) {
3657 					mtest.last() ^= den_m1;
3658 					mtest.childUpdated(mtest.size());
3659 				}
3660 				if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3661 					MathStructure m_interval(morig);
3662 					m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3663 					var->setInterval(m_interval);
3664 				} else {
3665 					var->setInterval(morig);
3666 				}
3667 				CALCULATOR->beginTemporaryStopMessages();
3668 				if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3669 					CALCULATOR->endTemporaryStopMessages(true);
3670 					mstruct.set(mtest, true);
3671 					mstruct.replace(var, morig);
3672 					mstruct.multiply(den);
3673 					var->destroy();
3674 					return true;
3675 				}
3676 				CALCULATOR->endTemporaryStopMessages();
3677 				var->destroy();
3678 			}
3679 		} else if((mfac.isOne() || mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].isInteger())) && (mexp.isPower() && mexp[0] != x_var && mexp[1].isNumber())) {
3680 			MathStructure madd2, mmul2, mexp2;
3681 			if(integrate_info(mexp[0], x_var, madd2, mmul2, mexp2) && (!madd.isZero() || mexp != x_var) && mexp2.isOne()) {
3682 				UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mexp[0]) + RIGHT_PARENTHESIS);
3683 				if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3684 					MathStructure m_interval(mexp[0]);
3685 					m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3686 					var->setInterval(m_interval);
3687 				} else {
3688 					var->setInterval(mexp[0]);
3689 				}
3690 				MathStructure mtest(var);
3691 				mtest ^= mexp[1];
3692 				if(!mmul.isOne()) mtest *= mmul;
3693 				if(!madd.isZero()) mtest += madd;
3694 				mtest.transform(mstruct.function());
3695 				if(!mpow.isOne()) mtest ^= mpow;
3696 				if(!mfac.isOne()) {
3697 					mtest *= var;
3698 					if(!madd2.isZero()) {
3699 						mtest.last() -= madd2;
3700 						mtest.childUpdated(mtest.size());
3701 					}
3702 					if(mfac.isPower()) {
3703 						mtest.last() ^= mfac[1];
3704 						mtest.childUpdated(mtest.size());
3705 					}
3706 				}
3707 				CALCULATOR->beginTemporaryStopMessages();
3708 				if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3709 					CALCULATOR->endTemporaryStopMessages(true);
3710 					mstruct.set(mtest, true);
3711 					mstruct.replace(var, mexp[0]);
3712 					if(!mmul2.isOne()) {
3713 		 				mstruct /= mmul2;
3714 						if(!mfac.isOne()) {
3715 							if(mfac.isPower()) mmul2 ^= mfac[1];
3716 							mstruct /= mmul2;
3717 						}
3718 					}
3719 					var->destroy();
3720 					return true;
3721 				}
3722 				CALCULATOR->endTemporaryStopMessages();
3723 				var->destroy();
3724 			}
3725 		}
3726 	}
3727 	if(mstruct[0].isAddition()) {
3728 		bool b = true;
3729 		for(size_t i = 0; i < mstruct.size(); i++) {
3730 			if(mstruct[i].containsType(STRUCT_ADDITION, true) == 1) {
3731 				b = false;
3732 				break;
3733 			}
3734 		}
3735 		if(b) {
3736 			MathStructure mtest(mstruct);
3737 			if(mtest[0].factorize(eo, false, 0, 0, false, false, NULL, x_var, true, true)) {
3738 				if(integrate_function(mtest, x_var, eo, mpow, mfac, mpowadd, mpowmul, use_abs, definite_integral, max_part_depth, parent_parts)) {
3739 					mstruct = mtest;
3740 					return true;
3741 				}
3742 			}
3743 		}
3744 	}
3745 
3746 	if(!mfac.isOne()) return false;
3747 	MathStructure *m_func = NULL, *m_pow = NULL;
3748 	if(mstruct[0].isFunction() && mstruct[0].contains(x_var, true) > 0) {
3749 		m_func = &mstruct[0];
3750 	} else if(mstruct[0].isPower() && mstruct[0][0].isFunction() && mstruct[0][0].contains(x_var, true) > 0) {
3751 		m_func = &mstruct[0][0];
3752 	} else if(mstruct[0].isPower() && mstruct[0][1].contains(x_var, true) > 0) {
3753 		m_pow = &mstruct[0];
3754 	} else if(mstruct[0].isMultiplication()) {
3755 		for(size_t i = 0; i < mstruct[0].size(); i++) {
3756 			if(mstruct[0][i].isFunction() && mstruct[0][i].contains(x_var, true) > 0) {
3757 				m_func = &mstruct[0][i];
3758 			} else if(mstruct[0][i].isPower() && mstruct[0][i][0].isFunction() && mstruct[0][i][0].contains(x_var, true) > 0) {
3759 				m_func = &mstruct[0][i][0];
3760 			} else if(mstruct[0][i].isPower() && mstruct[0][i][1].contains(x_var, true) > 0) {
3761 				m_pow = &mstruct[0][i];
3762 			}
3763 		}
3764 	} else if(mstruct[0].isAddition()) {
3765 		for(size_t i2 = 0; i2 < mstruct[0].size(); i2++) {
3766 			if(mstruct[0][i2].isFunction() && mstruct[0][i2].contains(x_var, true) > 0) {
3767 				m_func = &mstruct[0][i2];
3768 			} else if(mstruct[0][i2].isPower() && mstruct[0][i2][0].isFunction() && mstruct[0][i2][0].contains(x_var, true) > 0) {
3769 				m_func = &mstruct[0][i2][0];
3770 			} else if(mstruct[0][i2].isPower() && mstruct[0][i2][1].contains(x_var, true) > 0) {
3771 				m_pow = &mstruct[0][i2];
3772 			} else if(mstruct[0][i2].isMultiplication()) {
3773 				for(size_t i = 0; i < mstruct[0][i2].size(); i++) {
3774 					if(mstruct[0][i2][i].isFunction() && mstruct[0][i2][i].contains(x_var, true) > 0) {
3775 						m_func = &mstruct[0][i2][i];
3776 					} else if(mstruct[0][i2][i].isPower() && mstruct[0][i2][i][0].isFunction() && mstruct[0][i2][i][0].contains(x_var, true) > 0) {
3777 						m_func = &mstruct[0][i2][i][0];
3778 					} else if(mstruct[0][i2][i].isPower() && mstruct[0][i2][i][1].contains(x_var, true) > 0) {
3779 						m_pow = &mstruct[0][i2][i];
3780 					}
3781 				}
3782 			}
3783 		}
3784 	}
3785 	if(m_func && m_pow) return false;
3786 	if(m_func) {
3787 		if((m_func->function()->id() == FUNCTION_ID_LOG || m_func->function()->id() == FUNCTION_ID_ASIN || m_func->function()->id() == FUNCTION_ID_ACOS || m_func->function()->id() == FUNCTION_ID_ASINH || m_func->function()->id() == FUNCTION_ID_ACOSH) && m_func->size() == 1 && integrate_info((*m_func)[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3788 			MathStructure m_orig(*m_func);
3789 			UnknownVariable *var = new UnknownVariable("", format_and_print(m_orig));
3790 			MathStructure mtest(mstruct);
3791 			if(!mpow.isOne()) mtest ^= mpow;
3792 			mtest[0].replace(m_orig, var, (*m_func)[0].containsInterval());
3793 			if(mtest[0].containsRepresentativeOf(x_var, true, true) == 0) {
3794 				if(m_func->function()->id() == FUNCTION_ID_LOG) {
3795 					MathStructure m_epow(CALCULATOR->getVariableById(VARIABLE_ID_E));
3796 					m_epow ^= var;
3797 					mtest *= m_epow;
3798 				} else if(m_func->function()->id() == FUNCTION_ID_ASIN) {
3799 					MathStructure m_cos(var);
3800 					if(CALCULATOR->getRadUnit()) m_cos *= CALCULATOR->getRadUnit();
3801 					m_cos.transformById(FUNCTION_ID_COS);
3802 					mtest *= m_cos;
3803 				} else if(m_func->function()->id() == FUNCTION_ID_ACOS) {
3804 					MathStructure m_sin(var);
3805 					if(CALCULATOR->getRadUnit()) m_sin *= CALCULATOR->getRadUnit();
3806 					m_sin.transformById(FUNCTION_ID_SIN);
3807 					mtest *= m_sin;
3808 					mmul.negate();
3809 				} else if(m_func->function()->id() == FUNCTION_ID_ASINH) {
3810 					MathStructure m_cos(var);
3811 					m_cos.transformById(FUNCTION_ID_COSH);
3812 					mtest *= m_cos;
3813 				} else if(m_func->function()->id() == FUNCTION_ID_ACOSH) {
3814 					MathStructure m_sin(var);
3815 					m_sin.transformById(FUNCTION_ID_SINH);
3816 					mtest *= m_sin;
3817 				}
3818 				if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3819 					MathStructure m_interval(m_orig);
3820 					m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3821 					var->setInterval(m_interval);
3822 				} else {
3823 					var->setInterval(m_orig);
3824 				}
3825 				CALCULATOR->beginTemporaryStopMessages();
3826 				if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3827 					CALCULATOR->endTemporaryStopMessages(true);
3828 					mstruct.set(mtest, true);
3829 					mstruct.replace(var, m_orig);
3830 					if(!mmul.isOne()) mstruct /= mmul;
3831 					var->destroy();
3832 					return true;
3833 				}
3834 				CALCULATOR->endTemporaryStopMessages();
3835 			}
3836 			var->destroy();
3837 		}
3838 	}
3839 	if(m_pow) {
3840 		if((*m_pow)[0].containsRepresentativeOf(x_var, true, true) == 0 && integrate_info((*m_pow)[1], x_var, madd, mmul, mexp) && mexp.isOne()) {
3841 			if(definite_integral && ((*m_pow)[0].compare(m_zero) != COMPARISON_RESULT_LESS)) return false;
3842 			MathStructure m_orig(*m_pow);
3843 			UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_orig) + RIGHT_PARENTHESIS);
3844 			MathStructure mtest(mstruct);
3845 			mtest[0].replace(m_orig, var, m_pow->containsInterval());
3846 			if(mtest[0].containsRepresentativeOf(x_var, true, true) == 0) {
3847 				if(!mpow.isOne()) mtest ^= mpow;
3848 				mtest /= var;
3849 				if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3850 					MathStructure m_interval(m_orig);
3851 					m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3852 					var->setInterval(m_interval);
3853 				} else {
3854 					var->setInterval(m_orig);
3855 				}
3856 				CALCULATOR->beginTemporaryStopMessages();
3857 				if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3858 					CALCULATOR->endTemporaryStopMessages(true);
3859 					mstruct.set(mtest, true);
3860 					mstruct.replace(var, m_orig);
3861 					MathStructure m_ln(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &m_orig[0], NULL);
3862 					mstruct /= m_ln;
3863 					if(!mmul.isOne()) mstruct /= mmul;
3864 					var->destroy();
3865 					return true;
3866 				}
3867 				CALCULATOR->endTemporaryStopMessages();
3868 			}
3869 			var->destroy();
3870 		}
3871 	}
3872 
3873 	if(!by_parts_tested && mstruct.function()->id() != FUNCTION_ID_SIN && mstruct.function()->id() != FUNCTION_ID_COS && mstruct.function()->id() != FUNCTION_ID_TAN && mstruct.function()->id() != FUNCTION_ID_SINH && mstruct.function()->id() != FUNCTION_ID_COSH && mstruct.function()->id() != FUNCTION_ID_TANH) {
3874 		//integrate by parts
3875 		if(max_part_depth > 0) {
3876 			MathStructure minteg(mstruct);
3877 			if(!mpow.isOne()) minteg ^= mpow;
3878 			CALCULATOR->beginTemporaryStopMessages();
3879 			if(minteg.differentiate(x_var, eo) && minteg.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) <= 0 && (!definite_integral || check_zero_div(minteg, x_var, eo))) {
3880 				minteg *= x_var;
3881 				EvaluationOptions eo2 = eo;
3882 				eo2.expand = true;
3883 				eo2.combine_divisions = false;
3884 				eo2.sync_units = false;
3885 				minteg.evalSort(true);
3886 				minteg.calculateFunctions(eo);
3887 				minteg.calculatesub(eo2, eo2, true);
3888 				combine_ln(minteg, x_var, eo2);
3889 				do_simplification(minteg, eo2, true, false, false, true, true);
3890 				if(minteg.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0 && minteg.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0) {
3891 					CALCULATOR->endTemporaryStopMessages(true);
3892 					if(!mpow.isOne()) mstruct ^= mpow;
3893 					mstruct.multiply(x_var);
3894 					mstruct.subtract(minteg);
3895 					return true;
3896 				}
3897 			}
3898 			CALCULATOR->endTemporaryStopMessages();
3899 		}
3900 	}
3901 	return false;
3902 }
3903 
3904 #define CANNOT_INTEGRATE {MathStructure minteg(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), this, &m_undefined, &m_undefined, &x_var, &m_zero, NULL); set(minteg); return false;}
3905 #define CANNOT_INTEGRATE_INTERVAL {MathStructure minteg(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), this, &m_undefined, &m_undefined, &x_var, &m_zero, NULL); set(minteg); return -1;}
3906 
contains_unsolved_integrate(const MathStructure & mstruct,MathStructure * this_mstruct,vector<MathStructure * > * parent_parts)3907 int contains_unsolved_integrate(const MathStructure &mstruct, MathStructure *this_mstruct, vector<MathStructure*> *parent_parts) {
3908 	if(mstruct.isFunction() && mstruct.function()->id() == FUNCTION_ID_INTEGRATE) {
3909 		if(this_mstruct->equals(mstruct[0], true)) return 3;
3910 		for(size_t i = 0; i < parent_parts->size(); i++) {
3911 			if(mstruct[0].equals(*(*parent_parts)[i], true)) return 2;
3912 		}
3913 		return 1;
3914 	}
3915 	int ret = 0;
3916 	for(size_t i = 0; i < mstruct.size(); i++) {
3917 		int ret_i = contains_unsolved_integrate(mstruct[i], this_mstruct, parent_parts);
3918 		if(ret_i == 1) {
3919 			return 1;
3920 		} else if(ret_i > ret) {
3921 			ret = ret_i;
3922 		}
3923 	}
3924 	return ret;
3925 }
3926 
3927 // remove abs() when possible
fix_abs_x(MathStructure & mstruct,const MathStructure & x_var,const EvaluationOptions & eo,bool definite_integral)3928 bool fix_abs_x(MathStructure &mstruct, const MathStructure &x_var, const EvaluationOptions &eo, bool definite_integral) {
3929 	bool b = false;
3930 	if(mstruct.isFunction() && mstruct.size() == 1 && mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ABS && mstruct[0].size() == 1) {
3931 		if(!definite_integral && (mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_TAN || mstruct.function()->id() == FUNCTION_ID_SINH || mstruct.function()->id() == FUNCTION_ID_TANH || mstruct.function()->id() == FUNCTION_ID_ASIN || mstruct.function()->id() == FUNCTION_ID_ATAN || mstruct.function()->id() == FUNCTION_ID_ASINH || mstruct.function()->id() == FUNCTION_ID_ATANH) && mstruct[0][0].representsNonComplex(true)) {
3932 			// sin(abs(f(x)))=sgn(f(x))*sin(f(x)) if not f(x) is complex
3933 			mstruct[0].setToChild(1, true);
3934 			mstruct.multiply_nocopy(new MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIGNUM), &mstruct[0], &m_zero, NULL));
3935 			mstruct.evalSort(false);
3936 			b = true;
3937 		} else if((mstruct.function()->id() == FUNCTION_ID_COS || mstruct.function()->id() == FUNCTION_ID_COSH) && mstruct[0][0].representsNonComplex(true)) {
3938 			// cos(abs(f(x)))=cos(f(x)) if not f(x) is complex
3939 			mstruct[0].setToChild(1, true);
3940 			b = true;
3941 		} else if(mstruct.function()->id() == FUNCTION_ID_LOG) {
3942 			// ln(abs(f(x)))=ln(f(x)^2)/2 if not f(x) is complex
3943 			if(mstruct[0][0].representsNonComplex(true)) {
3944 				b = true;
3945 			} else {
3946 				MathStructure mtest(mstruct[0][0]);
3947 				transform_absln(mtest, -1, false, x_var, eo);
3948 				b = !mtest.isFunction() || mtest.function()->id() != FUNCTION_ID_LOG || (mtest.size() >= 0 && mtest[0].isFunction() && mtest[0].function()->id() == FUNCTION_ID_ABS);
3949 			}
3950 			if(b) {
3951 				mstruct[0].setToChild(1, true);
3952 				mstruct[0] ^= nr_two;
3953 				mstruct /= nr_two;
3954 			}
3955 		}
3956 	}
3957 	for(size_t i = 0; i < mstruct.size(); i++) {
3958 		if(fix_abs_x(mstruct[i], x_var, eo, definite_integral)) b = true;
3959 	}
3960 	return b;
3961 }
3962 
find_abs_x2(MathStructure & mstruct,const MathStructure & x_var,const MathStructure * parent=NULL,int level=0)3963 MathStructure *find_abs_x2(MathStructure &mstruct, const MathStructure &x_var, const MathStructure *parent = NULL, int level = 0) {
3964 	if(mstruct.isFunction()) {
3965 		if(((mstruct.function()->id() == FUNCTION_ID_ABS && mstruct.size() == 1) || (mstruct.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct) && mstruct[1].number().isOdd())) && mstruct[0].contains(x_var, true) > 0 && mstruct[0].representsNonComplex(true)) {
3966 			return &mstruct[0];
3967 		}
3968 		if((!parent || parent->isMultiplication() || parent->isAddition()) && level <= 2 && mstruct.function()->id() == FUNCTION_ID_LOG && mstruct.size() == 1) {
3969 			if((mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0].isPower() && mstruct[0][1].isInteger() && mstruct[0][0].isFunction() && mstruct[0][0].function()->id() == FUNCTION_ID_ROOT)) return NULL;
3970 			if(mstruct[0].isMultiplication() && mstruct[0].size() == 2 && ((mstruct[0][1].isFunction() && mstruct[0][1].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0][1].isPower() && mstruct[0][1][1].isInteger() && mstruct[0][1][0].isFunction() && mstruct[0][1][0].function()->id() == FUNCTION_ID_ROOT))) return NULL;
3971 		}
3972 	}
3973 	for(size_t i = 0; i < mstruct.size(); i++) {
3974 		MathStructure *m = find_abs_x2(mstruct[i], x_var, &mstruct, level + 1);
3975 		if(m) return m;
3976 	}
3977 	return NULL;
3978 }
fix_sgn_x(MathStructure & mstruct,const MathStructure & x_var,const EvaluationOptions & eo)3979 bool fix_sgn_x(MathStructure &mstruct, const MathStructure &x_var, const EvaluationOptions &eo) {
3980 	if(mstruct.isFunction() && mstruct.function()->id() == FUNCTION_ID_SIGNUM && mstruct.size() == 2) {
3981 		MathStructure mtest(mstruct);
3982 		KnownVariable *var = new KnownVariable("", format_and_print(x_var), ((UnknownVariable*) x_var.variable())->interval());
3983 		mtest.replace(x_var, var);
3984 		CALCULATOR->beginTemporaryStopMessages();
3985 		mtest.eval(eo);
3986 		var->destroy();
3987 		if(!CALCULATOR->endTemporaryStopMessages() && !mtest.isFunction()) {
3988 			mstruct.set(mtest);
3989 			return true;
3990 		}
3991 	}
3992 	bool b = false;
3993 	for(size_t i = 0; i < mstruct.size(); i++) {
3994 		if(fix_sgn_x(mstruct[i], x_var, eo)) b = true;
3995 	}
3996 	return b;
3997 }
replace_abs_x(MathStructure & mstruct,const MathStructure & marg,bool b_minus,const MathStructure * parent=NULL,int level=0)3998 bool replace_abs_x(MathStructure &mstruct, const MathStructure &marg, bool b_minus, const MathStructure *parent = NULL, int level = 0) {
3999 	if(mstruct.isFunction()) {
4000 		if(mstruct.function()->id() == FUNCTION_ID_ABS && mstruct.size() == 1 && mstruct[0].equals(marg, true)) {
4001 			mstruct.setToChild(1);
4002 			if(b_minus) mstruct.negate();
4003 			return true;
4004 		} else if(mstruct.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct) && mstruct[1].number().isOdd() && mstruct[0].equals(marg, true)) {
4005 			if(b_minus) mstruct[0].negate();
4006 			mstruct[1].number().recip();
4007 			mstruct.setType(STRUCT_POWER);
4008 			mstruct.childrenUpdated();
4009 			if(b_minus) mstruct.negate();
4010 			return true;
4011 		}
4012 		if((!parent || parent->isMultiplication() || parent->isAddition()) && level <= 2 && mstruct.function()->id() == FUNCTION_ID_LOG && mstruct.size() == 1) {
4013 			if((mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0].isPower() && mstruct[0][1].isInteger() && mstruct[0][0].isFunction() && mstruct[0][0].function()->id() == FUNCTION_ID_ROOT)) return false;
4014 			if(mstruct[0].isMultiplication() && mstruct[0].size() == 2 && ((mstruct[0][1].isFunction() && mstruct[0][1].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0][1].isPower() && mstruct[0][1][1].isInteger() && mstruct[0][1][0].isFunction() && mstruct[0][1][0].function()->id() == FUNCTION_ID_ROOT))) return false;
4015 		}
4016 	}
4017 	if(mstruct.isPower() && mstruct[1].isInteger() && mstruct[1].number().isOdd() && mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct[0]) && mstruct[0][1].number().isOdd() && mstruct[0][0].equals(marg, true)) {
4018 		mstruct[1].number().divide(mstruct[0][1].number());
4019 		mstruct[0].setToChild(1, true);
4020 		if(mstruct[1].number().isOne()) mstruct.setToChild(1, true);
4021 		if(b_minus) mstruct[0].negate();
4022 		mstruct.childrenUpdated();
4023 		if(b_minus) mstruct.negate();
4024 		return true;
4025 	}
4026 	bool b = false;
4027 	for(size_t i = 0; i < mstruct.size(); i++) {
4028 		if(replace_abs_x(mstruct[i], marg, b_minus, &mstruct, level + 1)) {
4029 			mstruct.childUpdated(i + 1);
4030 			b = true;
4031 		}
4032 	}
4033 	return b;
4034 }
4035 
test_sign_zero(const MathStructure & m,const MathStructure & x_var,const MathStructure & mzero,const EvaluationOptions & eo)4036 bool test_sign_zero(const MathStructure &m, const MathStructure &x_var, const MathStructure &mzero, const EvaluationOptions &eo) {
4037 	if(m.contains(x_var, true) <= 0) return false;
4038 	if(m.isMultiplication()) {
4039 		for(size_t i = 0; i < m.size(); i++) {
4040 			if(m[i].isPower() && m[i][1].representsNegative() && test_sign_zero(m[i][0], x_var, mzero, eo)) return true;
4041 		}
4042 	}
4043 	CALCULATOR->beginTemporaryStopMessages();
4044 	MathStructure mtest(m);
4045 	mtest.replace(x_var, mzero);
4046 	mtest.transform(COMPARISON_EQUALS, m_zero);
4047 	mtest.eval(eo);
4048 	return !CALCULATOR->endTemporaryStopMessages() && mtest.isOne();
4049 }
4050 
do_signum(MathStructure & m1,const MathStructure & marg)4051 void do_signum(MathStructure &m1, const MathStructure &marg) {
4052 	/*m1 *= marg;
4053 	m1 *= marg;
4054 	m1.last().transformById(FUNCTION_ID_ABS);
4055 	m1.last().inverse();*/
4056 	m1 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIGNUM), &marg, &m_zero, NULL);
4057 }
try_sign(MathStructure & m1,MathStructure & m2,const MathStructure & marg,const MathStructure & x_var,const MathStructure & mzero,const EvaluationOptions & eo,bool * test_zero=NULL)4058 bool try_sign(MathStructure &m1, MathStructure &m2, const MathStructure &marg, const MathStructure &x_var, const MathStructure &mzero, const EvaluationOptions &eo, bool *test_zero = NULL) {
4059 	if(m1.equals(m2, true)) return true;
4060 	if(m1.isNumber() && m1.number().isReal() && m2.isNumber() && m2.number().isReal()) {
4061 		m2.number().negate();
4062 		if(m1.number().equals(m2.number(), true)) {
4063 			m2.number().negate();
4064 			if(!test_sign_zero(m1, x_var, mzero, eo)) {
4065 				if(!test_zero) return false;
4066 				*test_zero = true;
4067 			}
4068 			if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4069 			return true;
4070 		}
4071 		m2.number().negate();
4072 		return false;
4073 	}
4074 	if(m1.type() != m2.type()) {
4075 		if((m1.isMultiplication() && m1.size() == 2 && m1[0].isMinusOne() && try_sign(m1[1], m2, marg, x_var, mzero, eo)) || (m2.isMultiplication() && m2.size() == 2 && m2[0].isMinusOne() && try_sign(m1, m2[1], marg, x_var, mzero, eo))) {
4076 			if(!test_sign_zero(m1, x_var, mzero, eo)) {
4077 				if(!test_zero) return false;
4078 				*test_zero = true;
4079 			}
4080 			if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4081 			return true;
4082 		}
4083 		return false;
4084 	}
4085 	if(m1.size() == 0) return false;
4086 	if(m1.size() != m2.size()) {
4087 		if(m1.isMultiplication() && ((m1.size() == m2.size() + 1 && m1[0].isMinusOne()) || (m2.size() == m1.size() + 1 && m2[0].isMinusOne()))) {
4088 			if(m1.size() > m2.size()) {
4089 				for(size_t i = 0; i < m2.size(); i++) {
4090 					if(!try_sign(m1[i + 1], m2[i], marg, x_var, mzero, eo)) return false;
4091 				}
4092 			} else {
4093 				for(size_t i = 0; i < m1.size(); i++) {
4094 					if(!try_sign(m1[i], m2[i + 1], marg, x_var, mzero, eo)) return false;
4095 				}
4096 			}
4097 			if(!test_sign_zero(m1, x_var, mzero, eo)) {
4098 				if(!test_zero) return false;
4099 				*test_zero = true;
4100 			}
4101 			if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4102 			return true;
4103 		}
4104 		return false;
4105 	}
4106 	if(m1.isFunction() && m1.function() != m2.function()) return false;
4107 	if(m1.isComparison() && m1.comparisonType() != m2.comparisonType()) return false;
4108 	if(m1.isMultiplication() && m1.size() > 1 && m1[0].isNumber() && !m1[0].equals(m2[0], true)) {
4109 		if(!m1[0].isNumber()) return false;
4110 		m2[0].number().negate();
4111 		if(m1[0].number().equals(m2[0].number(), true)) {
4112 			m2[0].number().negate();
4113 			for(size_t i = 1; i < m1.size(); i++) {
4114 				if(!try_sign(m1[i], m2[i], marg, x_var, mzero, eo)) return false;
4115 			}
4116 			if(!test_sign_zero(m1, x_var, mzero, eo)) {
4117 				if(!test_zero) return false;
4118 				*test_zero = true;
4119 			}
4120 			if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4121 			return true;
4122 		}
4123 		m2[0].number().negate();
4124 		return false;
4125 	}/* else if(m1.isPower()) {
4126 		bool b_tz = false;
4127 		if(!try_sign(m1[0], m2[0], marg, x_var, mzero, eo, &b_tz) || b_tz) return false;
4128 		if(!try_sign(m1[1], m2[1], marg, x_var, mzero, eo, &b_tz)) return false;
4129 		if(b_tz && (test_sign_zero(m1[1], x_var, mzero, eo) || !test_sign_zero(m1[0], x_var, mzero, eo))) return false;
4130 		return true;
4131 	}*/
4132 	bool b_tz = false;
4133 	bool b_equal = false;
4134 	for(size_t i = 0; i < m1.size(); i++) {
4135 		if(!b_equal && m1.isAddition() && m1[i].equals(m2[i], true)) b_equal = true;
4136 		else if(!try_sign(m1[i], m2[i], marg, x_var, mzero, eo, m1.isAddition() ? &b_tz : NULL)) return false;
4137 		if(b_tz && b_equal) break;
4138 	}
4139 	if(b_tz) {
4140 		if(!test_sign_zero(m1, x_var, mzero, eo)) {
4141 			if(!test_zero) return false;
4142 			*test_zero = true;
4143 		}
4144 		if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4145 	}
4146 	return true;
4147 }
contains_imaginary(const MathStructure & m)4148 bool contains_imaginary(const MathStructure &m) {
4149 	if(m.isNumber()) return m.number().hasImaginaryPart();
4150 	if(m.isVariable() && m.variable()->isKnown()) return contains_imaginary(((KnownVariable*) m.variable())->get());
4151 	for(size_t i = 0; i < m.size(); i++) {
4152 		if(contains_imaginary(m[i])) return true;
4153 	}
4154 	return false;
4155 }
4156 
integrate(const MathStructure & x_var,const EvaluationOptions & eo_pre,bool simplify_first,int use_abs,bool definite_integral,bool try_abs,int max_part_depth,vector<MathStructure * > * parent_parts)4157 int MathStructure::integrate(const MathStructure &x_var, const EvaluationOptions &eo_pre, bool simplify_first, int use_abs, bool definite_integral, bool try_abs, int max_part_depth, vector<MathStructure*> *parent_parts) {
4158 
4159 	if(CALCULATOR->aborted()) CANNOT_INTEGRATE
4160 
4161 	EvaluationOptions eo = eo_pre;
4162 	eo.protected_function = CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE);
4163 	EvaluationOptions eo2 = eo;
4164 	eo2.expand = true;
4165 	eo2.combine_divisions = false;
4166 	eo2.sync_units = false;
4167 	EvaluationOptions eo_t = eo;
4168 	eo_t.approximation = APPROXIMATION_TRY_EXACT;
4169 	eo_t.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
4170 
4171 	if(simplify_first) {
4172 		unformat(eo_pre);
4173 		calculateFunctions(eo2);
4174 		calculatesub(eo2, eo2);
4175 		combine_ln(*this, x_var, eo2);
4176 		if(CALCULATOR->aborted()) CANNOT_INTEGRATE
4177 	}
4178 	bool recalc = false;
4179 
4180 	// Try to remove abs() and sgn()
4181 
4182 	if(fix_abs_x(*this, x_var, eo, definite_integral)) recalc = true;
4183 
4184 	MathStructure *mfound = NULL;
4185 	if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4186 		if(fix_sgn_x(*this, x_var, eo_t)) recalc = true;
4187 		while(true) {
4188 			mfound = find_abs_x2(*this, x_var);
4189 			if(mfound) {
4190 				MathStructure m_interval(*mfound);
4191 				m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4192 				CALCULATOR->beginTemporaryStopMessages();
4193 				m_interval.eval(eo_t);
4194 				if(!CALCULATOR->endTemporaryStopMessages()) break;
4195 				if(m_interval.representsNonNegative(true)) {
4196 					replace_abs_x(*this, MathStructure(*mfound), false);
4197 					recalc = true;
4198 				} else if(m_interval.representsNegative(true)) {
4199 					replace_abs_x(*this, MathStructure(*mfound), true);
4200 					recalc = true;
4201 				} else {
4202 					break;
4203 				}
4204 			} else {
4205 				break;
4206 			}
4207 		}
4208 	}
4209 	if(recalc) {
4210 		calculatesub(eo2, eo2);
4211 		combine_ln(*this, x_var, eo2);
4212 	}
4213 
4214 	// x: x^2/2
4215 	if(equals(x_var)) {
4216 		raise(2);
4217 		multiply(MathStructure(1, 2, 0));
4218 		return true;
4219 	}
4220 
4221 	// a: a*x
4222 	if(containsRepresentativeOf(x_var, true, true) == 0) {
4223 		multiply(x_var);
4224 		return true;
4225 	}
4226 
4227 	if(m_type == STRUCT_ADDITION) {
4228 		// f(x)+g(x): integral of f(x) + integral of g(x)
4229 		bool b = false;
4230 		MathStructure mbak(*this);
4231 		for(size_t i = 0; i < SIZE; i++) {
4232 			int bint = CHILD(i).integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts);
4233 			if(bint < 0) {
4234 				set(mbak);
4235 				CANNOT_INTEGRATE_INTERVAL
4236 			}
4237 			if(bint > 0) b = true;
4238 			CHILD_UPDATED(i);
4239 		}
4240 		if(!b) return false;
4241 		return true;
4242 	} else if(m_type == STRUCT_MULTIPLICATION) {
4243 		// a*f(x): a * integral of f(x)
4244 		MathStructure mstruct;
4245 		bool b = false;
4246 		for(size_t i = 0; i < SIZE;) {
4247 			if(CHILD(i).containsRepresentativeOf(x_var, true, true) == 0) {
4248 				if(b) {
4249 					mstruct *= CHILD(i);
4250 				} else {
4251 					mstruct = CHILD(i);
4252 					b = true;
4253 				}
4254 				ERASE(i);
4255 			} else {
4256 				i++;
4257 			}
4258 		}
4259 		if(b) {
4260 			if(SIZE == 1) {
4261 				setToChild(1, true);
4262 			} else if(SIZE == 0) {
4263 				set(mstruct, true);
4264 				return true;
4265 			}
4266 			if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) {
4267 				multiply(mstruct);
4268 				CANNOT_INTEGRATE_INTERVAL
4269 			}
4270 			multiply(mstruct);
4271 			return true;
4272 		}
4273 
4274 		for(size_t i = 0; i < SIZE; i++) {
4275 			if((CHILD(i).isFunction() && CHILD(i).function()->id() == FUNCTION_ID_ABS && CHILD(i).size() == 1) || (CHILD(i).isPower() && CHILD(i)[0].isFunction() && CHILD(i)[0].function()->id() == FUNCTION_ID_ABS && CHILD(i)[0].size() == 1 && CHILD(i)[1].representsOdd())) {
4276 				if(definite_integral) CANNOT_INTEGRATE
4277 				bool b = (m_type == STRUCT_POWER ? CHILD(0)[0].representsNonComplex(true) : CHILD(0).representsNonComplex(true));
4278 				if(!b && !(m_type == STRUCT_POWER ? CHILD(0)[0].representsComplex(true) : CHILD(0).representsComplex(true))) {
4279 					MathStructure mtest(m_type == STRUCT_POWER ? CHILD(0)[0] : CHILD(0));
4280 					CALCULATOR->beginTemporaryStopMessages();
4281 					mtest.eval(eo_t);
4282 					CALCULATOR->endTemporaryStopMessages();
4283 					b = mtest.representsNonComplex(true);
4284 					if(!b && !mtest.representsComplex(true)) {
4285 						if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4286 							CALCULATOR->beginTemporaryStopMessages();
4287 							mtest.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4288 							mtest.eval(eo_t);
4289 							CALCULATOR->endTemporaryStopMessages();
4290 							b = mtest.representsNonComplex(true);
4291 							if(!b && !mtest.representsComplex(true) && !contains_imaginary(mtest) && !contains_imaginary(((UnknownVariable*) x_var.variable())->interval())) {
4292 								CALCULATOR->error(false, "Integral assumed real", NULL);
4293 								b = true;
4294 							}
4295 						} else if(!contains_imaginary(mtest)) {
4296 							CALCULATOR->error(false, "Integral assumed real", NULL);
4297 							b = true;
4298 						}
4299 					}
4300 				}
4301 				if(b) {
4302 					MathStructure mmul(CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i));
4303 					if(CHILD(i).isPower()) CHILD(i)[0].setToChild(1, true);
4304 					else CHILD(i).setToChild(1, true);
4305 					mmul.inverse();
4306 					mmul *= CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i);
4307 					if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) {
4308 						multiply(mmul);
4309 						CANNOT_INTEGRATE_INTERVAL
4310 					}
4311 					multiply(mmul);
4312 					return true;
4313 				}
4314 			}
4315 		}
4316 	} else if((m_type == STRUCT_FUNCTION && o_function->id() == FUNCTION_ID_ABS && SIZE == 1) || (m_type == STRUCT_POWER && CHILD(0).isFunction() && CHILD(0).function()->id() == FUNCTION_ID_ABS && CHILD(0).size() == 1 && CHILD(1).representsOdd())) {
4317 		bool b = (m_type == STRUCT_POWER ? CHILD(0)[0].representsNonComplex(true) : CHILD(0).representsNonComplex(true));
4318 		if(!b && !(m_type == STRUCT_POWER ? CHILD(0)[0].representsComplex(true) : CHILD(0).representsComplex(true))) {
4319 			MathStructure mtest(m_type == STRUCT_POWER ? CHILD(0)[0] : CHILD(0));
4320 			CALCULATOR->beginTemporaryStopMessages();
4321 			mtest.eval(eo_t);
4322 			CALCULATOR->endTemporaryStopMessages();
4323 			b = mtest.representsNonComplex(true);
4324 			if(!b && !mtest.representsComplex(true)) {
4325 				if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4326 					CALCULATOR->beginTemporaryStopMessages();
4327 					mtest.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4328 					mtest.eval(eo_t);
4329 					CALCULATOR->endTemporaryStopMessages();
4330 					b = mtest.representsNonComplex(true);
4331 					if(!b && !mtest.representsComplex(true) && !contains_imaginary(mtest) && !contains_imaginary(((UnknownVariable*) x_var.variable())->interval())) {
4332 						CALCULATOR->error(false, "Integral assumed real", NULL);
4333 						b = true;
4334 					}
4335 				} else if(!contains_imaginary(mtest)) {
4336 					CALCULATOR->error(false, "Integral assumed real", NULL);
4337 					b = true;
4338 				}
4339 			}
4340 		}
4341 		if(b) {
4342 			if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4343 				if(fix_sgn_x(*this, x_var, eo_t)) recalc = true;
4344 				while(true) {
4345 					mfound = find_abs_x2(*this, x_var);
4346 					if(mfound) {
4347 						MathStructure m_interval(*mfound);
4348 						m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4349 						CALCULATOR->beginTemporaryStopMessages();
4350 						m_interval.eval(eo_t);
4351 						if(!CALCULATOR->endTemporaryStopMessages()) break;
4352 						if(m_interval.representsNonNegative(true)) {
4353 							replace_abs_x(*this, MathStructure(*mfound), false);
4354 							recalc = true;
4355 						} else if(m_interval.representsNegative(true)) {
4356 							replace_abs_x(*this, MathStructure(*mfound), true);
4357 							recalc = true;
4358 						} else {
4359 							break;
4360 						}
4361 					} else {
4362 						break;
4363 					}
4364 				}
4365 			}
4366 			if(m_type == STRUCT_FUNCTION && CHILD(0).isFunction() && (CHILD(0).function()->id() == FUNCTION_ID_SIN || CHILD(0).function()->id() == FUNCTION_ID_COS) && CHILD(0).size() == 1) {
4367 				MathStructure madd, mmul, mexp;
4368 				if(integrate_info(CHILD(0)[0], x_var, madd, mmul, mexp, true) && mexp.isOne() && madd.isZero()) {
4369 					// abs(sin(ax)): 2/a*floor(ax/pi)-1/a*cos(ax-floor(ax/pi)*pi)
4370 					// abs(cos(ax)): 2/a*floor(ax/pi+1/2)+1/a*sin(ax-floor(ax/pi+1/2)*pi)
4371 					setToChild(1, true);
4372 					MathStructure mdivpi(x_var);
4373 					if(!mmul.isOne()) mdivpi *= mmul;
4374 					mdivpi /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
4375 					if(o_function->id() == FUNCTION_ID_COS) mdivpi += nr_half;
4376 					mdivpi.transformById(FUNCTION_ID_FLOOR);
4377 					if(o_function->id() == FUNCTION_ID_SIN) setFunctionId(FUNCTION_ID_COS);
4378 					else setFunctionId(FUNCTION_ID_SIN);
4379 					CHILD(0) += mdivpi;
4380 					CHILD(0).last() *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
4381 					CHILD(0).last() *= CALCULATOR->getRadUnit();
4382 					CHILD(0).last().negate();
4383 					CHILD(0).childUpdated(CHILD(0).size());
4384 					CHILD_UPDATED(0)
4385 					if(o_function->id() == FUNCTION_ID_COS) negate();
4386 					if(!mmul.isOne()) divide(mmul);
4387 					add(mdivpi);
4388 					LAST *= nr_two;
4389 					if(!mmul.isOne()) LAST /= mmul;
4390 					CHILD_UPDATED(SIZE - 1)
4391 					return true;
4392 				}
4393 			}
4394 			MathStructure mstruct(m_type == STRUCT_POWER ? CHILD(0) : *this);
4395 			if(m_type != STRUCT_POWER || (CHILD(1).isInteger() && !CHILD(1).number().isMinusOne() && CHILD(1).number().isOdd())) {
4396 				MathStructure mexp, mmul, madd;
4397 				if(integrate_info(m_type == STRUCT_POWER ? CHILD(0)[0] : CHILD(0), x_var, madd, mmul, mexp) && mexp.isOne()) {
4398 					MathStructure mpowp1(m_type == STRUCT_POWER ? CHILD(1) : nr_two);
4399 					if(m_type == STRUCT_POWER) {
4400 						mpowp1 += m_one;
4401 						setToChild(1, true);
4402 					}
4403 					MathStructure msgn(*this);
4404 					msgn.setFunctionId(FUNCTION_ID_SIGNUM);
4405 					setToChild(1, true);
4406 					raise(mpowp1);
4407 					divide(mmul);
4408 					divide(mpowp1);
4409 					multiply(msgn);
4410 					return true;
4411 				}
4412 			}
4413 			if(definite_integral) CANNOT_INTEGRATE
4414 			MathStructure mmul;
4415 			MathStructure mbak(*this);
4416 			if(isPower()) {
4417 				mmul = CHILD(0);
4418 				CHILD(0).setToChild(1, true);
4419 				mmul.inverse();
4420 				mmul *= CHILD(0);
4421 			} else {
4422 				mmul = *this;
4423 				setToChild(1, true);
4424 				mmul.inverse();
4425 				mmul *= *this;
4426 			}
4427 			int b_int = integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts);
4428 			if(b_int <= 0) {
4429 				set(mbak);
4430 				if(b_int < 0) CANNOT_INTEGRATE_INTERVAL
4431 				CANNOT_INTEGRATE
4432 			}
4433 			multiply(mmul);
4434 			return true;
4435 		}
4436 	}
4437 	mfound = try_abs ? find_abs_x2(*this, x_var) : NULL;
4438 	if(mfound) {
4439 		MathStructure mtest(*this);
4440 		MathStructure mtest_m(mtest);
4441 		if(!replace_abs_x(mtest, *mfound, false) || !replace_abs_x(mtest_m, *mfound, true)) CANNOT_INTEGRATE
4442 		eo_t.isolate_x = true;
4443 		eo_t.isolate_var = &x_var;
4444 		CALCULATOR->beginTemporaryStopMessages();
4445 		MathStructure mpos(*mfound);
4446 		mpos.transform(COMPARISON_EQUALS_GREATER, m_zero);
4447 		mpos.eval(eo_t);
4448 		UnknownVariable *var_p = NULL, *var_m = NULL;
4449 		if(!CALCULATOR->endTemporaryStopMessages() && mpos.isComparison() && (mpos.comparisonType() == COMPARISON_EQUALS_GREATER || mpos.comparisonType() == COMPARISON_EQUALS_LESS) && mpos[0] == x_var && mpos[1].isNumber()) {
4450 			var_p = new UnknownVariable("", format_and_print(x_var));
4451 			var_m = new UnknownVariable("", format_and_print(x_var));
4452 			Number nr_interval_p, nr_interval_m;
4453 			if(x_var.isVariable() && !x_var.variable()->isKnown() && ((UnknownVariable*) x_var.variable())->interval().isNumber() && ((UnknownVariable*) x_var.variable())->interval().number().isInterval() && ((UnknownVariable*) x_var.variable())->interval().number().isReal() && ((UnknownVariable*) x_var.variable())->interval().number().upperEndPoint().isGreaterThanOrEqualTo(mpos[1].number()) && ((UnknownVariable*) x_var.variable())->interval().number().lowerEndPoint().isLessThanOrEqualTo(mpos[1].number())) {
4454 				if(mpos.comparisonType() == COMPARISON_EQUALS_GREATER) {
4455 					nr_interval_p.setInterval(mpos[1].number(), ((UnknownVariable*) x_var.variable())->interval().number().upperEndPoint());
4456 					nr_interval_m.setInterval(((UnknownVariable*) x_var.variable())->interval().number().lowerEndPoint(), mpos[1].number());
4457 				} else {
4458 					nr_interval_m.setInterval(mpos[1].number(), ((UnknownVariable*) x_var.variable())->interval().number().upperEndPoint());
4459 					nr_interval_p.setInterval(((UnknownVariable*) x_var.variable())->interval().number().lowerEndPoint(), mpos[1].number());
4460 				}
4461 			} else {
4462 
4463 				if(mpos.comparisonType() == COMPARISON_EQUALS_GREATER) {
4464 					nr_interval_p.setInterval(mpos[1].number(), nr_plus_inf);
4465 					nr_interval_m.setInterval(nr_minus_inf, mpos[1].number());
4466 				} else {
4467 					nr_interval_m.setInterval(mpos[1].number(), nr_plus_inf);
4468 					nr_interval_p.setInterval(nr_minus_inf, mpos[1].number());
4469 				}
4470 			}
4471 			var_p->setInterval(nr_interval_p);
4472 			var_m->setInterval(nr_interval_m);
4473 			mtest.replace(x_var, var_p);
4474 			mtest_m.replace(x_var, var_m);
4475 		}
4476 		int bint1 = mtest.integrate(var_p ? var_p : x_var, eo, true, use_abs, true, definite_integral, max_part_depth, parent_parts);
4477 		if(var_p) {
4478 			mtest.replace(var_p, x_var);
4479 			var_p->destroy();
4480 		}
4481 		if(bint1 <= 0 || mtest.containsFunctionId(FUNCTION_ID_INTEGRATE, true) > 0) {
4482 			if(var_m) var_m->destroy();
4483 			if(bint1 < 0) CANNOT_INTEGRATE_INTERVAL
4484 			CANNOT_INTEGRATE;
4485 		}
4486 		int bint2 = mtest_m.integrate(var_m ? var_m : x_var, eo, true, use_abs, false, definite_integral, max_part_depth, parent_parts);
4487 		if(var_m) {
4488 			mtest_m.replace(var_m, x_var);
4489 			var_m->destroy();
4490 		}
4491 		if(bint2 < 0) CANNOT_INTEGRATE_INTERVAL
4492 		if(bint2 == 0 || mtest_m.containsFunctionId(FUNCTION_ID_INTEGRATE, true) > 0) CANNOT_INTEGRATE;
4493 		MathStructure m1(mtest), m2(mtest_m);
4494 		CALCULATOR->beginTemporaryStopMessages();
4495 		MathStructure mzero(*mfound);
4496 		mzero.transform(COMPARISON_EQUALS, m_zero);
4497 		mzero.eval(eo_t);
4498 		if(!CALCULATOR->endTemporaryStopMessages() && mzero.isComparison() && mzero.comparisonType() == COMPARISON_EQUALS && mzero[0] == x_var) {
4499 			mzero.setToChild(2);
4500 			CALCULATOR->beginTemporaryStopMessages();
4501 			m1.calculatesub(eo2, eo2, true);
4502 			m2.calculatesub(eo2, eo2, true);
4503 			m1.evalSort(true, true);
4504 			m2.evalSort(true, true);
4505 			eo_t.test_comparisons = true;
4506 			eo_t.isolate_x = false;
4507 			eo_t.isolate_var = NULL;
4508 			if((definite_integral && m1.equals(m2, true)) || (!definite_integral && try_sign(m1, m2, *mfound, x_var, mzero, eo_t))) {
4509 				set(m1, true);
4510 				CALCULATOR->endTemporaryStopMessages(true);
4511 				return true;
4512 			}
4513 			CALCULATOR->endTemporaryStopMessages();
4514 		}
4515 		/*MathStructure mcmp(*mfound);
4516 		mcmp.transform(COMPARISON_EQUALS_GREATER, m_zero);
4517 		set(mtest);
4518 		multiply(mcmp);
4519 		mcmp.setComparisonType(COMPARISON_LESS);
4520 		mtest_m *= mcmp;
4521 		add(mtest_m);*/
4522 		/*eo2.test_comparisons = true;
4523 		calculatesub(eo2, eo2, true);*/
4524 
4525 		///return true;
4526 	}
4527 
4528 	switch(m_type) {
4529 		case STRUCT_UNIT: {}
4530 		case STRUCT_NUMBER: {
4531 			// a: a*x
4532 			multiply(x_var);
4533 			break;
4534 		}
4535 		case STRUCT_POWER: {
4536 			if(CHILD(1).isNumber() || CHILD(1).containsRepresentativeOf(x_var, true, true) == 0) {
4537 				bool b_minusone = (CHILD(1).isNumber() && CHILD(1).number().isMinusOne());
4538 				MathStructure madd, mmul, mmul2, mexp;
4539 				if(CHILD(0).isFunction()) {
4540 					MathStructure mbase(CHILD(0));
4541 					int bint = integrate_function(mbase, x_var, eo, CHILD(1), m_one, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
4542 					if(bint < 0) CANNOT_INTEGRATE_INTERVAL
4543 					if(bint) {
4544 						set(mbase, true);
4545 						return true;
4546 					}
4547 				} else if(integrate_info(CHILD(0), x_var, madd, mmul, mmul2, false, true)) {
4548 					if(mmul2.isZero()) {
4549 						if(madd.isZero() && mmul.isOne()) {
4550 							if(b_minusone) {
4551 								// x^-1: ln(x)
4552 								if(!transform_absln(CHILD(0), use_abs, definite_integral, x_var, eo)) CANNOT_INTEGRATE_INTERVAL
4553 								SET_CHILD_MAP(0);
4554 							} else {
4555 								// x^a: x^(a+1)/(a+1)
4556 								CHILD(1) += m_one;
4557 								MathStructure mstruct(CHILD(1));
4558 								divide(mstruct);
4559 							}
4560 							return true;
4561 						} else if(b_minusone) {
4562 							// (ax+b)^-1: ln(ax+b)/a
4563 							if(!transform_absln(CHILD(0), use_abs, definite_integral, x_var, eo)) CANNOT_INTEGRATE_INTERVAL
4564 							SET_CHILD_MAP(0);
4565 							if(!mmul.isOne()) divide(mmul);
4566 							return true;
4567 						} else {
4568 							if(definite_integral && !madd.isZero() && (!x_var.representsNonComplex(true) || !mmul.representsNonComplex(true)) && !CHILD(1).representsInteger() && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero)) && !COMPARISON_IS_EQUAL_OR_LESS(madd.compare(m_zero))) CANNOT_INTEGRATE
4569 							// (ax+b)^c: (ax+b)^(c+1)/(a(c+1))
4570 							mexp = CHILD(1);
4571 							mexp += m_one;
4572 							SET_CHILD_MAP(0);
4573 							raise(mexp);
4574 							if(!mmul.isOne()) mexp *= mmul;
4575 							divide(mexp);
4576 							return true;
4577 						}
4578 					} else if(mmul.isZero() && !madd.isZero() && CHILD(1).number().denominatorIsTwo()) {
4579 						MathStructure mmulsqrt2(mmul2);
4580 						if(!mmul2.isOne()) mmulsqrt2 ^= nr_half;
4581 						Number num(CHILD(1).number().numerator());
4582 						if(num.isOne()) {
4583 							// sqrt(ax^2+b): (ln(sqrt(ax^2+b)+x*sqrt(a))*b+sqrt(a)*b*sqrt(ax^2+b))/(2*sqrt(a))
4584 							MathStructure mthis(*this);
4585 							add(x_var);
4586 							if(!mmul2.isOne()) LAST *= mmulsqrt2;
4587 							if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mthis); CANNOT_INTEGRATE_INTERVAL}
4588 							multiply(madd);
4589 							mthis *= x_var;
4590 							if(!mmul2.isOne()) mthis *= mmulsqrt2;
4591 							add(mthis);
4592 							multiply(nr_half);
4593 							if(!mmul2.isOne()) divide(mmulsqrt2);
4594 							childrenUpdated(true);
4595 							return true;
4596 						} else if(num == 3) {
4597 							// (ax^2+b)^(3/2):
4598 							// (ln(sqrt(ax^2+b)+x*sqrt(a))*b^2*3/8+(ax^2+b)^(3/2)*x*sqrt(a)/4+sqrt(ax^2+b)*x*sqrt(a)*b*3/8)/sqrt(a)
4599 							MathStructure mterm3(*this);
4600 							CHILD(1).number().set(1, 2, 0, true);
4601 							MathStructure mterm2(*this);
4602 							add(x_var);
4603 							if(!mmul2.isOne()) LAST *= mmulsqrt2;
4604 							if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mterm3); CANNOT_INTEGRATE_INTERVAL}
4605 							multiply(madd);
4606 							LAST ^= nr_two;
4607 							multiply(Number(3, 8, 0), true);
4608 							mterm2 *= x_var;
4609 							if(!mmul2.isOne()) mterm2 *= mmulsqrt2;
4610 							mterm2 *= madd;
4611 							mterm2 *= Number(3, 8, 0);
4612 							mterm3 *= x_var;
4613 							if(!mmul2.isOne()) mterm3 *= mmulsqrt2;
4614 							mterm3 *= Number(1, 4, 0);
4615 							add(mterm2);
4616 							add(mterm3);
4617 							if(!mmul2.isOne()) divide(mmulsqrt2);
4618 							return true;
4619 						} else if(num == 5) {
4620 							// (ax^2+b)^(5/2):
4621 							// sqrt(ax^2+b)*x^5*a^2/6+ln(sqrt(ax^2+b)*sqrt(a)+ax)*b^3/sqrt(a)*5/16+sqrt(ax^2+b)*x*b^2*11/16+sqrt(ax^2+b)*x^3*b*a*13/24
4622 							CHILD(1).number().set(1, 2, 0, true);
4623 							MathStructure mterm2(*this);
4624 							MathStructure mterm3(*this);
4625 							MathStructure mterm4(*this);
4626 							multiply(x_var);
4627 							LAST ^= Number(5, 1);
4628 							if(!mmul2.isOne()) {
4629 								multiply(mmul2, true);
4630 								LAST ^= nr_two;
4631 							}
4632 							multiply(Number(1, 6), true);
4633 							if(!mmul2.isOne()) mterm2 *= mmulsqrt2;
4634 							mterm2 += x_var;
4635 							if(!mmul2.isOne()) mterm2.last() *= mmul2;
4636 							if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mterm3); CANNOT_INTEGRATE_INTERVAL}
4637 							mterm2 *= madd;
4638 							mterm2.last() ^= nr_three;
4639 							if(!mmul2.isOne()) mterm2 /= mmulsqrt2;
4640 							mterm2 *= Number(5, 16);
4641 							mterm3 *= x_var;
4642 							mterm3 *= madd;
4643 							mterm3.last() ^= nr_two;
4644 							mterm3 *= Number(11, 16);
4645 							mterm4 *= x_var;
4646 							mterm4.last() ^= nr_three;
4647 							mterm4 *= madd;
4648 							if(!mmul2.isOne()) mterm4 *= mmul2;
4649 							mterm4 *= Number(13, 24);
4650 							add(mterm2);
4651 							add(mterm3);
4652 							add(mterm4);
4653 							childrenUpdated(true);
4654 							return true;
4655 						} else if(num.isMinusOne()) {
4656 							// 1/sqrt(ax^2+b): ln(sqrt(ax^2+b)*sqrt(a)+ax)/sqrt(a)
4657 							MathStructure mbak(*this);
4658 							CHILD(1).number().set(1, 2, 0, true);
4659 							if(!mmul2.isOne()) multiply(mmulsqrt2);
4660 							add(x_var);
4661 							if(!mmul2.isOne()) LAST.multiply(mmul2);
4662 							if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
4663 							if(!mmul2.isOne()) divide(mmulsqrt2);
4664 							return true;
4665 						} else if(num == -3) {
4666 							// (ax^2+b)^(-3/2): x/(b*sqrt(ax^2+b))
4667 							CHILD(1).number().set(-1, 2, 0, true);
4668 							madd.inverse();
4669 							multiply(madd);
4670 							multiply(x_var);
4671 							return true;
4672 						} else if(num == -5) {
4673 							// (ax^2+b)^(-5/2): (x(2ax^2+3b)/(3b^2*(ax^2+b)^(3/2))
4674 							CHILD(1).number().set(-3, 2, 0, true);
4675 							mmul = x_var;
4676 							mmul ^= nr_two;
4677 							if(!mmul2.isOne()) mmul *= mmul2;
4678 							mmul *= nr_two;
4679 							mmul += madd;
4680 							mmul.last() *= nr_three;
4681 							multiply(mmul);
4682 							multiply(x_var);
4683 							multiply(madd);
4684 							LAST ^= Number(-2, 1);
4685 							multiply(Number(1, 3));
4686 							return true;
4687 						}
4688 					} else if(b_minusone) {
4689 						// 1/(ax^2+bx+c)
4690 						// y=4ac-b^2
4691 						MathStructure m4acmb2(madd);
4692 						m4acmb2 *= mmul2;
4693 						m4acmb2 *= Number(4, 1);
4694 						m4acmb2 += mmul;
4695 						m4acmb2.last() ^= nr_two;
4696 						m4acmb2.last().negate();
4697 						m4acmb2.calculatesub(eo, eo, true);
4698 						if(!m4acmb2.representsNonZero(true)) {
4699 							if(m4acmb2.isZero()) {
4700 								// y=0: -2/(2ax+b)
4701 								set(x_var, true);
4702 								multiply(mmul2);
4703 								multiply(nr_two, true);
4704 								add(mmul);
4705 								inverse();
4706 								multiply(Number(-2, 1));
4707 								return true;
4708 							} else if(!warn_about_denominators_assumed_nonzero(m4acmb2, eo)) {
4709 								CANNOT_INTEGRATE
4710 							}
4711 						}
4712 						if(m4acmb2.representsNegative(true)) {
4713 							// y<0: ln((2ax+b-sqrt(-4ac+b^2))/(2ax+b+sqrt(-4ac+b^2)))/sqrt(-4ac+b^2)
4714 							MathStructure mbak(*this);
4715 							MathStructure m2axpb(x_var);
4716 							m2axpb *= mmul2;
4717 							m2axpb *= nr_two;
4718 							m2axpb += mmul;
4719 							MathStructure mb2m4ac(madd);
4720 							mb2m4ac *= mmul2;
4721 							mb2m4ac *= Number(-4, 1);
4722 							mb2m4ac += mmul;
4723 							mb2m4ac.last() ^= nr_two;
4724 							mb2m4ac ^= nr_half;
4725 							set(m2axpb);
4726 							subtract(mb2m4ac);
4727 							multiply(m2axpb);
4728 							LAST += mb2m4ac;
4729 							LAST ^= nr_minus_one;
4730 							if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
4731 							divide(mb2m4ac);
4732 							return true;
4733 						}
4734 						// y!=0: 2y*atan((2ax+b)/y^2)
4735 						m4acmb2 ^= Number(-1, 2);
4736 						set(x_var, true);
4737 						multiply(mmul2);
4738 						multiply(nr_two, true);
4739 						add(mmul);
4740 						multiply(m4acmb2);
4741 						transformById(FUNCTION_ID_ATAN);
4742 						multiply(nr_two);
4743 						multiply(m4acmb2, true);
4744 						return true;
4745 					} else if(CHILD(1).isInteger() && CHILD(1).number().isNegative()) {
4746 						// (ax^2+bx+c)^(-n): integral of (ax^2+bx+c)^(-n+1)*(-2a*(-2n+3)*c*a*4+1/(b^(2)*(n-1)))+(2ax+b)*c*a*4+1/b^(2)(ax^2+bx+c)^(-n+1)/(n-1)
4747 						MathStructure m2nm3(CHILD(1));
4748 						m2nm3 *= nr_two;
4749 						m2nm3 += Number(3, 1);
4750 						CHILD(1).number()++;
4751 						MathStructure mnp1(CHILD(1));
4752 						mnp1.number().negate();
4753 						mnp1.number().recip();
4754 						MathStructure mthis(*this);
4755 						if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
4756 						MathStructure m4acmb2(madd);
4757 						m4acmb2 *= mmul2;
4758 						m4acmb2 *= Number(4, 1);
4759 						m4acmb2 += mmul;
4760 						m4acmb2.last() ^= nr_two;
4761 						m4acmb2.last().negate();
4762 						m4acmb2.inverse();
4763 						MathStructure mfac1(mmul2);
4764 						mfac1 *= Number(-2, 1);
4765 						mfac1 *= m2nm3;
4766 						mfac1 *= mnp1;
4767 						mfac1 *= m4acmb2;
4768 						multiply(mfac1);
4769 						MathStructure mterm2(x_var);
4770 						mterm2 *= mmul2;
4771 						mterm2 *= nr_two;
4772 						mterm2 += mmul;
4773 						mterm2 *= m4acmb2;
4774 						mterm2 *= mthis;
4775 						mterm2 *= mnp1;
4776 						add(mterm2);
4777 						return true;
4778 					}
4779 				} else if(integrate_info(CHILD(0), x_var, madd, mmul, mexp, false, false)) {
4780 					if(madd.isZero() && !b_minusone) {
4781 						// (ax^b)^n (n != -1): (ax^b)^n*x/(b*n+1)
4782 						MathStructure mden(mexp);
4783 						mden *= CHILD(1);
4784 						mden += m_one;
4785 						multiply(x_var);
4786 						divide(mden);
4787 						return true;
4788 					} else if(b_minusone && mexp.isNumber() && mexp.number().isNegative() && mexp.number().isInteger()) {
4789 						if(!madd.isZero()) {
4790 							// 1/(ax^(-n)+b): integral of 1/(x^n*b+a)*x^n
4791 							Number nexp(mexp.number());
4792 							nexp.negate();
4793 							MathStructure mtest(x_var);
4794 							mtest ^= nexp;
4795 							mtest *= madd;
4796 							mtest += mmul;
4797 							mtest.inverse();
4798 							mtest *= x_var;
4799 							mtest.last() ^= nexp;
4800 							CALCULATOR->beginTemporaryStopMessages();
4801 							if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
4802 								CALCULATOR->endTemporaryStopMessages(true);
4803 								set(mtest, true);
4804 								return true;
4805 							}
4806 							CALCULATOR->endTemporaryStopMessages();
4807 						}
4808 					} else if(mexp.isNumber() && mexp.number().isRational() && !mexp.number().isInteger()) {
4809 						// (ax^(n/d)+b)^c:
4810 						// integral of (ay^(n=-1?1:n)+b)^c*(y^(sgn(n)/d))^(sgn(n)*d-1) where y=x^(sgn(n)/d) and divide with sgn(n)*d
4811 						Number num(mexp.number().numerator());
4812 						Number den(mexp.number().denominator());
4813 						MathStructure morig(x_var);
4814 						if(num.isNegative()) den.negate();
4815 						Number den_inv(den);
4816 						den_inv.recip();
4817 						morig ^= den_inv;
4818 						UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
4819 						Number den_m1(den);
4820 						den_m1--;
4821 						MathStructure mtest(var);
4822 						if(!num.isOne() && !num.isMinusOne()) mtest ^= num;
4823 						if(!mmul.isOne()) mtest *= mmul;
4824 						if(!madd.isZero()) mtest += madd;
4825 						mtest ^= CHILD(1);
4826 						mtest *= var;
4827 						if(!den_m1.isOne()) {
4828 							mtest.last() ^= den_m1;
4829 							mtest.childUpdated(mtest.size());
4830 						}
4831 						if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4832 							MathStructure m_interval(morig);
4833 							m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4834 							var->setInterval(m_interval);
4835 						} else {
4836 							var->setInterval(morig);
4837 						}
4838 						CALCULATOR->beginTemporaryStopMessages();
4839 						if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
4840 							CALCULATOR->endTemporaryStopMessages(true);
4841 							set(mtest, true);
4842 							replace(var, morig);
4843 							multiply(den);
4844 							var->destroy();
4845 							return true;
4846 						}
4847 						CALCULATOR->endTemporaryStopMessages();
4848 						var->destroy();
4849 					}
4850 				} else if(integrate_info(CHILD(0), x_var, madd, mmul, mexp, false, false, true) && !madd.isZero()) {
4851 					if(mexp.isFunction()) {
4852 						// (a*f(x)+b)^c
4853 						MathStructure mfunc(mexp);
4854 						int bint = integrate_function(mfunc, x_var, eo, CHILD(1), m_one, madd, mmul, use_abs, definite_integral, max_part_depth, parent_parts);
4855 						if(bint < 0) CANNOT_INTEGRATE_INTERVAL
4856 						if(bint) {
4857 							set(mfunc, true);
4858 							return true;
4859 						}
4860 					} else if(mexp.isPower() && mexp[1].containsRepresentativeOf(x_var, true, true) == 0) {
4861 						MathStructure mbase(mexp[0]);
4862 						if(integrate_info(mbase, x_var, madd, mmul, mexp, false, false) && mexp.isOne() && (!madd.isZero() || !mmul.isOne())) {
4863 							// ((ax^c1+b)^c2+b2)^c3: integral of (y^c2+b^2)^c3 where y=ax^c1+b and divide with a
4864 							MathStructure mtest(*this);
4865 
4866 							UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mbase) + RIGHT_PARENTHESIS);
4867 							mtest.replace(mbase, var, mbase.containsInterval());
4868 							if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4869 								MathStructure m_interval(mbase);
4870 								m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4871 								var->setInterval(m_interval);
4872 							} else {
4873 								var->setInterval(mbase);
4874 							}
4875 							CALCULATOR->beginTemporaryStopMessages();
4876 							if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
4877 								CALCULATOR->endTemporaryStopMessages(true);
4878 								set(mtest, true);
4879 								replace(var, mbase);
4880 								if(!mmul.isOne()) divide(mmul);
4881 								var->destroy();
4882 								return true;
4883 							}
4884 							CALCULATOR->endTemporaryStopMessages();
4885 							var->destroy();
4886 						}
4887 					}
4888 				}
4889 				if(CHILD(0).isAddition()) {
4890 					MathStructure mtest(*this);
4891 					// factor base
4892 					if(mtest[0].factorize(eo, false, 0, 0, false, false, NULL, x_var)) {
4893 						mmul = m_one;
4894 						while(mtest[0].isMultiplication() && mtest[0].size() >= 2 && mtest[0][0].containsRepresentativeOf(x_var, true, true) == 0) {
4895 							MathStructure *mchild = &mtest[0][0];
4896 							mchild->ref();
4897 							mtest[0].delChild(1, true);
4898 							if(mtest[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[0].compare(m_zero))) {
4899 								if(mmul.isOne()) mmul = *mchild;
4900 								else mmul *= *mchild;
4901 								mchild->unref();
4902 							} else {
4903 								mtest[0].multiply_nocopy(mchild, true);
4904 							}
4905 						}
4906 						if(!mmul.isOne()) {
4907 							mmul ^= mtest[1];
4908 						}
4909 						MathStructure mtest2(mtest);
4910 						if(mtest2.decomposeFractions(x_var, eo) && mtest2.isAddition()) {
4911 							bool b = true;
4912 							CALCULATOR->beginTemporaryStopMessages();
4913 							for(size_t i = 0; i < mtest2.size(); i++) {
4914 								if(mtest2[i].integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) <= 0) {
4915 									b = false;
4916 									break;
4917 								}
4918 							}
4919 							CALCULATOR->endTemporaryStopMessages(b);
4920 							if(b) {
4921 								set(mtest2, true);
4922 								if(!mmul.isOne()) multiply(mmul);
4923 								return true;
4924 							}
4925 						}
4926 						MathStructure mmul2(1, 1, 0);
4927 						if(mtest[0].isMultiplication() && mtest[0].size() >= 2 && !mtest[0][0].isAddition()) {
4928 							MathStructure *mchild = &mtest[0][0];
4929 							mchild->ref();
4930 							mtest[0].delChild(1, true);
4931 							if(mtest[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[0].compare(m_zero))) {
4932 								mmul2 = *mchild;
4933 								mmul2.calculateRaise(mtest[1], eo2);
4934 								mchild->unref();
4935 							} else {
4936 								mtest[0].multiply_nocopy(mchild, true);
4937 							}
4938 						}
4939 						if(mtest[0].isPower()) {
4940 							if(mtest[1].representsInteger() || mtest[0][1].representsFraction() || COMPARISON_IS_EQUAL_OR_LESS(mtest[0][0].compare(m_zero))) {
4941 								mtest[1].calculateMultiply(mtest[0][1], eo2);
4942 								mtest[0].setToChild(1);
4943 							} else if(mtest[0][1].representsEven()) {
4944 								if(COMPARISON_IS_EQUAL_OR_GREATER(mtest[0][0].compare(m_zero))) {
4945 									mtest[1].calculateMultiply(mtest[0][1], eo2);
4946 									mtest[0].setToChild(1);
4947 									mtest[0].calculateNegate(eo2);
4948 								} else if(!definite_integral && mtest[0][0].representsReal(true)) {
4949 									mtest[1].calculateMultiply(mtest[0][1], eo2);
4950 									mtest[0].setToChild(1);
4951 									mtest[0].transformById(FUNCTION_ID_ABS);
4952 								}
4953 							}
4954 						}
4955 						mtest[0].evalSort(false);
4956 						if(!mmul2.isOne()) {
4957 							mtest *= mmul2;
4958 							mtest.evalSort(false);
4959 						}
4960 						CALCULATOR->beginTemporaryStopMessages();
4961 						if(mtest.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
4962 							CALCULATOR->endTemporaryStopMessages(true);
4963 							set(mtest, true);
4964 							if(!mmul.isOne()) multiply(mmul);
4965 							return true;
4966 						}
4967 						CALCULATOR->endTemporaryStopMessages();
4968 					}
4969 				}
4970 			} else if((CHILD(0).isNumber() && !CHILD(0).number().isOne()) || (!CHILD(0).isNumber() && CHILD(0).containsRepresentativeOf(x_var, true, true) == 0)) {
4971 				MathStructure madd, mmul, mmul2, mexp;
4972 				if(integrate_info(CHILD(1), x_var, madd, mmul, mexp)) {
4973 					if(mexp.isOne()) {
4974 						if(CHILD(0).isVariable() && CHILD(0).variable()->id() == VARIABLE_ID_E) {
4975 							// e^(ax+b): e^(ax+b)/a
4976 							if(!mmul.isOne()) divide(mmul);
4977 							return true;
4978 						} else if(CHILD(0).isNumber() || warn_about_assumed_not_value(CHILD(0), m_one, eo)) {
4979 							// c^(ax+b): c^(ax+b)/(a*ln(c))
4980 							MathStructure mmulfac(CHILD(0));
4981 							mmulfac.transformById(FUNCTION_ID_LOG);
4982 							if(!mmul.isOne()) mmulfac *= mmul;
4983 							divide(mmulfac);
4984 							return true;
4985 						}
4986 					} else if(madd.isZero() || COMPARISON_IS_NOT_EQUAL(madd.compare(m_zero))) {
4987 						if(mmul.representsPositive(true) && COMPARISON_IS_EQUAL_OR_GREATER(CHILD(0).compare(m_one)) && CHILD(0).compare(m_zero) == COMPARISON_RESULT_LESS) {
4988 							madd.negate();
4989 							mmul.negate();
4990 							CHILD(0).inverse();
4991 						}
4992 						if(mexp == nr_two) {
4993 							if(!madd.isZero()) {madd ^= CHILD(0); madd.swapChildren(1, 2);}
4994 							bool mmul_neg = mmul.representsNegative(true);
4995 							if(mmul_neg) mmul.negate();
4996 							if(CHILD(0).isVariable() && CHILD(0).variable()->id() == VARIABLE_ID_E) {
4997 								set(mmul);
4998 								if(!mmul.isOne()) raise(nr_half);
4999 								multiply(x_var);
5000 								if(!mmul_neg) multiply(nr_one_i);
5001 								transformById(FUNCTION_ID_ERF);
5002 								if(!mmul.isOne()) {
5003 									mmul ^= Number(-1, 2);
5004 									multiply(mmul);
5005 								}
5006 								multiply(CALCULATOR->getVariableById(VARIABLE_ID_PI));
5007 								LAST ^= nr_half;
5008 								multiply(nr_half);
5009 								if(!mmul_neg) multiply(nr_minus_i);
5010 							} else {
5011 								MathStructure mlog(CHILD(0));
5012 								mlog.transformById(FUNCTION_ID_LOG);
5013 								mlog ^= nr_half;
5014 								set(mmul);
5015 								if(!mmul.isOne()) raise(nr_half);
5016 								multiply(x_var);
5017 								multiply(mlog);
5018 								if(!mmul_neg) multiply(nr_one_i);
5019 								transformById(FUNCTION_ID_ERF);
5020 								if(!mmul.isOne()) {
5021 									mmul ^= Number(-1, 2);
5022 									multiply(mmul);
5023 								}
5024 								multiply(CALCULATOR->getVariableById(VARIABLE_ID_PI));
5025 								LAST ^= nr_half;
5026 								multiply(nr_half);
5027 								if(!mmul_neg) multiply(nr_minus_i);
5028 								divide(mlog);
5029 							}
5030 							if(!madd.isZero()) multiply(madd);
5031 							return true;
5032 						} else if(mexp.isNumber() && mexp.number().isRational() && !mexp.isInteger()) {
5033 							Number num(mexp.number().numerator());
5034 							Number den(mexp.number().denominator());
5035 							MathStructure morig(x_var);
5036 							Number den_inv(den);
5037 							den_inv.recip();
5038 							morig ^= den_inv;
5039 
5040 							UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
5041 							MathStructure mvar(var);
5042 							if(!num.isOne()) mvar ^= num;
5043 							MathStructure mtest(CHILD(0));
5044 							mtest ^= mvar;
5045 							if(!mmul.isOne()) mtest.last() *= mmul;
5046 							if(!madd.isZero()) mtest.last() += madd;
5047 							mtest.childUpdated(mtest.size());
5048 							Number npow(den);
5049 							npow--;
5050 							mtest *= var;
5051 							if(!npow.isOne()) mtest.last() ^= npow;
5052 							if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5053 								MathStructure m_interval(morig);
5054 								m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5055 								var->setInterval(m_interval);
5056 							} else {
5057 								var->setInterval(morig);
5058 							}
5059 							CALCULATOR->beginTemporaryStopMessages();
5060 							if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5061 								CALCULATOR->endTemporaryStopMessages(true);
5062 								set(mtest, true);
5063 								replace(var, morig);
5064 								multiply(den);
5065 								var->destroy();
5066 								return true;
5067 							}
5068 							CALCULATOR->endTemporaryStopMessages();
5069 							var->destroy();
5070 						}
5071 						// a^(b+cx^d): -x*a^b*(-c*x^d*ln(a))^(-1/d)*igamma(1/d, -c*x^d*ln(a))/d
5072 						if(definite_integral) CANNOT_INTEGRATE
5073 						if(!madd.isZero()) {madd ^= CHILD(0); madd.swapChildren(1, 2);}
5074 						MathStructure mexpinv(mexp);
5075 						mexpinv.inverse();
5076 						MathStructure marg2(CHILD(0));
5077 						marg2.transformById(FUNCTION_ID_LOG);
5078 						marg2 *= x_var;
5079 						marg2.last() ^= mexp;
5080 						marg2 *= mmul;
5081 						marg2.negate();
5082 						set(CALCULATOR->getFunctionById(FUNCTION_ID_I_GAMMA), &mexpinv, &marg2, NULL);
5083 						if(!madd.isZero()) multiply(madd);
5084 						multiply(x_var);
5085 						multiply(mexpinv);
5086 						mexpinv.negate();
5087 						multiply(marg2);
5088 						LAST ^= mexpinv;
5089 						negate();
5090 						return true;
5091 					}
5092 				} else if(integrate_info(CHILD(1), x_var, madd, mmul, mmul2, false, true)) {
5093 					// a^(bx-cx^2+d): sqrt(pi)*a^(b^2/(4c)+d)*erf(sqrt(ln(a))*(2cx-b)/(2*sqrt(c)))/(2*sqrt(c)*sqrt(ln(a))
5094 					MathStructure sqrt2(1, 1, 0);
5095 					if(mmul2.isMinusOne()) {
5096 						mmul2 = m_one;
5097 					} else {
5098 						mmul2.negate();
5099 						sqrt2 = mmul2;
5100 						sqrt2 ^= Number(-1, 2);
5101 					}
5102 					MathStructure loga(1, 1, 0);
5103 					if(CHILD(0) != CALCULATOR->getVariableById(VARIABLE_ID_E)) {loga = CHILD(0); loga.transformById(FUNCTION_ID_LOG);}
5104 					loga ^= nr_half;
5105 					MathStructure merf(x_var);
5106 					if(!mmul2.isOne()) merf *= mmul2;
5107 					merf *= nr_two;
5108 					merf -= mmul;
5109 					if(!loga.isOne()) merf *= loga;
5110 					merf *= nr_half;
5111 					if(!sqrt2.isOne()) merf *= sqrt2;
5112 					merf.transformById(FUNCTION_ID_ERF);
5113 					MathStructure mapow(mmul);
5114 					if(!mapow.isOne()) mapow ^= nr_two;
5115 					mapow *= Number(1, 4);
5116 					if(!mmul2.isOne()) mapow /= mmul2;
5117 					if(!madd.isZero()) mapow += madd;
5118 					SET_CHILD_MAP(0)
5119 					raise(mapow);
5120 					multiply(merf);
5121 					multiply(CALCULATOR->getVariableById(VARIABLE_ID_PI));
5122 					LAST ^= nr_half;
5123 					if(!sqrt2.isOne()) multiply(sqrt2);
5124 					if(!loga.isOne()) divide(loga);
5125 					multiply(nr_half);
5126 					return true;
5127 				}
5128 			}
5129 			CANNOT_INTEGRATE
5130 		}
5131 		case STRUCT_FUNCTION: {
5132 			MathStructure mfunc(*this);
5133 			int bint = integrate_function(mfunc, x_var, eo, m_one, m_one, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
5134 			if(bint < 0) CANNOT_INTEGRATE_INTERVAL
5135 			if(!bint) CANNOT_INTEGRATE
5136 			set(mfunc, true);
5137 			break;
5138 		}
5139 		case STRUCT_MULTIPLICATION: {
5140 			if(combine_powers(*this, x_var, eo2) && m_type != STRUCT_MULTIPLICATION) return integrate(x_var, eo, false, use_abs, definite_integral, try_abs, max_part_depth, parent_parts);
5141 			if(SIZE == 2) {
5142 				if(CHILD(0) != x_var && (CHILD(1) == x_var || (CHILD(1).isPower() && CHILD(1)[0] == x_var))) SWAP_CHILDREN(0, 1);
5143 				if(CHILD(1).isPower() && CHILD(1)[1].containsRepresentativeOf(x_var, true, true) == 0) {
5144 					MathStructure madd, mmul, mmul2;
5145 					MathStructure mexp(CHILD(1)[1]);
5146 					if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mmul2, false, true)) {
5147 						if(mmul2.isZero() && mexp.isNumber()) {
5148 							if(CHILD(0) == x_var) {
5149 								MathStructure mbak(*this);
5150 								SET_CHILD_MAP(1)
5151 								SET_CHILD_MAP(0)
5152 								if(mexp.number().isMinusOne()) {
5153 									MathStructure mterm(x_var);
5154 									if(!mmul.isOne()) mterm /= mmul;
5155 									if(!madd.isZero()) {
5156 										if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5157 										multiply(madd);
5158 										if(!mmul.isOne()) {
5159 											MathStructure a2(mmul);
5160 											a2 ^= nr_two;
5161 											divide(a2);
5162 										}
5163 										negate();
5164 										add(mterm);
5165 									} else {
5166 										set(mterm, true);
5167 									}
5168 								} else if(mexp.number() == -2) {
5169 									MathStructure mterm(*this);
5170 									if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5171 									MathStructure a2(mmul);
5172 									if(!mmul.isOne()) {
5173 										a2 ^= nr_two;
5174 										divide(a2);
5175 									}
5176 									if(!madd.isZero()) {
5177 										if(!mmul.isOne()) mterm *= a2;
5178 										mterm.inverse();
5179 										mterm *= madd;
5180 									}
5181 									add(mterm);
5182 								} else if(mexp.number().isNegative()) {
5183 									MathStructure onemn(1, 1, 0);
5184 									onemn += mexp;
5185 									MathStructure nm1(mexp);
5186 									nm1.negate();
5187 									MathStructure nm2(nm1);
5188 									nm1 += nr_minus_one;
5189 									nm2 += Number(-2, 1);
5190 									raise(nm1);
5191 									multiply(nm2);
5192 									multiply(nm1);
5193 									if(!mmul.isOne()) {
5194 										MathStructure a2(mmul);
5195 										a2 ^= nr_two;
5196 										multiply(a2);
5197 									}
5198 									inverse();
5199 									MathStructure mnum(x_var);
5200 									mnum *= onemn;
5201 									if(!mmul.isOne()) mnum *= mmul;
5202 									if(!madd.isZero()) mnum -= madd;
5203 									multiply(mnum);
5204 								} else {
5205 									MathStructure nm1(mexp);
5206 									nm1 += m_one;
5207 									raise(nm1);
5208 									MathStructure mnum(x_var);
5209 									mnum *= nm1;
5210 									if(!mmul.isOne()) mnum *= mmul;
5211 									mnum -= madd;
5212 									MathStructure mden(mexp);
5213 									mden += nr_two;
5214 									mden *= nm1;
5215 									if(!mmul.isOne()) {
5216 										mden *= mmul;
5217 										mden.last() ^= nr_two;
5218 									}
5219 									multiply(mnum);
5220 									divide(mden);
5221 									return true;
5222 								}
5223 								return true;
5224 							} else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1] == nr_two) {
5225 								MathStructure mbak(*this);
5226 								SET_CHILD_MAP(1)
5227 								SET_CHILD_MAP(0)
5228 								if(mexp.number().isMinusOne()) {
5229 									MathStructure mterm(x_var);
5230 									mterm ^= nr_two;
5231 									if(!mmul.isOne()) mterm *= mmul;
5232 									if(!madd.isZero()) {
5233 										MathStructure mtwobx(-2 ,1, 0);
5234 										mtwobx *= madd;
5235 										mtwobx *= x_var;
5236 										mterm += mtwobx;
5237 									}
5238 									if(!mmul.isOne()) {
5239 										MathStructure a2(mmul);
5240 										a2 ^= nr_two;
5241 										a2 *= nr_two;
5242 										mterm /= a2;
5243 									} else {
5244 										mterm /= nr_two;
5245 									}
5246 									if(!madd.isZero()) {
5247 										if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5248 										MathStructure b2(madd);
5249 										b2 ^= nr_two;
5250 										multiply(b2);
5251 										if(!mmul.isOne()) {
5252 											MathStructure a3(mmul);
5253 											a3 ^= nr_three;
5254 											divide(a3);
5255 										}
5256 										add(mterm);
5257 									} else {
5258 										set(mterm, true);
5259 									}
5260 								} else if(mexp.number() == -2) {
5261 									MathStructure mterm1(x_var);
5262 									if(!mmul.isOne()) mterm1 *= mmul;
5263 									if(!madd.isZero()) {
5264 										MathStructure mterm2(*this);
5265 										if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5266 										mterm2 *= madd;
5267 										mterm2 *= -2;
5268 										MathStructure mterm3(*this);
5269 										mterm3.inverse();
5270 										madd ^= nr_two;
5271 										mterm3 *= madd;
5272 										mterm3.negate();
5273 										set(mterm1);
5274 										add(mterm2);
5275 										add(mterm3);
5276 									} else {
5277 										set(mterm1);
5278 									}
5279 									if(!mmul.isOne()) {
5280 										MathStructure a3(mmul);
5281 										a3 ^= nr_three;
5282 										divide(a3);
5283 									}
5284 								} else if(mexp.number() == -3) {
5285 									if(!madd.isZero()) {
5286 										MathStructure mterm2(*this);
5287 										mterm2.inverse();
5288 										mterm2 *= madd;
5289 										mterm2 *= nr_two;
5290 										MathStructure mterm3(*this);
5291 										mterm3 ^= nr_two;
5292 										mterm3 *= nr_two;
5293 										mterm3.inverse();
5294 										madd ^= nr_two;
5295 										mterm3 *= madd;
5296 										mterm3.negate();
5297 										if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5298 										add(mterm2);
5299 										add(mterm3);
5300 									} else {
5301 										if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5302 									}
5303 									if(!mmul.isOne()) {
5304 										MathStructure a3(mmul);
5305 										a3 ^= nr_three;
5306 										divide(a3);
5307 									}
5308 								} else {
5309 									MathStructure mterm2(*this);
5310 									MathStructure mterm3(*this);
5311 									raise(nr_three);
5312 									CHILD(1) += mexp;
5313 									MathStructure mden(mexp);
5314 									mden += nr_three;
5315 									divide(mden);
5316 									if(!madd.isZero()) {
5317 										mterm2 ^= nr_two;
5318 										mterm2[1] += mexp;
5319 										mterm2 *= madd;
5320 										mterm2 *= -2;
5321 										mden = mexp;
5322 										mden += nr_two;
5323 										mterm2 /= mden;
5324 										mterm3 ^= m_one;
5325 										mterm3[1] += mexp;
5326 										madd ^= nr_two;
5327 										mterm3 *= madd;
5328 										mden = mexp;
5329 										mden += m_one;
5330 										mterm3 /= mden;
5331 										add(mterm2);
5332 										add(mterm3);
5333 									}
5334 									if(!mmul.isOne()) {
5335 										MathStructure a3(mmul);
5336 										a3 ^= nr_three;
5337 										divide(a3);
5338 									}
5339 								}
5340 								return true;
5341 							} else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1] == nr_minus_one && !madd.isZero()) {
5342 								if(mexp.number().isMinusOne()) {
5343 									MathStructure mbak(*this);
5344 									SET_CHILD_MAP(1)
5345 									SET_CHILD_MAP(0)
5346 									divide(x_var);
5347 									if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5348 									divide(madd);
5349 									negate();
5350 									return true;
5351 								}
5352 							} else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1] == -2 && !madd.isZero()) {
5353 								if(mexp.number().isMinusOne()) {
5354 									MathStructure mbak(*this);
5355 									SET_CHILD_MAP(1)
5356 									SET_CHILD_MAP(0)
5357 									divide(x_var);
5358 									if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5359 									MathStructure madd2(madd);
5360 									madd2 ^= nr_two;
5361 									divide(madd2);
5362 									if(!mmul.isOne()) multiply(mmul);
5363 									madd *= x_var;
5364 									madd.inverse();
5365 									subtract(madd);
5366 									return true;
5367 								} else if(mexp.number() == -2) {
5368 									MathStructure mbak(*this);
5369 									SET_CHILD_MAP(1)
5370 									SET_CHILD_MAP(0)
5371 									MathStructure mterm2(madd);
5372 									mterm2 ^= nr_two;
5373 									MathStructure mterm3(mterm2);
5374 									mterm2 *= *this;
5375 									mterm2.inverse();
5376 									divide(x_var);
5377 									if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5378 									MathStructure madd3(madd);
5379 									madd3 ^= nr_three;
5380 									divide(madd3);
5381 									multiply(Number(-2, 1, 0));
5382 									mterm3 *= x_var;
5383 									if(!mmul.isOne()) mterm3 *= mmul;
5384 									mterm3.inverse();
5385 									add(mterm2);
5386 									add(mterm3);
5387 									mmul.negate();
5388 									multiply(mmul);
5389 									return true;
5390 								}
5391 							}
5392 						} else if(mmul.isZero() && !madd.isZero() && mexp.isNumber() && mexp.number().denominatorIsTwo()) {
5393 							Number num(mexp.number());
5394 							if(CHILD(0) == x_var) {
5395 								num.add(1);
5396 								SET_CHILD_MAP(1)
5397 								SET_CHILD_MAP(0)
5398 								raise(num);
5399 								num.multiply(2);
5400 								num.recip();
5401 								multiply(num);
5402 								if(!mmul2.isOne()) divide(mmul2);
5403 								return true;
5404 							} else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isInteger()) {
5405 								if(CHILD(0)[1].number() == 2) {
5406 									if(num == nr_half) {
5407 										MathStructure mbak(*this);
5408 										SET_CHILD_MAP(1)
5409 										MathStructure mterm2(*this);
5410 										if(!mmul2.isOne()) {
5411 											mterm2 *= mmul2;
5412 											mterm2.last() ^= nr_half;
5413 										}
5414 										mterm2 += x_var;
5415 										if(!mmul2.isOne()) mterm2.last() *= mmul2;
5416 										if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5417 										mterm2.multiply(madd);
5418 										mterm2.last() ^= nr_two;
5419 										multiply(x_var);
5420 										if(!mmul2.isOne()) {
5421 											multiply(mmul2);
5422 											LAST ^= nr_half;
5423 										}
5424 										multiply(x_var);
5425 										LAST ^= nr_two;
5426 										if(!mmul2.isOne()) LAST *= mmul2;
5427 										LAST *= nr_two;
5428 										LAST += madd;
5429 										subtract(mterm2);
5430 										multiply(Number(1, 8));
5431 										if(!mmul2.isOne()) {
5432 											multiply(mmul2);
5433 											LAST ^= Number(-3, 2);
5434 										}
5435 										return true;
5436 									}
5437 								} else if(CHILD(0)[1].number() == -1) {
5438 									if(num == nr_minus_half) {
5439 										MathStructure mbak(*this);
5440 										SET_CHILD_MAP(1)
5441 										SET_CHILD_MAP(0)
5442 										raise(nr_half);
5443 										multiply(madd);
5444 										LAST ^= nr_half;
5445 										add(madd);
5446 										transformById(FUNCTION_ID_LOG);
5447 										negate();
5448 										add(x_var);
5449 										if(!transform_absln(LAST, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5450 										multiply(madd);
5451 										LAST ^= nr_minus_half;
5452 										return true;
5453 									} else if(num == nr_half) {
5454 										MathStructure mbak(*this);
5455 										SET_CHILD_MAP(1)
5456 										MathStructure mterm2(*this);
5457 										mterm2 *= madd;
5458 										mterm2.last() ^= nr_half;
5459 										mterm2 += madd;
5460 										mterm2.transformById(FUNCTION_ID_LOG);
5461 										mterm2 *= madd;
5462 										mterm2.last() ^= nr_half;
5463 										MathStructure mterm3(x_var);
5464 										if(!transform_absln(mterm3, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5465 										mterm3 *= madd;
5466 										mterm3.last() ^= nr_half;
5467 										subtract(mterm2);
5468 										add(mterm3);
5469 										return true;
5470 									}
5471 								}
5472 							}
5473 						} else if(mmul2.isZero()) {
5474 							if(CHILD(0) == x_var) {
5475 								SET_CHILD_MAP(1)
5476 								CHILD(1) += m_one;
5477 								MathStructure mnum(x_var);
5478 								mnum *= CHILD(1);
5479 								if(!mmul.isOne()) mnum *= mmul;
5480 								mnum -= madd;
5481 								MathStructure mden(CHILD(1)[0]);
5482 								mden += nr_two;
5483 								mden *= CHILD(1);
5484 								if(!mmul.isOne()) {
5485 									mden *= mmul;
5486 									mden[mden.size() - 1] ^= nr_two;
5487 								}
5488 								multiply(mnum);
5489 								divide(mden);
5490 								return true;
5491 							}
5492 						} else if(mexp.isMinusOne() && CHILD(0) == x_var) {
5493 							MathStructure mbak(*this);
5494 							SET_CHILD_MAP(1)
5495 							MathStructure mterm2(CHILD(0));
5496 							if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
5497 							multiply(mmul);
5498 							divide(mmul2);
5499 							multiply(Number(-1, 2));
5500 							if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5501 							mterm2 /= mmul2;
5502 							mterm2 *= nr_half;
5503 							add(mterm2);
5504 							return true;
5505 						} else if(mexp.isMinusOne() && CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isMinusOne()) {
5506 							MathStructure mbak(*this);
5507 							SET_CHILD_MAP(1)
5508 							MathStructure mterm2(CHILD(0));
5509 							if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
5510 							multiply(mmul);
5511 							divide(madd);
5512 							multiply(Number(-1, 2));
5513 							mterm2.inverse();
5514 							mterm2 *= x_var;
5515 							mterm2.last() ^= nr_two;
5516 							if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5517 							mterm2 /= madd;
5518 							mterm2 *= nr_half;
5519 							add(mterm2);
5520 							return true;
5521 						} else if(mexp.isInteger() && mexp.number().isNegative() && CHILD(0) == x_var) {
5522 							MathStructure mbak(*this);
5523 							SET_CHILD_MAP(1)
5524 							MathStructure m2nm3(CHILD(1));
5525 							m2nm3 *= nr_two;
5526 							m2nm3 += Number(3, 1);
5527 							CHILD(1).number()++;
5528 							MathStructure mnp1(CHILD(1));
5529 							mnp1.number().negate();
5530 							mnp1.number().recip();
5531 							MathStructure mthis(*this);
5532 							if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5533 							MathStructure m4acmb2(madd);
5534 							m4acmb2 *= mmul2;
5535 							m4acmb2 *= Number(4, 1);
5536 							m4acmb2 += mmul;
5537 							m4acmb2.last() ^= nr_two;
5538 							m4acmb2.last().negate();
5539 							m4acmb2.inverse();
5540 							MathStructure mfac1(mmul);
5541 							mfac1 *= m2nm3;
5542 							mfac1 *= mnp1;
5543 							mfac1 *= m4acmb2;
5544 							multiply(mfac1);
5545 							MathStructure mterm2(x_var);
5546 							mterm2 *= mmul;
5547 							mterm2 += madd;
5548 							mterm2.last() *= nr_two;
5549 							mterm2 *= m4acmb2;
5550 							mterm2 *= mthis;
5551 							mterm2 *= mnp1;
5552 							subtract(mterm2);
5553 							return true;
5554 						}
5555 					}
5556 
5557 					if(CHILD(0) == x_var || (CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isRational())) {
5558 						Number nexp(1, 1, 0);
5559 						if(CHILD(0).isPower()) nexp = CHILD(0)[1].number();
5560 						MathStructure madd, mmul, mpow;
5561 						if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mpow, false, false, true)) {
5562 							if(mpow.isPower() && mpow[0] == x_var) {
5563 								mpow.setToChild(2);
5564 								if(mpow.isNumber() && mpow.number().isRational() & !mpow.number().isOne()) {
5565 									if(!nexp.isOne() && mpow.isInteger()) {
5566 										if(mexp.isMinusOne() && nexp.isMinusOne()) {
5567 											MathStructure mbak(*this);
5568 											if(mpow.number().isNegative()) {
5569 												set(x_var, true);
5570 												mpow.number().negate();
5571 												raise(mpow);
5572 												if(!madd.isOne()) multiply(madd);
5573 												add(mmul);
5574 												if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5575 												divide(mpow);
5576 												if(!madd.isOne()) divide(madd);
5577 											} else {
5578 												SET_CHILD_MAP(1)
5579 												SET_CHILD_MAP(0)
5580 												if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5581 												add(x_var);
5582 												if(!transform_absln(LAST, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5583 												LAST *= mpow;
5584 												LAST.negate();
5585 												negate();
5586 												divide(mpow);
5587 												if(!madd.isOne()) divide(madd);
5588 											}
5589 											return true;
5590 										}
5591 										Number mpowmexp(mpow.number());
5592 										mpowmexp -= nexp;
5593 										if(mpowmexp.isOne()) {
5594 											if(mexp.isMinusOne()) {
5595 												MathStructure mbak(*this);
5596 												if(mpow.number().isNegative()) {
5597 													set(x_var, true);
5598 													mpow.number().negate();
5599 													raise(mpow);
5600 													if(!madd.isOne()) multiply(madd);
5601 													add(mmul);
5602 													if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5603 													divide(mpow);
5604 													divide(madd);
5605 													add(x_var);
5606 													if(!transform_absln(LAST, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5607 													LAST.negate();
5608 													divide(mpow);
5609 													divide(madd);
5610 													negate();
5611 												} else {
5612 													SET_CHILD_MAP(1)
5613 													SET_CHILD_MAP(0)
5614 													if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5615 													divide(mpow);
5616 													if(!mmul.isOne()) divide(mmul);
5617 												}
5618 											} else {
5619 												SET_CHILD_MAP(1)
5620 												MathStructure mden(CHILD(1));
5621 												CHILD(1) += m_one;
5622 												mden *= mpow;
5623 												if(!mmul.isOne()) mden *= mmul;
5624 												mden += mpow;
5625 												if(!mmul.isOne()) mden.last() *= mmul;
5626 												divide(mden);
5627 											}
5628 											return true;
5629 										}
5630 									}
5631 									if(x_var.representsNonNegative(true) || mpow.number().isEven() || mpow.number().isFraction()) {
5632 										for(int i = 1; i <= 3; i++) {
5633 											if(i > 1 && (!mpow.isInteger() || !mpow.number().isIntegerDivisible(i) || mpow.number() == i)) break;
5634 											UnknownVariable *var = NULL;
5635 											MathStructure m_replace(x_var);
5636 											MathStructure mtest(CHILD(1));
5637 											Number new_pow(nexp);
5638 											bool b = false;
5639 											if(i == 1) {
5640 												m_replace ^= mpow;
5641 												var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
5642 												mtest.replace(m_replace, var);
5643 												new_pow++;
5644 												new_pow -= mpow.number();
5645 												new_pow /= mpow.number();
5646 												b = true;
5647 											} else if(i == 2) {
5648 												new_pow = nexp;
5649 												new_pow++;
5650 												new_pow -= 2;
5651 												new_pow /= 2;
5652 												if(new_pow.isInteger()) {
5653 													b = true;
5654 													m_replace ^= nr_two;
5655 													var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
5656 													MathStructure m_prev(x_var), m_new(var);
5657 													m_prev ^= mpow;
5658 													m_new ^= mpow;
5659 													m_new[1].number() /= 2;
5660 													mtest.replace(m_prev, m_new);
5661 												}
5662 											} else if(i == 3) {
5663 												new_pow++;
5664 												new_pow -= 3;
5665 												new_pow /= 3;
5666 												if(new_pow.isInteger()) {
5667 													b = true;
5668 													m_replace ^= nr_three;
5669 													var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
5670 													MathStructure m_prev(x_var), m_new(var);
5671 													m_prev ^= mpow;
5672 													m_new ^= mpow;
5673 													m_new[1].number() /= 3;
5674 													mtest.replace(m_prev, m_new);
5675 												}
5676 											}
5677 											if(b) {
5678 												if(!new_pow.isZero()) {
5679 													mtest *= var;
5680 													mtest.swapChildren(1, mtest.size());
5681 													if(!new_pow.isOne()) mtest[0] ^= new_pow;
5682 												}
5683 												CALCULATOR->beginTemporaryStopMessages();
5684 												if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5685 													MathStructure m_interval(m_replace);
5686 													m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5687 													var->setInterval(m_interval);
5688 												} else {
5689 													var->setInterval(m_replace);
5690 												}
5691 												if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
5692 													CALCULATOR->endTemporaryStopMessages(true);
5693 													mtest.replace(var, m_replace);
5694 													set(mtest, true);
5695 													divide(m_replace[1]);
5696 													var->destroy();
5697 													return true;
5698 												}
5699 												CALCULATOR->endTemporaryStopMessages();
5700 												var->destroy();
5701 											}
5702 										}
5703 									}
5704 								}
5705 							} else if(mpow.isPower() && nexp.isInteger() && !madd.isZero() && mpow[1].containsRepresentativeOf(x_var, true, true) == 0) {
5706 								MathStructure mbase(mpow[0]);
5707 								if(integrate_info(mbase, x_var, madd, mmul, mpow, false, false) && mpow.isOne() && (!madd.isZero() || !mmul.isOne())) {
5708 									MathStructure mtest(CHILD(1));
5709 
5710 									UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mbase) + RIGHT_PARENTHESIS);
5711 									mtest.replace(mbase, var, mbase.containsInterval());
5712 									if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5713 										MathStructure m_interval(mbase);
5714 										m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5715 										var->setInterval(m_interval);
5716 									} else {
5717 										var->setInterval(mbase);
5718 									}
5719 									mtest *= var;
5720 									if(!madd.isZero()) {
5721 										mtest.last() -= madd;
5722 										mtest.childUpdated(mtest.size());
5723 									}
5724 									if(!nexp.isOne()) {
5725 										mtest.last() ^= nexp;
5726 										mtest.childUpdated(mtest.size());
5727 									}
5728 									CALCULATOR->beginTemporaryStopMessages();
5729 									if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5730 										CALCULATOR->endTemporaryStopMessages(true);
5731 										set(mtest, true);
5732 										replace(var, mbase);
5733 										if(!mmul.isOne()) {
5734 											nexp++;
5735 											if(!nexp.isOne()) mmul ^= nexp;
5736 											divide(mmul);
5737 										}
5738 										var->destroy();
5739 										return true;
5740 									}
5741 									CALCULATOR->endTemporaryStopMessages();
5742 									var->destroy();
5743 								}
5744 							} /*else if(mpow.isFunction() && mpow.function()->id() == FUNCTION_ID_LOG && mpow.size() == 1 && mpow[0] == x_var) {
5745 								MathStructure mtest(CHILD(1));
5746 								UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mpow) + RIGHT_PARENTHESIS);
5747 								mtest.replace(mpow, var, mpow.containsInterval());
5748 								if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5749 									MathStructure m_interval(mpow);
5750 									m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5751 									var->setInterval(m_interval);
5752 								} else {
5753 									var->setInterval(mpow);
5754 								}
5755 								nexp++;
5756 								mtest *= CALCULATOR->getVariableById(VARIABLE_ID_E);
5757 								mtest.last() ^= nexp;
5758 								mtest.last().last() *= var;
5759 								mmul = CALCULATOR->getVariableById(VARIABLE_ID_E);
5760 								mmul ^= nexp;
5761 								mmul.last() *= Number(-2, 1);
5762 								CALCULATOR->beginTemporaryStopMessages();
5763 								if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5764 									CALCULATOR->endTemporaryStopMessages(true);
5765 									set(mtest, true);
5766 									replace(var, mpow);
5767 									multiply(mmul);
5768 									var->destroy();
5769 									return true;
5770 								}
5771 								CALCULATOR->endTemporaryStopMessages();
5772 								var->destroy();
5773 							}*/
5774 						}
5775 					}
5776 					if(CHILD(0).isPower() && (CHILD(0)[1] == x_var || (CHILD(0)[1].isMultiplication() && CHILD(0)[1].size() >= 2 && CHILD(0)[1].last() == x_var)) && CHILD(0)[0].containsRepresentativeOf(x_var, true, true) == 0) {
5777 						MathStructure mpow, madd, mmul;
5778 						if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mpow, false, false, true) && mpow.isPower() && (mpow[1] == x_var || (mpow[1].isMultiplication() && mpow[1].size() >= 2 && mpow[1].last() == x_var)) && (CHILD(0)[0] == mpow[0] || (CHILD(0)[0].isNumber() && CHILD(0)[0].number().isRational() && mpow[0].isNumber() && mpow[0].number().isRational() && mpow[1] == CHILD(0)[1]))) {
5779 							Number pow1(1, 1), pow2;
5780 							MathStructure morig(mpow);
5781 							bool b  = true;
5782 							if(CHILD(0)[1].isMultiplication()) {
5783 								if(!mpow[1].isMultiplication()) {
5784 									if(CHILD(0)[1].size() != 2 || !CHILD(0)[1][0].isNumber()) b = false;
5785 									else {pow2 = CHILD(0)[1][0].number(); pow2--;}
5786 								} else {
5787 									for(size_t i = 0; i < mpow[1].size() - 1; i++) {
5788 										if(i == 0 && mpow[1][i].isNumber()) {
5789 											pow1 = mpow[1][i].number();
5790 										} else if(CHILD(0)[1][i].containsRepresentativeOf(x_var, true, true) != 0) {
5791 											b = false;
5792 											break;
5793 										}
5794 									}
5795 									if(b) {
5796 										if(mpow[1] == CHILD(0)[1]) {
5797 											pow1.set(1, 1);
5798 										} else if(CHILD(0)[1].size() - (CHILD(0)[1][0].isNumber() ? 1 : 0) != mpow[1].size() - (mpow[1][0].isNumber() ? 1 : 0)) {
5799 											b = false;
5800 										} else if(b) {
5801 											for(size_t i = 0; i < CHILD(0)[1].size() - 1; i++) {
5802 												if(i == 0 && CHILD(0)[1][i].isNumber()) {
5803 													pow2 = CHILD(0)[1][i].number();
5804 													pow2--;
5805 												} else if(CHILD(0)[1][i] != mpow[1][i + (mpow[1][0].isNumber() ? 1 : 0) - (CHILD(0)[1][0].isNumber() ? 1 : 0)]) {
5806 													b = false;
5807 													break;
5808 												}
5809 											}
5810 										}
5811 									}
5812 								}
5813 							} else if(mpow[1].isMultiplication()) {
5814 								if(mpow[1].size() != 2 || !mpow[1][0].isNumber()) b = false;
5815 								else pow1 = mpow[1][0].number();
5816 							}
5817 							if(b && !pow1.isOne()) morig[1].delChild(1, true);
5818 							if(b && CHILD(0)[0] != mpow[0]) {
5819 								bool b1 = CHILD(0)[0].number() < mpow[0].number();
5820 								if(mpow[0].number().isFraction() || CHILD(0)[0].number().isFraction()) b1 = !b1;
5821 								Number nlog(b1 ? mpow[0].number() : CHILD(0)[0].number());
5822 								nlog.log(b1 ? CHILD(0)[0].number() : mpow[0].number());
5823 								if(!nlog.isInteger()) {
5824 									nlog.round();
5825 									b = nlog.isInteger() && (b1 ? ((CHILD(0)[0].number() ^ nlog) == mpow[0].number()) : ((mpow[0].number() ^ nlog) == CHILD(0)[0].number()));
5826 								}
5827 								if(b) {
5828 									if(b1) {
5829 										pow1 = nlog;
5830 										morig = CHILD(0);
5831 									} else {
5832 										pow2 = nlog;
5833 										pow2--;
5834 									}
5835 								}
5836 							}
5837 							if(b) {
5838 								UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
5839 								MathStructure mtest(var);
5840 								if(!pow1.isOne()) mtest ^= pow1;
5841 								if(!mmul.isOne()) mtest *= mmul;
5842 								if(!madd.isZero()) mtest += madd;
5843 								if(!mexp.isOne()) mtest ^= mexp;
5844 								if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5845 									MathStructure m_interval(morig);
5846 									m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5847 									var->setInterval(m_interval);
5848 								} else {
5849 									var->setInterval(morig);
5850 								}
5851 								if(!pow2.isZero()) {
5852 									mtest *= var;
5853 									if(!pow2.isOne()) mtest.last() ^= pow2;
5854 									mtest.swapChildren(1, 2);
5855 								}
5856 								CALCULATOR->beginTemporaryStopMessages();
5857 								if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5858 									CALCULATOR->endTemporaryStopMessages(true);
5859 									set(mtest, true);
5860 									replace(var, morig);
5861 									if(!morig[0].isVariable() || morig[0].variable()->id() != VARIABLE_ID_E) divide_nocopy(new MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &morig[0], NULL));
5862 									if(morig[1].isMultiplication()) {
5863 										morig[1].delChild(morig[1].size(), true);
5864 										divide(morig[1]);
5865 									}
5866 									var->destroy();
5867 									return true;
5868 								}
5869 								CALCULATOR->endTemporaryStopMessages();
5870 								var->destroy();
5871 							}
5872 						}
5873 					}
5874 					if(CHILD(1)[1].number().isMinusOne() && CHILD(1)[0].isMultiplication() && CHILD(1)[0].size() == 2 && CHILD(1)[0][0].isAddition() && CHILD(1)[0][1].isAddition() && (CHILD(0) == x_var || (CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isTwo()))) {
5875 						MathStructure madd1, mmul1, mexp1;
5876 						if(integrate_info(CHILD(1)[0][0], x_var, madd1, mmul1, mexp1) && mexp1.isOne()) {
5877 							MathStructure madd2, mexp2;
5878 							if(integrate_info(CHILD(1)[0][1], x_var, madd2, mmul2, mexp2) && mexp2.isOne()) {
5879 								MathStructure mnum1, mnum2, mx1(madd2), mx2(madd1);
5880 								mx1.negate();
5881 								if(!mmul2.isOne()) mx1 /= mmul2;
5882 								mnum1 = mx1;
5883 								if(!mmul1.isOne()) mx1 *= mmul1;
5884 								mx1 += madd1;
5885 								mnum1 /= mx1;
5886 								mx2.negate();
5887 								if(!mmul1.isOne()) mx2 /= mmul1;
5888 								mnum2 = mx2;
5889 								if(!mmul2.isOne()) mx2 *= mmul2;
5890 								mx2 += madd2;
5891 								mnum2 /= mx2;
5892 								mnum2 /= CHILD(1)[0][0];
5893 								mnum1 /= CHILD(1)[0][1];
5894 								if(CHILD(0) != x_var) {
5895 									mnum1 *= x_var;
5896 									mnum2 *= x_var;
5897 								}
5898 								mnum2 += mnum1;
5899 								CALCULATOR->beginTemporaryStopMessages();
5900 								if(mnum2.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
5901 									CALCULATOR->endTemporaryStopMessages(true);
5902 									set(mnum2, true);
5903 									return true;
5904 								}
5905 								CALCULATOR->endTemporaryStopMessages();
5906 							}
5907 						}
5908 					}
5909 					if(CHILD(1)[0].isAddition()) {
5910 						bool b_poly = false;
5911 						if(CHILD(1)[1].isMinusOne()) {
5912 							MathStructure mquo, mrem;
5913 							b_poly = polynomial_long_division(CHILD(0), CHILD(1)[0], x_var, mquo, mrem, eo, true);
5914 							if(b_poly && !mquo.isZero()) {
5915 								MathStructure mtest(mquo);
5916 								if(!mrem.isZero()) {
5917 									mtest += mrem;
5918 									mtest.last() *= CHILD(1);
5919 									mtest.childrenUpdated();
5920 								}
5921 								CALCULATOR->beginTemporaryStopMessages();
5922 								if(mtest.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
5923 									CALCULATOR->endTemporaryStopMessages(true);
5924 									set(mtest, true);
5925 									return true;
5926 								}
5927 								CALCULATOR->endTemporaryStopMessages();
5928 							}
5929 						}
5930 						MathStructure mtest(*this);
5931 						if(mtest[1][0].factorize(eo, false, 0, 0, false, false, NULL, x_var)) {
5932 							mmul = m_one;
5933 							while(mtest[1][0].isMultiplication() && mtest[1][0].size() >= 2 && mtest[1][0][0].containsRepresentativeOf(x_var, true, true) == 0) {
5934 								MathStructure *mchild = &mtest[1][0][0];
5935 								mchild->ref();
5936 								mtest[1][0].delChild(1, true);
5937 								if(CHILD(1)[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[1][0].compare(m_zero))) {
5938 									if(mmul.isOne()) mmul = *mchild;
5939 									else mmul *= *mchild;
5940 									mchild->unref();
5941 								} else {
5942 									mtest[1][0].multiply_nocopy(mchild, true);
5943 								}
5944 							}
5945 							if(!mmul.isOne()) {
5946 								mmul ^= CHILD(1)[1];
5947 							}
5948 							if(b_poly) {
5949 								MathStructure mtest2(mtest);
5950 								if(mtest2.decomposeFractions(x_var, eo)) {
5951 									if(mtest2.isAddition()) {
5952 										bool b = true;
5953 										CALCULATOR->beginTemporaryStopMessages();
5954 										for(size_t i = 0; i < mtest2.size(); i++) {
5955 											if(mtest2[i].integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) <= 0) {
5956 												b = false;
5957 												break;
5958 											}
5959 										}
5960 										CALCULATOR->endTemporaryStopMessages(b);
5961 										if(b) {
5962 											set(mtest2, true);
5963 											if(!mmul.isOne()) multiply(mmul);
5964 											return true;
5965 										}
5966 									}
5967 								} else {
5968 									mtest2 = mtest[1];
5969 									if(mtest2.decomposeFractions(x_var, eo) && mtest2.isAddition()) {
5970 										if(mtest2.isAddition()) {
5971 											bool b = true;
5972 											CALCULATOR->beginTemporaryStopMessages();
5973 											for(size_t i = 0; i < mtest2.size(); i++) {
5974 												mtest2[i] *= mtest[0];
5975 												if(mtest2[i].integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) <= 0) {
5976 													b = false;
5977 													break;
5978 												}
5979 											}
5980 											CALCULATOR->endTemporaryStopMessages(b);
5981 											if(b) {
5982 												set(mtest2, true);
5983 												if(!mmul.isOne()) multiply(mmul);
5984 												return true;
5985 											}
5986 										}
5987 									}
5988 								}
5989 							}
5990 							mmul2 = m_one;
5991 							if(mtest[1][0].isMultiplication() && mtest[1][0].size() >= 2 && !mtest[1][0][0].isAddition()) {
5992 								MathStructure *mchild = &mtest[1][0][0];
5993 								mchild->ref();
5994 								mtest[1][0].delChild(1, true);
5995 								if(CHILD(1)[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[1][0].compare(m_zero))) {
5996 									mmul2 = *mchild;
5997 									mmul2.calculateRaise(CHILD(1)[1], eo2);
5998 									mchild->unref();
5999 								} else {
6000 									mtest[1][0].multiply_nocopy(mchild, true);
6001 								}
6002 							}
6003 							if(mtest[1][0].isPower()) {
6004 								if(mtest[1][1].representsInteger() || mtest[1][0][1].representsFraction() || COMPARISON_IS_EQUAL_OR_LESS(mtest[1][0][0].compare(m_zero))) {
6005 									mtest[1][1].calculateMultiply(mtest[1][0][1], eo2);
6006 									mtest[1][0].setToChild(1);
6007 								} else if(mtest[1][0][1].representsEven()) {
6008 									if(COMPARISON_IS_EQUAL_OR_GREATER(mtest[1][0][0].compare(m_zero))) {
6009 										mtest[1][1].calculateMultiply(mtest[1][0][1], eo2);
6010 										mtest[1][0].setToChild(1);
6011 										mtest[1][0].calculateNegate(eo2);
6012 									} else if(!definite_integral && mtest[1][0][0].representsReal(true)) {
6013 										mtest[1][1].calculateMultiply(mtest[1][0][1], eo2);
6014 										mtest[1][0].setToChild(1);
6015 										mtest[1][0].transformById(FUNCTION_ID_ABS);
6016 									}
6017 								}
6018 							}
6019 							mtest[1][0].evalSort(false);
6020 							if(!mmul2.isOne()) {
6021 								mtest *= mmul2;
6022 								mtest.evalSort(false);
6023 							}
6024 							CALCULATOR->beginTemporaryStopMessages();
6025 							if(mtest.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
6026 								CALCULATOR->endTemporaryStopMessages(true);
6027 								set(mtest);
6028 								if(!mmul.isOne()) multiply(mmul);
6029 								return true;
6030 							}
6031 							CALCULATOR->endTemporaryStopMessages();
6032 						}
6033 						if(CHILD(1)[1].number().isMinusOne() && CHILD(0) == x_var) {
6034 							if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mmul2, false, true) && !mmul2.isZero() && mmul.isZero() && !madd.isZero()) {
6035 								SET_CHILD_MAP(1)
6036 								SET_CHILD_MAP(0)
6037 								transformById(FUNCTION_ID_LOG);
6038 								mmul2 *= Number(-2, 1);
6039 								multiply(mmul2);
6040 								return true;
6041 							}
6042 						}
6043 					}
6044 				} else if(CHILD(1).isPower() && ((CHILD(1)[0].isNumber() && !CHILD(1)[0].number().isOne()) || (!CHILD(1)[0].isNumber() && CHILD(1)[0].containsRepresentativeOf(x_var, true, true) == 0))) {
6045 					MathStructure mexp(1, 1, 0);
6046 					if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isInteger()) mexp = CHILD(0)[1];
6047 					else if(CHILD(0) != x_var) CANNOT_INTEGRATE;
6048 					MathStructure madd, mmul, mpow;
6049 					if(mexp.number() < 100 && mexp.number() > -100 && integrate_info(CHILD(1)[1], x_var, madd, mmul, mpow, false, false) && mpow.isInteger()) {
6050 						bool b_e = CHILD(1)[0].isVariable() && CHILD(1)[0].variable()->id() == VARIABLE_ID_E;
6051 						if(b_e || CHILD(1)[0].isNumber() || warn_about_assumed_not_value(CHILD(1)[0], m_one, eo)) {
6052 							if(mpow.isOne()) {
6053 								SET_CHILD_MAP(1)
6054 								if(!b_e) {
6055 									if(mmul.isOne()) {
6056 										mmul = CHILD(0);
6057 										mmul.transformById(FUNCTION_ID_LOG);
6058 									} else {
6059 										MathStructure lnbase(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &CHILD(0), NULL);
6060 										mmul *= lnbase;
6061 									}
6062 								}
6063 								if(mexp.isOne()) {
6064 									MathStructure mmulfac(x_var);
6065 									if(!mmul.isOne()) mmulfac *= mmul;
6066 									mmulfac += nr_minus_one;
6067 									multiply(mmulfac);
6068 									if(!mmul.isOne()) {
6069 										mmul ^= Number(-2, 1);;
6070 										multiply(mmul);
6071 									}
6072 								} else if(mexp.number().isTwo()) {
6073 									MathStructure mmulfac(x_var);
6074 									mmulfac ^= nr_two;
6075 									if(!mmul.isOne()) mmulfac /= mmul;
6076 									mmulfac += x_var;
6077 									mmulfac.last() *= Number(-2, 1);
6078 									if(!mmul.isOne()) {
6079 										mmulfac.last() *= mmul;
6080 										mmulfac.last().last() ^= Number(-2, 1);
6081 									}
6082 									mmulfac += nr_two;
6083 									if(!mmul.isOne()) {
6084 										mmulfac.last() *= mmul;
6085 										mmulfac.last().last() ^= Number(-3, 1);
6086 									}
6087 									mmulfac.childrenUpdated(true);
6088 									multiply(mmulfac);
6089 								} else if(mexp.isMinusOne()) {
6090 									if(!madd.isZero()) {
6091 										madd.raise(CHILD(0));
6092 										madd.swapChildren(1, 2);
6093 									}
6094 									set(x_var, true);
6095 									if(!mmul.isOne()) multiply(mmul);
6096 									transformById(FUNCTION_ID_EXPINT);
6097 									if(!madd.isZero()) multiply(madd);
6098 								} else if(mexp.number().isNegative()) {
6099 									MathStructure mterm2(*this);
6100 									mexp += m_one;
6101 									multiply(x_var);
6102 									LAST ^= mexp;
6103 									CHILDREN_UPDATED
6104 									if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
6105 									if(!mmul.isOne()) multiply(mmul);
6106 									mterm2 *= x_var;
6107 									mterm2.last() ^= mexp;
6108 									mterm2.childrenUpdated();
6109 									subtract(mterm2);
6110 									mexp.negate();
6111 									divide(mexp);
6112 								} else {
6113 									MathStructure mterm2(*this);
6114 									multiply(x_var);
6115 									LAST ^= mexp;
6116 									LAST[1] += nr_minus_one;
6117 									LAST.childUpdated(2);
6118 									CHILDREN_UPDATED
6119 									if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
6120 									multiply(mexp);
6121 									if(!mmul.isOne()) divide(mmul);
6122 									negate();
6123 									mterm2 *= x_var;
6124 									mterm2.last() ^= mexp;
6125 									mterm2.childrenUpdated();
6126 									if(!mmul.isOne()) mterm2.divide(mmul);
6127 									add(mterm2);
6128 								}
6129 								return true;
6130 							} else {
6131 								Number mpowmexp(mpow.number());
6132 								mpowmexp -= mexp.number();
6133 								if(mpowmexp.isOne()) {
6134 									SET_CHILD_MAP(1)
6135 									MathStructure malog(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &CHILD(0), NULL);
6136 									divide(mpow);
6137 									if(!mmul.isOne()) divide(mmul);
6138 									if(!b_e) divide(malog);
6139 									return true;
6140 								} else if(mexp.isMinusOne() && mpow.number().isPositive()) {
6141 									MathStructure malog;
6142 									if(b_e) {
6143 										malog = x_var;
6144 										malog ^= mpow;
6145 									} else {
6146 										malog.set(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &CHILD(1)[0], NULL);
6147 										malog *= x_var;
6148 										malog.last() ^= mpow;
6149 									}
6150 									if(!mmul.isOne()) malog *= mmul;
6151 									malog.transformById(FUNCTION_ID_EXPINT);
6152 									if(madd.isZero()) {
6153 										set(malog, true);
6154 									} else {
6155 										SET_CHILD_MAP(1)
6156 										SET_CHILD_MAP(0)
6157 										raise(madd);
6158 										multiply(malog);
6159 									}
6160 									divide(mpow);
6161 									return true;
6162 								}
6163 							}
6164 						}
6165 					}
6166 				}
6167 			}
6168 			if(SIZE >= 2) {
6169 				for(size_t i = 0; i < SIZE; i++) {
6170 					if((CHILD(i).isFunction() && CHILD(i).function()->id() == FUNCTION_ID_SIGNUM) || (CHILD(i).isPower() && CHILD(i)[0].isFunction() && CHILD(i)[0].function()->id() == FUNCTION_ID_SIGNUM)) {
6171 						MathStructure mfunc(CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i));
6172 						MathStructure mmul(*this);
6173 						mmul.delChild(i + 1, true);
6174 						CALCULATOR->beginTemporaryStopMessages();
6175 						int bint = integrate_function(mfunc, x_var, eo, CHILD(i).isPower() ? CHILD(i)[1] : m_one, mmul, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
6176 						CALCULATOR->endTemporaryStopMessages(bint > 0);
6177 						if(bint < 0) CANNOT_INTEGRATE_INTERVAL
6178 						if(bint) {
6179 							set(mfunc, true);
6180 							return true;
6181 						}
6182 					}
6183 				}
6184 				for(size_t i = 0; i < SIZE; i++) {
6185 					if((CHILD(i).isFunction() && CHILD(i).function()->id() != FUNCTION_ID_SIGNUM) || (CHILD(i).isPower() && CHILD(i)[0].isFunction() && CHILD(i)[0].function()->id() != FUNCTION_ID_SIGNUM)) {
6186 						MathStructure mfunc(CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i));
6187 						MathStructure mmul(*this);
6188 						mmul.delChild(i + 1, true);
6189 						CALCULATOR->beginTemporaryStopMessages();
6190 						int bint = integrate_function(mfunc, x_var, eo, CHILD(i).isPower() ? CHILD(i)[1] : m_one, mmul, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
6191 						CALCULATOR->endTemporaryStopMessages(bint > 0);
6192 						if(bint < 0) CANNOT_INTEGRATE_INTERVAL
6193 						if(bint) {
6194 							set(mfunc, true);
6195 							return true;
6196 						}
6197 					}
6198 				}
6199 				MathStructure mbak(*this);
6200 				if(CHILD(0) == x_var || (CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isRational())) {
6201 					Number nexp(1, 1, 0);
6202 					if(CHILD(0).isPower()) nexp = CHILD(0)[1].number();
6203 					MathStructure mpow(1, 1, 0);
6204 					bool b = true;
6205 					MathStructure madd, mmul, mpown;
6206 					for(size_t i = 1; i < SIZE; i++) {
6207 						if(CHILD(i).isFunction() && CHILD(i).size() >= 1) {
6208 							if(!integrate_info(CHILD(i)[0], x_var, madd, mmul, mpown, false, false) || !mpown.isNumber() || !mpown.number().isRational() || mpown.number().isOne() || (!mpow.isOne() && mpow != mpown)) {
6209 								b = false;
6210 								break;
6211 							}
6212 							mpow = mpown;
6213 						} else if(CHILD(i).isPower() && CHILD(i)[1].containsRepresentativeOf(x_var, true, true) == 0) {
6214 							if((CHILD(i)[0].isFunction() && CHILD(i)[0].size() == 1)) {
6215 								if(!integrate_info(CHILD(i)[0][0], x_var, madd, mmul, mpown, false, false)) {b = false; break;}
6216 							} else if(integrate_info(CHILD(i)[0], x_var, madd, mmul, mpown, false, false, true)) {
6217 								if(mpown.isPower() && mpown[0] == x_var) {
6218 									mpown.setToChild(2);
6219 									if(SIZE == 2 && mpown.isInteger()) {b = false; break;}
6220 								} else if(mpown.isFunction() && mpown.size() >= 1) {
6221 									MathStructure marg(mpown[0]);
6222 									if(!integrate_info(marg, x_var, madd, mmul, mpown, false, false)) {b = false; break;	}
6223 								} else {
6224 									b = false; break;
6225 								}
6226 							} else {
6227 								b = false; break;
6228 							}
6229 							if(!mpown.isNumber() || !mpown.number().isRational() || mpown.number().isOne() || (!mpow.isOne() && mpow != mpown)) {
6230 								b = false;
6231 								break;
6232 							}
6233 							mpow = mpown;
6234 						} else if(CHILD(i).isPower() && CHILD(i)[0].containsRepresentativeOf(x_var, true, true) == 0) {
6235 							if(!integrate_info(CHILD(i)[1], x_var, madd, mmul, mpown, false, false) || !mpown.isNumber() || !mpown.number().isRational() || mpown.number().isOne() || (!mpow.isOne() && mpow != mpown)) {
6236 								b = false;
6237 								break;
6238 							}
6239 							mpow = mpown;
6240 						} else {
6241 							b = false;
6242 							break;
6243 						}
6244 					}
6245 					if(b && (x_var.representsNonNegative(true) || mpow.number().isEven() || mpow.number().isFraction())) {
6246 						for(int i = 1; i <= 3; i++) {
6247 							if(!mpow.isInteger()) {
6248 								if(i > 2) break;
6249 							} else if(i > 1 && (!mpow.number().isIntegerDivisible(i) || mpow.number() == i)) {
6250 								break;
6251 							}
6252 							if(CALCULATOR->aborted()) CANNOT_INTEGRATE
6253 							UnknownVariable *var = NULL;
6254 							MathStructure m_replace(x_var);
6255 							MathStructure mtest(*this);
6256 							mtest.delChild(1, true);
6257 							Number new_pow(nexp);
6258 							b = false;
6259 							if(i == 1) {
6260 								m_replace ^= mpow;
6261 								var = new UnknownVariable("", "");
6262 								mtest.replace(m_replace, var);
6263 								new_pow++;
6264 								new_pow -= mpow.number();
6265 								new_pow /= mpow.number();
6266 								b = true;
6267 							} else if(i == 2) {
6268 								if(!mpow.number().isInteger()) {
6269 									Number nden = mpow.number().denominator();
6270 									nden.recip();
6271 									nden--;
6272 									nden.negate();
6273 									new_pow = nexp;
6274 									new_pow += nden;
6275 									new_pow *= mpow.number().denominator();
6276 									if(new_pow.isInteger()) {
6277 										b = true;
6278 										m_replace ^= mpow.number().denominator();
6279 										m_replace[1].number().recip();
6280 										var = new UnknownVariable("", "");
6281 										MathStructure m_prev(x_var), m_new(var);
6282 										m_prev ^= mpow;
6283 										if(!mpow.number().numeratorIsOne()) m_new ^= mpow.number().numerator();
6284 										mtest.replace(m_prev, m_new);
6285 									}
6286 								} else if((mpow.number() / 2).isEven()) {
6287 									new_pow = nexp;
6288 									new_pow++;
6289 									new_pow -= 2;
6290 									new_pow /= 2;
6291 									if(new_pow.isInteger()) {
6292 										b = true;
6293 										m_replace ^= nr_two;
6294 										var = new UnknownVariable("", "");
6295 										MathStructure m_prev(x_var), m_new(var);
6296 										m_prev ^= mpow;
6297 										m_new ^= mpow;
6298 										m_new[1].number() /= 2;
6299 										mtest.replace(m_prev, m_new);
6300 									}
6301 								}
6302 							} else if(i == 3) {
6303 								new_pow++;
6304 								new_pow -= 3;
6305 								new_pow /= 3;
6306 								if(new_pow.isInteger()) {
6307 									b = true;
6308 									m_replace ^= nr_three;
6309 									var = new UnknownVariable("", "");
6310 									MathStructure m_prev(x_var), m_new(var);
6311 									m_prev ^= mpow;
6312 									m_new ^= mpow;
6313 									m_new[1].number() /= 3;
6314 									mtest.replace(m_prev, m_new);
6315 								}
6316 							}
6317 							if(b) {
6318 								if(!new_pow.isZero()) {
6319 									mtest *= var;
6320 									mtest.swapChildren(1, mtest.size());
6321 									if(!new_pow.isOne()) mtest[0] ^= new_pow;
6322 								}
6323 								CALCULATOR->beginTemporaryStopMessages();
6324 								var->setName(string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
6325 								if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
6326 									MathStructure m_interval(m_replace);
6327 									m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
6328 									var->setInterval(m_interval);
6329 								} else {
6330 									var->setInterval(m_replace);
6331 								}
6332 								if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
6333 									CALCULATOR->endTemporaryStopMessages(true);
6334 									mtest.replace(var, m_replace);
6335 									set(mtest, true);
6336 									if(m_replace.isPower()) divide(m_replace[1]);
6337 									var->destroy();
6338 									return true;
6339 								}
6340 								CALCULATOR->endTemporaryStopMessages();
6341 								var->destroy();
6342 							}
6343 						}
6344 					}
6345 				}
6346 
6347 				vector<MathStructure*> parent_parts_pre;
6348 				if(parent_parts) {
6349 					for(size_t i = 0; i < parent_parts->size(); i++) {
6350 						if(equals(*(*parent_parts)[i], true)) CANNOT_INTEGRATE
6351 					}
6352 				} else {
6353 					parent_parts = &parent_parts_pre;
6354 				}
6355 				size_t pp_size = parent_parts->size();
6356 				bool b = false;
6357 
6358 				// integration by parts: u(x)*v(x): u*integral of(v) - integral of (u'(x) * integral of v(x))
6359 				for(size_t i = 0; !b && max_part_depth > 0 && (i < SIZE || (SIZE == 3 && i < SIZE * 2)) && SIZE < 10; i++) {
6360 					if(CALCULATOR->aborted()) CANNOT_INTEGRATE
6361 					CALCULATOR->beginTemporaryStopMessages();
6362 					MathStructure mstruct_u;
6363 					MathStructure mstruct_v;
6364 					MathStructure minteg_v;
6365 
6366 					// select two parts
6367 					if(SIZE == 3 && i >= 3) {
6368 						mstruct_v = CHILD(i - 3);
6369 						mstruct_u = *this;
6370 						mstruct_u.delChild(i - 2);
6371 					} else {
6372 						mstruct_u = CHILD(i);
6373 						if(SIZE == 2 && i == 0) mstruct_v = CHILD(1);
6374 						else if(SIZE == 2 && i == 1) mstruct_v = CHILD(0);
6375 						else {mstruct_v = *this; mstruct_v.delChild(i + 1);}
6376 					}
6377 
6378 					MathStructure mdiff_u(mstruct_u);
6379 					if(mdiff_u.differentiate(x_var, eo2) && mdiff_u.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) <= 0 && (!definite_integral || check_zero_div(mdiff_u, x_var, eo))) {
6380 						minteg_v = mstruct_v;
6381 						if(minteg_v.integrate(x_var, eo, false, use_abs, definite_integral, true, 0, parent_parts) > 0) {
6382 							parent_parts->push_back(this);
6383 							MathStructure minteg_2(minteg_v);
6384 							if(!mdiff_u.isOne()) minteg_2 *= mdiff_u;
6385 							if(minteg_2.countTotalChildren() < 1000) {
6386 								minteg_2.evalSort(true);
6387 								minteg_2.calculateFunctions(eo2);
6388 								minteg_2.calculatesub(eo2, eo2, true);
6389 								combine_ln(minteg_2, x_var, eo2);
6390 								do_simplification(minteg_2, eo2, true, false, false, true, true);
6391 							}
6392 							if(minteg_2.countTotalChildren() < 100 && minteg_2.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0) {
6393 								int cui = contains_unsolved_integrate(minteg_2, this, parent_parts);
6394 								if(cui == 3) {
6395 									MathStructure mfunc(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), this, &m_undefined, &m_undefined, &x_var, &m_zero, NULL);
6396 									UnknownVariable *var = new UnknownVariable("", format_and_print(mfunc));
6397 									var->setAssumptions(mfunc);
6398 									MathStructure mvar(var);
6399 									minteg_2.replace(mfunc, mvar);
6400 									MathStructure msolve(mstruct_u);
6401 									msolve.multiply(minteg_v);
6402 									msolve.evalSort(false);
6403 									msolve.calculatesub(eo2, eo2, true);
6404 									msolve.subtract(minteg_2);
6405 									msolve.evalSort(false);
6406 									msolve.calculatesub(eo2, eo2, true);
6407 									MathStructure msolve_d(msolve);
6408 									if(msolve_d.differentiate(mvar, eo2) && COMPARISON_IS_NOT_EQUAL(msolve_d.compare(m_one))) {
6409 										msolve.transform(COMPARISON_EQUALS, mvar);
6410 										msolve.isolate_x(eo2, mvar);
6411 										if(msolve.isComparison() && msolve.comparisonType() == COMPARISON_EQUALS && msolve[0] == mvar && msolve[1].contains(mvar, true) <= 0) {
6412 											b = true;
6413 											set(msolve[1], true);
6414 										}
6415 									}
6416 									var->destroy();
6417 								} else if(cui != 1) {
6418 									set(mstruct_u);
6419 									multiply(minteg_v);
6420 									subtract(minteg_2);
6421 									b = true;
6422 								}
6423 							}
6424 							parent_parts->pop_back();
6425 						}
6426 					}
6427 					CALCULATOR->endTemporaryStopMessages(b);
6428 				}
6429 				while(parent_parts->size() > pp_size) parent_parts->pop_back();
6430 				if(b) return true;
6431 			}
6432 			CANNOT_INTEGRATE
6433 			break;
6434 		}
6435 		case STRUCT_SYMBOLIC: {
6436 			if(representsNumber(true)) {
6437 				// y: x*y
6438 				multiply(x_var);
6439 			} else {
6440 				CANNOT_INTEGRATE
6441 			}
6442 			break;
6443 		}
6444 		case STRUCT_VARIABLE: {
6445 			if(eo.calculate_variables && o_variable->isKnown()) {
6446 				if(eo.approximation != APPROXIMATION_EXACT || !o_variable->isApproximate()) {
6447 					set(((KnownVariable*) o_variable)->get(), true);
6448 					unformat(eo);
6449 					return integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts);
6450 				} else if(containsRepresentativeOf(x_var, true, true) != 0) {
6451 					CANNOT_INTEGRATE
6452 				}
6453 			}
6454 			// y: x*y
6455 			if(representsNumber(true)) {
6456 				multiply(x_var);
6457 				break;
6458 			}
6459 		}
6460 		default: {
6461 			CANNOT_INTEGRATE
6462 		}
6463 	}
6464 	return true;
6465 }
6466 
6467 // Type 0: Simpson's rule, 1: trapezoid, 2: Simpson's 3/8, 3: Boole's
6468 
numerical_integration(const MathStructure & mstruct,Number & nvalue,const MathStructure & x_var,const EvaluationOptions & eo2,const Number & nr_begin,const Number & nr_end,int i_samples,int type=0)6469 bool numerical_integration(const MathStructure &mstruct, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo2, const Number &nr_begin, const Number &nr_end, int i_samples, int type = 0) {
6470 	if((type == 0 && i_samples % 2 == 1) || (type == 2 && i_samples % 3 == 2) || (type == 3 && i_samples % 4 == 3)) {
6471 		i_samples++;
6472 	} else if((type == 2 && i_samples % 3 == 1) || (type == 3 && i_samples % 4 == 2)) {
6473 		i_samples += 2;
6474 	} else if(type == 3 && i_samples % 4 == 1) {
6475 		i_samples += 3;
6476 	}
6477 	Number nr_step(nr_end);
6478 	nr_step -= nr_begin;
6479 	nr_step /= i_samples;
6480 	MathStructure m_a = mstruct;
6481 	m_a.replace(x_var, nr_begin);
6482 	m_a.eval(eo2);
6483 	if(!m_a.isNumber()) return false;
6484 	nvalue = m_a.number();
6485 	m_a = mstruct;
6486 	m_a.replace(x_var, nr_end);
6487 	m_a.eval(eo2);
6488 	if(!m_a.isNumber()) return false;
6489 	if(!nvalue.add(m_a.number())) return false;
6490 	if(type == 1 && !nvalue.multiply(nr_half)) return false;
6491 	if(type == 3 && !nvalue.multiply(7)) return false;
6492 	for(int i = 1; i < i_samples; i++) {
6493 		if(CALCULATOR->aborted()) {
6494 			return false;
6495 		}
6496 		Number nr(nr_step);
6497 		nr *= i;
6498 		nr += nr_begin;
6499 		MathStructure m_a(mstruct);
6500 		m_a.replace(x_var, nr);
6501 		m_a.eval(eo2);
6502 		if(!m_a.isNumber()) return false;
6503 		if((type == 0 && i % 2 == 0) || (type == 2 && i % 3 == 0)) {
6504 			if(!m_a.number().multiply(nr_two)) return false;
6505 		} else if(type == 0) {
6506 			if(!m_a.number().multiply(4)) return false;
6507 		} else if(type == 2) {
6508 			if(!m_a.number().multiply(nr_three)) return false;
6509 		} else if(type == 3 && i % 4 == 0) {
6510 			if(!m_a.number().multiply(14)) return false;
6511 		} else if(type == 3 && i % 2 == 0) {
6512 			if(!m_a.number().multiply(12)) return false;
6513 		} else if(type == 3) {
6514 			if(!m_a.number().multiply(32)) return false;
6515 		}
6516 		if(!nvalue.add(m_a.number())) return false;
6517 	}
6518 	if(!nvalue.multiply(nr_step)) return false;
6519 	if(type == 0 && !nvalue.multiply(Number(1, 3))) return false;
6520 	if(type == 2 && !nvalue.multiply(Number(3, 8))) return false;
6521 	if(type == 3 && !nvalue.multiply(Number(2, 45))) return false;
6522 	return true;
6523 }
montecarlo(const MathStructure & minteg,Number & nvalue,const MathStructure & x_var,const EvaluationOptions & eo,Number a,Number b,Number n)6524 bool montecarlo(const MathStructure &minteg, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b, Number n) {
6525 	Number range(b); range -= a;
6526 	MathStructure m;
6527 	Number u;
6528 	nvalue.clear();
6529 	vector<Number> v;
6530 	Number i(1, 1);
6531 	while(i <= n) {
6532 		if(CALCULATOR->aborted()) {
6533 			n = i;
6534 			break;
6535 		}
6536 		u.rand();
6537 		u *= range;
6538 		u += a;
6539 		m = minteg;
6540 		m.replace(x_var, u);
6541 		m.eval(eo);
6542 		if(!m.isNumber() || m.number().includesInfinity()) return false;
6543 		if(!m.number().multiply(range)) return false;
6544 		if(!nvalue.add(m.number())) return false;
6545 		v.push_back(m.number());
6546 		i++;
6547 	}
6548 	if(!nvalue.divide(n)) return false;
6549 	Number var;
6550 	for(size_t i = 0; i < v.size(); i++) {
6551 		if(!v[i].subtract(nvalue) || !v[i].square() || !var.add(v[i])) return false;
6552 	}
6553 	if(!var.divide(n) || !var.sqrt()) return false;
6554 	Number nsqrt(n); if(!nsqrt.sqrt() || !var.divide(nsqrt)) return false;
6555 	nvalue.setUncertainty(var);
6556 	return true;
6557 }
has_wide_trig_interval(const MathStructure & m,const MathStructure & x_var,const EvaluationOptions & eo,Number a,Number b)6558 bool has_wide_trig_interval(const MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b) {
6559 	for(size_t i = 0; i < m.size(); i++) {
6560 		if(has_wide_trig_interval(m[i], x_var, eo, a, b)) return true;
6561 	}
6562 	if(m.isFunction() && m.size() == 1 && (m.function()->id() == FUNCTION_ID_SINC || m.function()->id() == FUNCTION_ID_SIN || m.function()->id() == FUNCTION_ID_COS)) {
6563 		Number nr_interval;
6564 		nr_interval.setInterval(a, b);
6565 		MathStructure mtest(m[0]);
6566 		mtest.replace(x_var, nr_interval);
6567 		CALCULATOR->beginTemporaryStopMessages();
6568 		mtest.eval(eo);
6569 		CALCULATOR->endTemporaryStopMessages();
6570 		return mtest.isMultiplication() && mtest.size() >= 1 && mtest[0].isNumber() && (mtest[0].number().uncertainty().realPart() > 100 || mtest[0].number().uncertainty().imaginaryPart() > 100);
6571 	}
6572 	return false;
6573 }
romberg(const MathStructure & minteg,Number & nvalue,const MathStructure & x_var,const EvaluationOptions & eo,Number a,Number b,long int max_steps,long int min_steps,bool safety_measures)6574 bool romberg(const MathStructure &minteg, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b, long int max_steps, long int min_steps, bool safety_measures) {
6575 
6576 	bool auto_max = max_steps <= 0;
6577 	if(auto_max) max_steps = 22;
6578 	if(min_steps > max_steps) max_steps = min_steps;
6579 
6580 	Number R1[max_steps], R2[max_steps];
6581 	Number *Rp = &R1[0], *Rc = &R2[0];
6582 	Number h(b); h -= a;
6583 	Number acc, acc_i, c, ntmp, prevunc, prevunc_i, nunc, nunc_i;
6584 
6585 	nvalue.clear();
6586 
6587 	MathStructure mf(minteg);
6588 	mf.replace(x_var, a);
6589 	mf.eval(eo);
6590 	if(!mf.isNumber() || mf.number().includesInfinity()) {
6591 		if(!a.setToFloatingPoint()) return false;
6592 		mpfr_nextabove(a.internalLowerFloat());
6593 		mpfr_nextabove(a.internalUpperFloat());
6594 		mf = minteg;
6595 		mf.replace(x_var, a);
6596 		mf.eval(eo);
6597 	}
6598 	if(!mf.isNumber()) return false;
6599 	Rp[0] = mf.number();
6600 
6601 	mf = minteg;
6602 	mf.replace(x_var, b);
6603 	mf.eval(eo);
6604 	if(!mf.isNumber() || mf.number().includesInfinity()) {
6605 		if(!b.setToFloatingPoint()) return false;
6606 		mpfr_nextbelow(b.internalLowerFloat());
6607 		mpfr_nextbelow(b.internalUpperFloat());
6608 		mf = minteg;
6609 		mf.replace(x_var, a);
6610 		mf.eval(eo);
6611 	}
6612 	if(!mf.isNumber()) return false;
6613 
6614 	if(!Rp[0].add(mf.number()) || !Rp[0].multiply(nr_half) || !Rp[0].multiply(h)) return false;
6615 
6616 	if(safety_measures && min_steps < 15 && has_wide_trig_interval(minteg, x_var, eo, a, b)) min_steps = (max_steps < 15 ? max_steps : 15);
6617 
6618 	for(long int i = 1; i < max_steps; i++) {
6619 
6620 		if(CALCULATOR->aborted()) break;
6621 
6622 		if(!h.multiply(nr_half)) return false;
6623 
6624 		c.clear();
6625 
6626 		long int ep = 1 << (i - 1);
6627 		ntmp = a; ntmp += h;
6628 		for(long int j = 1; j <= ep; j++){
6629 			if(CALCULATOR->aborted()) break;
6630 			mf = minteg;
6631 			mf.replace(x_var, ntmp);
6632 			mf.eval(eo);
6633 			if(CALCULATOR->aborted()) break;
6634 			if(!mf.isNumber() || mf.number().includesInfinity()) {
6635 				Number ntmp2(ntmp);
6636 				if(ntmp2.setToFloatingPoint()) return false;
6637 				if(j % 2 == 0) {mpfr_nextabove(ntmp2.internalLowerFloat()); mpfr_nextabove(ntmp2.internalUpperFloat());}
6638 				else {mpfr_nextbelow(ntmp2.internalLowerFloat()); mpfr_nextbelow(ntmp2.internalUpperFloat());}
6639 				mf = minteg;
6640 				mf.replace(x_var, ntmp2);
6641 				mf.eval(eo);
6642 				if(CALCULATOR->aborted()) break;
6643 			}
6644 			if(!mf.isNumber() || !c.add(mf.number())) return false;
6645 			ntmp += h; ntmp += h;
6646 		}
6647 		if(CALCULATOR->aborted()) break;
6648 
6649 		Rc[0] = h;
6650 		ntmp = Rp[0];
6651 		if(!ntmp.multiply(nr_half) || !Rc[0].multiply(c) || !Rc[0].add(ntmp)) return false;
6652 
6653 		for(long int j = 1; j <= i; ++j){
6654 			if(CALCULATOR->aborted()) break;
6655 			ntmp = 4;
6656 			ntmp ^= j;
6657 			Rc[j] = ntmp;
6658 			ntmp--; ntmp.recip();
6659 			if(!Rc[j].multiply(Rc[j - 1]) || !Rc[j].subtract(Rp[j - 1]) || !Rc[j].multiply(ntmp)) return false;
6660 		}
6661 		if(CALCULATOR->aborted()) break;
6662 
6663 		if(i >= min_steps - 1 && !Rp[i - 1].includesInfinity() && !Rc[i].includesInfinity()) {
6664 			if(Rp[i - 1].hasImaginaryPart()) nunc = Rp[i - 1].realPart();
6665 			else nunc = Rp[i - 1];
6666 			if(Rc[i].hasImaginaryPart()) nunc -= Rc[i].realPart();
6667 			else nunc -= Rc[i];
6668 			nunc.abs();
6669 			if(safety_measures) nunc *= 10;
6670 			nunc.intervalToMidValue();
6671 			if(Rp[i - 1].hasImaginaryPart() || Rc[i].hasImaginaryPart()) {
6672 				nunc_i = Rp[i - 1].imaginaryPart();
6673 				nunc_i -= Rc[i].imaginaryPart();
6674 				nunc_i.abs();
6675 			} else {
6676 				nunc_i.clear();
6677 			}
6678 			if(safety_measures) nunc_i *= 10;
6679 			nunc_i.intervalToMidValue();
6680 			long int prec = PRECISION + (auto_max ? 3 : 1);
6681 			if(auto_max) {
6682 				if(i > 10) prec += 10 - ((!prevunc.isZero() || !prevunc_i.isZero()) ? i - 1 : i);
6683 				if(prec < 4) prec = 4;
6684 			}
6685 			acc.set(1, 1, -prec);
6686 			ntmp = Rc[i - 1];
6687 			ntmp.intervalToMidValue();
6688 			if(ntmp.hasImaginaryPart()) {
6689 				if(ntmp.hasRealPart()) acc *= ntmp.realPart();
6690 			} else {
6691 				if(!ntmp.isZero()) acc *= ntmp;
6692 			}
6693 			acc.abs();
6694 			acc.intervalToMidValue();
6695 			nvalue = Rc[i - 1];
6696 			if(nunc <= acc) {
6697 				if(!nunc_i.isZero()) {
6698 					acc_i.set(1, 1, -prec);
6699 					if(ntmp.hasImaginaryPart()) acc_i *= ntmp.imaginaryPart();
6700 					acc_i.abs();
6701 					acc_i.intervalToMidValue();
6702 					if(nunc_i <= acc_i) {
6703 						if(!safety_measures) {
6704 							nunc.setImaginaryPart(nunc_i);
6705 							nvalue.setUncertainty(nunc);
6706 							return true;
6707 						}
6708 						if(!prevunc.isZero() || !prevunc_i.isZero() || (nunc.isZero() && nunc_i.isZero())) {
6709 							if(nunc <= prevunc && nunc_i <= prevunc_i) {
6710 								if(!ntmp.hasRealPart()) prevunc = acc;
6711 								if(!ntmp.hasImaginaryPart()) prevunc.setImaginaryPart(acc_i);
6712 								else prevunc.setImaginaryPart(prevunc_i);
6713 								nvalue.setUncertainty(prevunc);
6714 							} else {
6715 								acc.setImaginaryPart(acc_i);
6716 								nvalue.setUncertainty(acc);
6717 							}
6718 							return true;
6719 						}
6720 						prevunc = nunc;
6721 						prevunc_i = nunc_i;
6722 					} else {
6723 						prevunc.clear();
6724 						prevunc_i.clear();
6725 					}
6726 				} else {
6727 					if(!safety_measures) {
6728 						nvalue.setUncertainty(nunc);
6729 						return true;
6730 					}
6731 					if(!prevunc.isZero() || nunc.isZero()) {
6732 						if(!prevunc_i.isZero()) nunc.setImaginaryPart(prevunc_i);
6733 						if(!ntmp.isZero() && nunc <= prevunc) nvalue.setUncertainty(prevunc);
6734 						else nvalue.setUncertainty(acc);
6735 						return true;
6736 					}
6737 					prevunc = nunc;
6738 					prevunc_i = nunc_i;
6739 				}
6740 			} else {
6741 				prevunc.clear();
6742 				prevunc_i.clear();
6743 			}
6744 		}
6745 
6746 		Number *rt = Rp;
6747 		Rp = Rc;
6748 		Rc = rt;
6749 	}
6750 	if(!nunc.isZero() || !nunc_i.isZero()) {
6751 		acc.set(1, 1, auto_max ? -3 : -2);
6752 		ntmp = nvalue;
6753 		ntmp.intervalToMidValue();
6754 		if(ntmp.hasImaginaryPart()) {
6755 			if(ntmp.hasRealPart()) acc *= ntmp.realPart();
6756 		} else {
6757 			if(!ntmp.isZero()) acc *= ntmp;
6758 		}
6759 		acc.abs();
6760 		acc.intervalToMidValue();
6761 		if(nunc > acc) return false;
6762 		if(!ntmp.hasRealPart()) nunc = acc;
6763 		if(!nunc_i.isZero()) {
6764 			acc.set(1, 1, -3);
6765 			if(ntmp.hasImaginaryPart()) acc *= ntmp.imaginaryPart();
6766 			acc.abs();
6767 			acc.intervalToMidValue();
6768 			if(nunc_i > acc) return false;
6769 			if(ntmp.hasImaginaryPart()) nunc.setImaginaryPart(nunc_i);
6770 			else nunc.setImaginaryPart(acc);
6771 		}
6772 		if(safety_measures) nunc *= 10;
6773 		nvalue.setUncertainty(nunc);
6774 		return true;
6775 	}
6776 	return false;
6777 }
numerical_integration_part(const MathStructure & minteg,const MathStructure & x_var,const MathStructure & merr_pre,const MathStructure & merr_diff,KnownVariable * v,Number & nvalue,EvaluationOptions & eo,const Number & nr,int type=0,int depth=0,bool nzerodiff=false)6778 int numerical_integration_part(const MathStructure &minteg, const MathStructure &x_var, const MathStructure &merr_pre, const MathStructure &merr_diff, KnownVariable *v, Number &nvalue, EvaluationOptions &eo, const Number &nr, int type = 0, int depth = 0, bool nzerodiff = false) {
6779 	if(CALCULATOR->aborted()) return 0;
6780 	eo.interval_calculation = INTERVAL_CALCULATION_NONE;
6781 	MathStructure merr(merr_pre);
6782 	int i_ret = 1;
6783 	v->set(nr);
6784 	bool do_parts = true;
6785 	/*if(nzerodiff) {
6786 		v->set(nr.lowerEndPoint());
6787 		MathStructure mlow(merr);
6788 		mlow.eval(eo);
6789 		v->set(nr.upperEndPoint());
6790 		merr.eval(eo);
6791 		if(!merr.isNumber() || !mlow.isNumber() || merr.number().includesInfinity() || mlow.number().includesInfinity()) return 0;
6792 		merr.number().setInterval(mlow.number(), merr.number());
6793 		do_parts = false;
6794 	} else if(depth > 1 && !merr_diff.isUndefined()) {
6795 		CALCULATOR->beginTemporaryStopMessages();
6796 		MathStructure mzero(merr_diff);
6797 		mzero.eval(eo);
6798 		if(CALCULATOR->endTemporaryStopMessages() == 0 && mzero.isNumber() && mzero.number().isNonZero() && (!mzero.number().hasImaginaryPart() || mzero.number().internalImaginary()->isNonZero())) {
6799 			v->set(nr.lowerEndPoint());
6800 			MathStructure mlow(merr);
6801 			mlow.eval(eo);
6802 			v->set(nr.upperEndPoint());
6803 			merr.eval(eo);
6804 			if(!merr.isNumber() || !mlow.isNumber() || merr.number().includesInfinity() || mlow.number().includesInfinity()) return 0;
6805 			merr.number().setInterval(mlow.number(), merr.number());
6806 			do_parts = false;
6807 			nzerodiff = true;
6808 		}
6809 	}*/
6810 	if(depth > 0 && do_parts) {
6811 		CALCULATOR->beginTemporaryStopMessages();
6812 		merr.eval(eo);
6813 		do_parts = (CALCULATOR->endTemporaryStopMessages() > 0 || !merr.isNumber() || merr.number().includesInfinity());
6814 	}
6815 	if(do_parts) {
6816 		integrate_parts:
6817 		if(depth > 4) {
6818 			if(numerical_integration(minteg, nvalue, x_var, eo, nr.lowerEndPoint(), nr.upperEndPoint(), 1002, type)) {nvalue.setApproximate(); return -1;}
6819 			return 0;
6820 		}
6821 		vector<Number> parts;
6822 		nr.splitInterval(depth == 0 ? 5 : 5, parts);
6823 		nvalue.clear();
6824 		Number n_i;
6825 		for(size_t i = 0; i < parts.size(); i++) {
6826 			int i_reti = numerical_integration_part(minteg, x_var, merr_pre, merr_diff, v, n_i, eo, parts[i], type, depth + 1, nzerodiff);
6827 			if(i_reti != 0) {
6828 				if(i_reti < i_ret) i_ret = i_reti;
6829 				if(!nvalue.add(n_i)) return false;
6830 			} else {
6831 				return 0;
6832 			}
6833 		}
6834 		return i_ret;
6835 	} else {
6836 		CALCULATOR->beginTemporaryStopIntervalArithmetic();
6837 		eo.interval_calculation = INTERVAL_CALCULATION_NONE;
6838 		Number nr_interval(merr.number());
6839 		Number nr_interval_abs;
6840 		Number nr1(nr_interval.upperEndPoint(true));
6841 		Number nr2(nr_interval.lowerEndPoint(true));
6842 		nr1.abs();
6843 		nr2.abs();
6844 		if(nr1.isGreaterThan(nr2)) nr_interval_abs = nr1;
6845 		else nr_interval_abs = nr2;
6846 		if(merr.number().hasImaginaryPart()) {
6847 			if(merr.number().hasRealPart()) {
6848 				nr1 = merr.number().realPart().upperEndPoint();
6849 				nr2 = merr.number().realPart().lowerEndPoint();
6850 				nr1.abs();
6851 				nr2.abs();
6852 				if(nr1.isGreaterThan(nr2)) nr_interval = nr1;
6853 				else nr_interval = nr2;
6854 				nr1 = merr.number().imaginaryPart().upperEndPoint();
6855 				nr2 = merr.number().imaginaryPart().lowerEndPoint();
6856 				nr1.abs();
6857 				nr2.abs();
6858 				if(nr1.isGreaterThan(nr2)) nr_interval.setImaginaryPart(nr1);
6859 				else nr_interval.setImaginaryPart(nr2);
6860 			} else {
6861 				nr_interval.setImaginaryPart(nr_interval_abs);
6862 			}
6863 		} else {
6864 			nr_interval = nr_interval_abs;
6865 		}
6866 		Number nr_samples(6, 1);
6867 		Number nr_range(nr.upperEndPoint());
6868 		nr_range -= nr.lowerEndPoint();
6869 		int i_run = 0;
6870 		while(true) {
6871 			if(CALCULATOR->aborted()) {CALCULATOR->endTemporaryStopIntervalArithmetic(); return 0;}
6872 			if(numerical_integration(minteg, nvalue, x_var, eo, nr.lowerEndPoint(), nr.upperEndPoint(), nr_samples.intValue(), type)) {
6873 				if(nr.includesInfinity()) {
6874 					CALCULATOR->endTemporaryStopIntervalArithmetic();
6875 					return 0;
6876 				}
6877 				Number nr_prec(nr_range);
6878 				if(type == 0 || type == 2) {
6879 					nr_prec /= nr_samples;
6880 					nr_prec ^= 4;
6881 					nr_prec *= nr_range;
6882 					nr_prec /= (type == 2 ? 80 : 180);
6883 				} else if(type == 1) {
6884 					nr_prec /= nr_samples;
6885 					nr_prec ^= 2;
6886 					nr_prec *= nr_range;
6887 					nr_prec /= 12;
6888 				} else if(type == 3) {
6889 					nr_prec ^= 7;
6890 					//nr_prec *= Number(8, 945); ?
6891 					nr_prec /= (nr_samples ^ 6);
6892 				}
6893 				nr_prec *= nr_interval;
6894 				Number nr_prec_abs(nr_prec);
6895 				nr_prec_abs.abs();
6896 				Number mabs(nvalue);
6897 				mabs.abs();
6898 				Number max_error(1, 1, -(PRECISION + 1 - (i_run * 2)));
6899 				max_error *= mabs;
6900 				if(nr_prec_abs >= max_error) {
6901 					for(int i = 0; ; i++) {
6902 						if(type == 0 || type == 2) {
6903 							nr_samples = nr_range;
6904 							nr_samples ^= 5;
6905 							nr_samples /= (type == 2 ? 80 : 180);
6906 							nr_samples *= nr_interval_abs;
6907 							nr_samples /= max_error;
6908 							nr_samples.root(4);
6909 						} else if(type == 3) {
6910 							nr_samples = nr_range;
6911 							nr_samples ^= 7;
6912 							//nr_samples *= Number(8, 945); ?
6913 							nr_samples *= nr_interval_abs;
6914 							nr_samples /= max_error;
6915 							nr_samples.root(6);
6916 						} else {
6917 							nr_samples = nr_range;
6918 							nr_samples ^= 3;
6919 							nr_samples /= 12;
6920 							nr_samples *= nr_interval_abs;
6921 							nr_samples /= max_error;
6922 							nr_samples.sqrt();
6923 						}
6924 						nr_samples.intervalToMidValue();
6925 						nr_samples.ceil();
6926 						if(type == 0 && nr_samples.isOdd()) {
6927 							nr_samples++;
6928 						} else if(type == 2 && !nr_samples.isIntegerDivisible(3)) {
6929 							Number nmod(nr_samples);
6930 							nmod.mod(3);
6931 							if(nmod == 1) nr_samples += 2;
6932 							else nr_samples += 1;
6933 						} else if(type == 3 && !nr_samples.isIntegerDivisible(4)) {
6934 							Number nmod(nr_samples);
6935 							nmod.mod(4);
6936 							if(nmod == 1) nr_samples += 3;
6937 							if(nmod == 2) nr_samples += 2;
6938 							else nr_samples += 1;
6939 						}
6940 						if(nr_samples < 10000) break;
6941 						i_run++;
6942 						if(depth <= 3 && PRECISION + 1 - (i_run * 2) < (PRECISION > 10 ? 10 : PRECISION) - depth) goto integrate_parts;
6943 						if(PRECISION + 1 - (i_run * 2) < 5) {
6944 							if(nr_samples < 50000) break;
6945 							if(PRECISION + 1 - (i_run * 2) < 2 - depth) {
6946 								if(numerical_integration(minteg, nvalue, x_var, eo, nr.lowerEndPoint(), nr.upperEndPoint(), 1002, type)) {nvalue.setApproximate(); return -1;}
6947 								return 0;
6948 							}
6949 						}
6950 						max_error *= Number(1, 1, (PRECISION + 1 - ((i_run - 1) * 2)));
6951 						max_error *= Number(1, 1, -(PRECISION + 1 - (i_run * 2)));
6952 					}
6953 				} else {
6954 					CALCULATOR->endTemporaryStopIntervalArithmetic();
6955 					nvalue.setUncertainty(nr_prec);
6956 					return 1;
6957 				}
6958 			} else {
6959 				CALCULATOR->endTemporaryStopIntervalArithmetic();
6960 				return 0;
6961 			}
6962 			i_run++;
6963 		}
6964 	}
6965 	return 0;
6966 }
contains_complex(const MathStructure & mstruct)6967 bool contains_complex(const MathStructure &mstruct) {
6968 	if(mstruct.isNumber()) return mstruct.number().isComplex();
6969 	if(mstruct.isVariable() && mstruct.variable()->isKnown()) return contains_complex(((KnownVariable*) mstruct.variable())->get());
6970 	for(size_t i = 0; i < mstruct.size(); i++) {
6971 		if(contains_complex(mstruct[i])) return true;
6972 	}
6973 	return false;
6974 }
6975 
check_denominators(const MathStructure & m,const MathStructure & mi,const MathStructure & mx,const EvaluationOptions & eo)6976 bool check_denominators(const MathStructure &m, const MathStructure &mi, const MathStructure &mx, const EvaluationOptions &eo) {
6977 	if(m.contains(mx, false, true, true) == 0) return true;
6978 	for(size_t i = 0; i < m.size(); i++) {
6979 		if(!check_denominators(m[i], mi, mx, eo)) return false;
6980 	}
6981 	if(m.isPower()) {
6982 		bool b_neg = m[1].representsNegative();
6983 		if(!m[1].representsNonNegative()) {
6984 			if(!m[0].representsNonZero()) {
6985 				EvaluationOptions eo2 = eo;
6986 				eo2.approximation = APPROXIMATION_APPROXIMATE;
6987 				eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
6988 				CALCULATOR->beginTemporaryStopMessages();
6989 				KnownVariable *v = new KnownVariable("", "v", mi);
6990 				MathStructure mpow(m[1]);
6991 				mpow.replace(mx, v, true);
6992 				mpow.eval(eo2);
6993 				b_neg = mpow.representsNegative();
6994 				CALCULATOR->endTemporaryStopMessages();
6995 				v->destroy();
6996 			}
6997 		}
6998 		if(b_neg && !m[0].representsNonZero()) {
6999 			if(m[0].isZero()) return false;
7000 			EvaluationOptions eo2 = eo;
7001 			eo2.approximation = APPROXIMATION_APPROXIMATE;
7002 			eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
7003 			CALCULATOR->beginTemporaryStopMessages();
7004 			MathStructure mbase(m[0]);
7005 			KnownVariable *v = new KnownVariable("", "v", mi);
7006 			mbase.replace(mx, v, true);
7007 			bool b_multiple = mbase.contains(mx, true) > 0;
7008 			if(b_multiple) mbase.replace(mx, v);
7009 			mbase.eval(eo2);
7010 			CALCULATOR->endTemporaryStopMessages();
7011 			/*if(mbase.isZero()) {
7012 				v->destroy(); return false;
7013 			} else if(!b_multiple && mbase.isNumber()) {
7014 				if(!mbase.number().isNonZero()) {v->destroy(); return false;}
7015 			} else if(!mbase.isNumber() || !mbase.number().isNonZero()) {
7016 				CALCULATOR->beginTemporaryStopMessages();
7017 				eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
7018 				mbase = m[0];
7019 				mbase.replace(mx, v);
7020 				mbase.eval(eo2);
7021 				CALCULATOR->endTemporaryStopMessages();
7022 			}*/
7023 			if(mbase.isZero()) {
7024 				v->destroy(); return false;
7025 			} else if(!b_multiple && mbase.isNumber()) {
7026 				if(!mbase.number().isNonZero()) {v->destroy(); return false;}
7027 			} else if(!mbase.isNumber() || !mbase.number().isNonZero()) {
7028 				CALCULATOR->beginTemporaryStopMessages();
7029 				mbase = m[0];
7030 				eo2.isolate_x = true;
7031 				eo2.isolate_var = &mx;
7032 				eo2.test_comparisons = true;
7033 				eo2.approximation = APPROXIMATION_EXACT;
7034 				mbase.transform(COMPARISON_NOT_EQUALS, m_zero);
7035 				mbase.eval(eo2);
7036 				eo2.approximation = APPROXIMATION_APPROXIMATE;
7037 				eo2.isolate_x = false;
7038 				eo2.isolate_var = NULL;
7039 				if(!mbase.isNumber()) {
7040 					MathStructure mtest(mbase);
7041 					mtest.replace(mx, v);
7042 					mtest.eval(eo2);
7043 					if(mtest.isNumber()) mbase = mtest;
7044 				}
7045 				CALCULATOR->endTemporaryStopMessages();
7046 				if(!mbase.isOne()) {
7047 					if(mbase.isZero()) {v->destroy(); return false;}
7048 					bool b = false;
7049 					if(mbase.isComparison()) {
7050 						CALCULATOR->beginTemporaryStopMessages();
7051 						mbase[0].eval(eo2); mbase[1].eval(eo2);
7052 						CALCULATOR->endTemporaryStopMessages();
7053 					}
7054 					if(mbase.isComparison() && mbase.comparisonType() == COMPARISON_NOT_EQUALS && (mbase[0] == mx || mbase[0].isFunction()) && mbase[1].isNumber() && mi.isNumber()) {
7055 						ComparisonResult cr = COMPARISON_RESULT_UNKNOWN;
7056 						if(mbase[0].isFunction()) {
7057 							MathStructure mfunc(mbase[0]);
7058 							mfunc.replace(mx, v);
7059 							mfunc.eval(eo2);
7060 							if(mfunc.isNumber()) cr = mbase[1].number().compare(mfunc.number());
7061 						} else {
7062 							cr = mbase[1].number().compare(mi.number());
7063 						}
7064 						b = COMPARISON_IS_NOT_EQUAL(cr);
7065 						if(!b && cr != COMPARISON_RESULT_UNKNOWN) {v->destroy(); return false;}
7066 					} else if(mbase.isLogicalAnd()) {
7067 						for(size_t i = 0; i < mbase.size(); i++) {
7068 							if(mbase[i].isComparison()) {mbase[i][0].eval(eo2); mbase[i][1].eval(eo2);}
7069 							if(mbase[i].isComparison() && mbase[i].comparisonType() == COMPARISON_NOT_EQUALS && (mbase[i][0] == mx || mbase[i][0].isFunction()) && mbase[i][1].isNumber() && mi.isNumber()) {
7070 								ComparisonResult cr = COMPARISON_RESULT_UNKNOWN;
7071 								if(mbase[i][0].isFunction()) {
7072 									MathStructure mfunc(mbase[i][0]);
7073 									mfunc.replace(mx, v);
7074 									mfunc.eval(eo2);
7075 									if(mfunc.isNumber()) cr = mbase[i][1].number().compare(mfunc.number());
7076 								} else {
7077 									cr = mbase[i][1].number().compare(mi.number());
7078 								}
7079 								b = COMPARISON_IS_NOT_EQUAL(cr);
7080 								if(!b && cr != COMPARISON_RESULT_UNKNOWN) {v->destroy(); return false;}
7081 							}
7082 						}
7083 					}
7084 					if(!b) {
7085 						CALCULATOR->endTemporaryStopMessages();
7086 						CALCULATOR->endTemporaryStopMessages();
7087 						CALCULATOR->error(false, _("To avoid division by zero, the following must be true: %s."), format_and_print(mbase).c_str(), NULL);
7088 						CALCULATOR->beginTemporaryStopMessages();
7089 						CALCULATOR->beginTemporaryStopMessages();
7090 					}
7091 				}
7092 			}
7093 			v->destroy();
7094 		}
7095 	} else if(m.isVariable()) {
7096 		if(m.variable()->isKnown() && !check_denominators(((KnownVariable*) m.variable())->get(), mi, mx, eo)) return false;
7097 	} else if(m.isFunction() && (m.function()->id() == FUNCTION_ID_TAN || m.function()->id() == FUNCTION_ID_TANH || !m.representsNumber(true))) {
7098 		EvaluationOptions eo2 = eo;
7099 		eo2.approximation = APPROXIMATION_APPROXIMATE;
7100 		eo2.assume_denominators_nonzero = false;
7101 		MathStructure mfunc(m);
7102 		bool b = mfunc.calculateFunctions(eo2);
7103 		if(b && !check_denominators(mfunc, mi, mx, eo)) return false;
7104 		if(mfunc.isFunction() && (mfunc.function()->id() == FUNCTION_ID_TAN || mfunc.function()->id() == FUNCTION_ID_TANH)) {
7105 			mfunc.replace(mx, mi);
7106 			eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
7107 			CALCULATOR->beginTemporaryStopMessages();
7108 			b = mfunc.calculateFunctions(eo2);
7109 			CALCULATOR->endTemporaryStopMessages();
7110 			if(!b) return false;
7111 		}
7112 	}
7113 	return true;
7114 }
replace_atanh(MathStructure & m,const MathStructure & x_var,const MathStructure & m1,const MathStructure & m2,const EvaluationOptions & eo)7115 bool replace_atanh(MathStructure &m, const MathStructure &x_var, const MathStructure &m1, const MathStructure &m2, const EvaluationOptions &eo) {
7116 	bool b = false;
7117 	if(m.isFunction() && m.function()->id() == FUNCTION_ID_ATANH && m.size() == 1 && m[0].contains(x_var, true)) {
7118 		/*MathStructure mtest(m[0]);
7119 		mtest.replace(x_var, m1);
7120 		b = (mtest.compare(m_one) == COMPARISON_RESULT_EQUAL) || (mtest.compare(m_minus_one) == COMPARISON_RESULT_EQUAL);
7121 		if(!b) {
7122 			mtest = m[0];
7123 			mtest.replace(x_var, m2);
7124 			b = (mtest.compare(m_one) == COMPARISON_RESULT_EQUAL) || (mtest.compare(m_minus_one) == COMPARISON_RESULT_EQUAL);
7125 		}*/
7126 		b = true;
7127 		if(b) {
7128 			MathStructure marg(m[0]);
7129 			m = marg;
7130 			m += m_one;
7131 			m.transformById(FUNCTION_ID_LOG);
7132 			m *= nr_half;
7133 			m += marg;
7134 			m.last().negate();
7135 			m.last() += m_one;
7136 			m.last().transformById(FUNCTION_ID_LOG);
7137 			m.last() *= Number(-1, 2);
7138 			return true;
7139 		}
7140 	}
7141 	if(m.isPower() && m[1].isInteger() && (m[1].number() > 10 || m[1].number() < -10)) return false;
7142 	for(size_t i = 0; i < m.size(); i++) {
7143 		if(replace_atanh(m[i], x_var, m1, m2, eo)) b = true;
7144 	}
7145 	if(b) {
7146 		m.childrenUpdated();
7147 		m.calculatesub(eo, eo, false);
7148 	}
7149 	return b;
7150 }
find_abs_x(MathStructure & mstruct,const MathStructure & x_var)7151 MathStructure *find_abs_x(MathStructure &mstruct, const MathStructure &x_var) {
7152 	for(size_t i = 0; i < mstruct.size(); i++) {
7153 		MathStructure *m = find_abs_x(mstruct[i], x_var);
7154 		if(m) return m;
7155 	}
7156 	if(mstruct.isFunction() && ((mstruct.function()->id() == FUNCTION_ID_ABS && mstruct.size() == 1) || (mstruct.function()->id() == FUNCTION_ID_ROOT && mstruct.size() == 2 && mstruct[1].isInteger() && mstruct[1].number().isOdd()))) {
7157 		return &mstruct;
7158 	}
7159 	return NULL;
7160 }
replace_abs(MathStructure & mstruct,const MathStructure & mabs,bool neg)7161 bool replace_abs(MathStructure &mstruct, const MathStructure &mabs, bool neg) {
7162 	if(mstruct.equals(mabs, true, true)) {
7163 		if(mabs.function()->id() == FUNCTION_ID_ROOT) {
7164 			mstruct[1].inverse();
7165 			mstruct.setType(STRUCT_POWER);
7166 			if(neg) {
7167 				mstruct[0].negate();
7168 				mstruct.negate();
7169 			}
7170 		} else {
7171 			mstruct.setToChild(1, true);
7172 			if(neg) mstruct.negate();
7173 		}
7174 		return true;
7175 	}
7176 	bool b_ret = false;
7177 	for(size_t i = 0; i < mstruct.size(); i++) {
7178 		if(replace_abs(mstruct[i], mabs, neg)) b_ret = true;
7179 	}
7180 	return b_ret;
7181 }
7182 
7183 // Check definite integral for functions that cannot be calculated
contains_incalc_function(const MathStructure & mstruct,const EvaluationOptions & eo)7184 bool contains_incalc_function(const MathStructure &mstruct, const EvaluationOptions &eo) {
7185 	for(size_t i = 0; i < mstruct.size(); i++) {
7186 		if(contains_incalc_function(mstruct[i], eo)) return true;
7187 	}
7188 	if(mstruct.isFunction()) {
7189 		if((mstruct.function()->id() == FUNCTION_ID_FRESNEL_S || mstruct.function()->id() == FUNCTION_ID_FRESNEL_C) && mstruct.size() == 1) {
7190 			if(mstruct[0].representsComplex()) return true;
7191 			MathStructure mtest(mstruct[0]);
7192 			mtest.eval(eo);
7193 			return !mtest.isNumber() || !(mtest.number() >= -6) || !(mtest.number() <= 6);
7194 		} else if(mstruct.function()->id() == FUNCTION_ID_POLYLOG || ((mstruct.function()->id() == FUNCTION_ID_EXPINT || mstruct.function()->id() == FUNCTION_ID_ERF || mstruct.function()->id() == FUNCTION_ID_ERFI) && mstruct.size() == 1 && !mstruct[0].representsReal())) {
7195 			MathStructure mtest(mstruct);
7196 			mtest.eval(eo);
7197 			return !mtest.isNumber();
7198 		} else if(mstruct.function()->id() == FUNCTION_ID_I_GAMMA && mstruct.size() == 2) {
7199 #if MPFR_VERSION_MAJOR < 4
7200 			return true;
7201 #else
7202 			return !COMPARISON_IS_EQUAL_OR_LESS(mstruct[1].compare(m_zero));
7203 #endif
7204 		}
7205 	}
7206 	return false;
7207 }
7208 
test_definite_ln(const MathStructure & m,const MathStructure & mi,const MathStructure & mx,const EvaluationOptions & eo)7209 bool test_definite_ln(const MathStructure &m, const MathStructure &mi, const MathStructure &mx, const EvaluationOptions &eo) {
7210 	for(size_t i = 0; i < m.size(); i++) {
7211 		if(!test_definite_ln(m[i], mi, mx, eo)) return false;
7212 	}
7213 	if(m.isFunction() && m.function()->id() == FUNCTION_ID_LOG && m.size() == 1 && m[0].contains(mx, true) > 0 && !m[0].representsNonComplex(true)) {
7214 		MathStructure mtest(m[0]);
7215 		mtest.replace(mx, mi);
7216 		EvaluationOptions eo2 = eo;
7217 		eo2.approximation = APPROXIMATION_APPROXIMATE;
7218 		eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
7219 		CALCULATOR->beginTemporaryStopMessages();
7220 		mtest.eval(eo2);
7221 		CALCULATOR->endTemporaryStopMessages();
7222 		if(mtest.isNumber() && mtest.number().hasImaginaryPart() && !mtest.number().imaginaryPartIsNonZero() && !mtest.number().realPart().isNonNegative()) return false;
7223 	}
7224 	return true;
7225 }
7226 
replace_intervals(MathStructure & m,vector<KnownVariable * > vars)7227 void replace_intervals(MathStructure &m, vector<KnownVariable*> vars) {
7228 	if(m.isNumber() && m.number().isInterval()) {
7229 		KnownVariable *v = new KnownVariable("", format_and_print(m), m);
7230 		m.set(v, true);
7231 		vars.push_back(v);
7232 		return;
7233 	}
7234 	for(size_t i = 0; i < m.size(); i++) {
7235 		replace_intervals(m[i], vars);
7236 	}
7237 }
restore_intervals(MathStructure & m,MathStructure & m2,vector<KnownVariable * > vars,const EvaluationOptions & eo)7238 void restore_intervals(MathStructure &m, MathStructure &m2, vector<KnownVariable*> vars, const EvaluationOptions &eo) {
7239 	for(size_t i = 0; i < vars.size(); i++) {
7240 		if(eo.approximation == APPROXIMATION_EXACT) {
7241 			m.replace(vars[i], vars[i]->get());
7242 			m2.replace(vars[i], vars[i]->get());
7243 		}
7244 		vars[i]->destroy();
7245 	}
7246 }
7247 
integrate(const MathStructure & lower_limit,const MathStructure & upper_limit,const MathStructure & x_var_pre,const EvaluationOptions & eo,bool force_numerical,bool simplify_first)7248 bool MathStructure::integrate(const MathStructure &lower_limit, const MathStructure &upper_limit, const MathStructure &x_var_pre, const EvaluationOptions &eo, bool force_numerical, bool simplify_first) {
7249 
7250 	if(!lower_limit.isUndefined() && lower_limit == upper_limit) {
7251 		clear();
7252 		return true;
7253 	}
7254 
7255 	MathStructure m1(lower_limit), m2(upper_limit);
7256 	MathStructure x_var = x_var_pre;
7257 	if(m1.isUndefined() != m2.isUndefined()) {
7258 		if(m1.isUndefined()) m1.set(nr_minus_inf);
7259 		else m2.set(nr_plus_inf);
7260 	}
7261 	m1.eval(eo);
7262 	m2.eval(eo);
7263 	int definite_integral = 0;
7264 	if(!m1.isUndefined() && !m2.isUndefined()) definite_integral = -1;
7265 	if(definite_integral < 0 && (!m1.isNumber() || !m1.number().isMinusInfinity()) && (!m2.isNumber() || !m2.number().isPlusInfinity())) definite_integral = 1;
7266 	if(definite_integral > 0 && m1 == m2) {
7267 		clear();
7268 		return true;
7269 	}
7270 
7271 	CALCULATOR->beginTemporaryStopMessages();
7272 	EvaluationOptions eo2 = eo;
7273 	if(simplify_first) eo2.approximation = APPROXIMATION_EXACT;
7274 	CALCULATOR->beginTemporaryStopMessages();
7275 	MathStructure mstruct_pre(*this);
7276 	MathStructure m_interval;
7277 	if(!m1.isUndefined()) {
7278 		m_interval.set(CALCULATOR->getFunctionById(FUNCTION_ID_INTERVAL), &m1, &m2, NULL);
7279 		CALCULATOR->beginTemporaryStopMessages();
7280 		EvaluationOptions eo3 = eo;
7281 		eo3.approximation = APPROXIMATION_APPROXIMATE;
7282 		m_interval.calculateFunctions(eo3);
7283 		CALCULATOR->endTemporaryStopMessages();
7284 		UnknownVariable *var = new UnknownVariable("", format_and_print(x_var_pre));
7285 		var->setInterval(m_interval);
7286 		x_var.set(var);
7287 		mstruct_pre.replace(x_var_pre, x_var);
7288 		var->destroy();
7289 		if(definite_integral && !check_denominators(mstruct_pre, m_interval, x_var, eo)) {
7290 			if(definite_integral < 0) {
7291 				definite_integral = 0;
7292 			} else {
7293 				CALCULATOR->endTemporaryStopMessages();
7294 				CALCULATOR->endTemporaryStopMessages(true);
7295 				CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7296 				return false;
7297 			}
7298 		}
7299 	}
7300 	MathStructure mstruct(mstruct_pre);
7301 	vector<KnownVariable*> vars;
7302 	replace_intervals(mstruct, vars);
7303 	eo2.do_polynomial_division = false;
7304 
7305 	if(simplify_first) mstruct.eval(eo2);
7306 
7307 	if(definite_integral > 0 && mstruct.isAddition() && m1.isNumber() && m1.number().isReal() && m2.isNumber() && m2.number().isReal()) {
7308 		mstruct.replace(x_var, x_var_pre);
7309 		MathStructure mbak(mstruct);
7310 		Number nr;
7311 		for(size_t i = 0; i < mstruct.size();) {
7312 			if(!mstruct[i].integrate(lower_limit, upper_limit, x_var_pre, eo, force_numerical, simplify_first)) {
7313 				CALCULATOR->endTemporaryStopMessages();
7314 				CALCULATOR->endTemporaryStopMessages();
7315 				CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7316 				if(simplify_first) set(mbak);
7317 				return false;
7318 			}
7319 			if(mstruct[i].isNumber()) {
7320 				if(nr.add(mstruct[i].number())) mstruct.delChild(i + 1);
7321 				else i++;
7322 			} else i++;
7323 		}
7324 		mstruct.childrenUpdated();
7325 		if(mstruct.size() == 0) mstruct.set(nr, true);
7326 		else if(!nr.isZero() || nr.isApproximate()) mstruct.addChild(nr);
7327 		CALCULATOR->endTemporaryStopMessages(true);
7328 		CALCULATOR->endTemporaryStopMessages(true);
7329 		set(mstruct);
7330 		return true;
7331 	}
7332 	if(simplify_first) do_simplification(mstruct, eo2, true, false, false, true, true);
7333 	eo2.do_polynomial_division = eo.do_polynomial_division;
7334 	MathStructure mbak(mstruct);
7335 
7336 	if(!force_numerical || definite_integral == 0) {
7337 		int use_abs = -1;
7338 		/*if(m1.isUndefined() && x_var.representsReal() && !contains_complex(mstruct)) {
7339 			use_abs = 1;
7340 		}*/
7341 		if(definite_integral) replace_atanh(mstruct, x_var, lower_limit, upper_limit, eo2);
7342 		if(definite_integral && !simplify_first) combine_ln(mstruct, x_var, eo2);
7343 
7344 		int b = mstruct.integrate(x_var, eo2, simplify_first, use_abs, definite_integral, true, (definite_integral && eo.approximation != APPROXIMATION_EXACT && PRECISION < 20) ? 2 : 4);
7345 
7346 		if(b < 0) {
7347 			restore_intervals(mstruct, mbak, vars, eo);
7348 			CALCULATOR->endTemporaryStopMessages(true);
7349 			CALCULATOR->endTemporaryStopMessages(true);
7350 			CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7351 			if(simplify_first) {
7352 				set(mbak);
7353 				if(definite_integral != 0) replace(x_var, x_var_pre);
7354 			}
7355 			return false;
7356 		}
7357 		if(simplify_first && eo.approximation != APPROXIMATION_EXACT && (!b || mstruct.containsFunctionId(FUNCTION_ID_INTEGRATE, true) > 0)) {
7358 			vector<CalculatorMessage> blocked_messages;
7359 			CALCULATOR->endTemporaryStopMessages(false, &blocked_messages);
7360 			CALCULATOR->beginTemporaryStopMessages();
7361 			MathStructure mbak_integ(mstruct);
7362 			eo2.approximation = eo.approximation;
7363 			eo2.do_polynomial_division = false;
7364 			mstruct = mstruct_pre;
7365 			if(definite_integral) replace_atanh(mstruct, x_var, lower_limit, upper_limit, eo2);
7366 			mstruct.eval(eo2);
7367 			do_simplification(mstruct, eo2, true, false, false, true, true);
7368 			eo2.do_polynomial_division = eo.do_polynomial_division;
7369 			int b2 = mstruct.integrate(x_var, eo2, true, use_abs, definite_integral, true, (definite_integral && eo.approximation != APPROXIMATION_EXACT && PRECISION < 20) ? 2 : 4);
7370 			if(b2 < 0) {
7371 				restore_intervals(mstruct, mbak, vars, eo);
7372 				CALCULATOR->endTemporaryStopMessages(true);
7373 				CALCULATOR->endTemporaryStopMessages(true);
7374 				CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7375 				if(simplify_first) {
7376 					set(mbak);
7377 					if(definite_integral != 0) replace(x_var, x_var_pre);
7378 				}
7379 				return false;
7380 			}
7381 			if(b2 && (!b || mstruct.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0)) {
7382 				CALCULATOR->endTemporaryStopMessages(true);
7383 				b = true;
7384 			} else {
7385 				CALCULATOR->endTemporaryStopMessages(false);
7386 				if(b) {
7387 					CALCULATOR->addMessages(&blocked_messages);
7388 					mstruct = mbak_integ;
7389 				}
7390 			}
7391 		} else {
7392 			restore_intervals(mstruct, mbak, vars, eo);
7393 			CALCULATOR->endTemporaryStopMessages(true);
7394 		}
7395 		eo2.approximation = eo.approximation;
7396 		if(b) {
7397 			if(definite_integral && mstruct.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0 && test_definite_ln(mstruct, m_interval, x_var, eo)) {
7398 				CALCULATOR->endTemporaryStopMessages(true);
7399 				MathStructure mstruct_lower(mstruct);
7400 				if(m1.isInfinite() || m2.isInfinite()) {
7401 					CALCULATOR->beginTemporaryStopMessages();
7402 					EvaluationOptions eo3 = eo;
7403 					eo3.approximation = APPROXIMATION_EXACT;
7404 					if(m1.isInfinite()) {
7405 						b = mstruct_lower.calculateLimit(x_var, m1, eo3) && !mstruct_lower.isInfinite();
7406 					} else {
7407 						mstruct_lower.replace(x_var, lower_limit);
7408 						b = eo.approximation == APPROXIMATION_EXACT || !contains_incalc_function(mstruct_lower, eo);
7409 					}
7410 					MathStructure mstruct_upper(mstruct);
7411 					if(m2.isInfinite()) {
7412 						b = mstruct_upper.calculateLimit(x_var, m2, eo3) && !mstruct_upper.isInfinite();
7413 					} else {
7414 						mstruct_upper.replace(x_var, upper_limit);
7415 						b = eo.approximation == APPROXIMATION_EXACT || !contains_incalc_function(mstruct_upper, eo);
7416 					}
7417 					if(b) {
7418 						set(mstruct_upper);
7419 						subtract(mstruct_lower);
7420 						return true;
7421 					} else {
7422 						if(definite_integral > 0) {
7423 							CALCULATOR->endTemporaryStopMessages(true);
7424 							CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7425 							if(simplify_first) {
7426 								set(mbak);
7427 								replace(x_var, x_var_pre);
7428 							}
7429 							return false;
7430 						} else {
7431 							definite_integral = 0;
7432 						}
7433 					}
7434 				} else {
7435 					mstruct_lower.replace(x_var, lower_limit);
7436 					if(eo.approximation == APPROXIMATION_EXACT || !m1.isNumber() || !m1.number().isReal() || !contains_incalc_function(mstruct_lower, eo)) {
7437 						mstruct.replace(x_var, upper_limit);
7438 						if(eo.approximation != APPROXIMATION_EXACT && m2.isNumber() && m2.number().isReal() && contains_incalc_function(mstruct, eo)) {
7439 							mstruct = mbak;
7440 						} else {
7441 							set(mstruct);
7442 							subtract(mstruct_lower);
7443 							return true;
7444 						}
7445 					}
7446 				}
7447 			} else if(definite_integral < 0) {
7448 				definite_integral = 0;
7449 			} else if(definite_integral > 0) {
7450 				mstruct = mbak;
7451 			}
7452 			if(!definite_integral) {
7453 				set(mstruct);
7454 				if(!m1.isUndefined()) replace(x_var, x_var_pre);
7455 				CALCULATOR->endTemporaryStopMessages(true);
7456 				add(CALCULATOR->getVariableById(VARIABLE_ID_C));
7457 				return true;
7458 			}
7459 		}
7460 		if(!b) {
7461 			if(definite_integral <= 0) {
7462 				CALCULATOR->endTemporaryStopMessages(true);
7463 				CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7464 				if(simplify_first) {
7465 					set(mbak);
7466 					replace(x_var, x_var_pre);
7467 				}
7468 				return false;
7469 			} else {
7470 				mstruct = mbak;
7471 			}
7472 		}
7473 
7474 		// Calculate definite integral with abs() or root() with appropriate intervals
7475 		MathStructure *mabs = find_abs_x(mbak, x_var);
7476 		if(mabs && !is_differentiable((*mabs)[0])) mabs = NULL;
7477 		if(mabs && !(*mabs)[0].representsNonComplex(true)) {
7478 			MathStructure mtest((*mabs)[0]);
7479 			mtest.transformById(FUNCTION_ID_IM);
7480 			if(mtest.compare(m_zero) != COMPARISON_RESULT_EQUAL) mabs = NULL;
7481 		}
7482 		if(mabs) {
7483 			bool b_reversed = COMPARISON_IS_EQUAL_OR_GREATER(m2.compare(m1));
7484 			MathStructure m0((*mabs)[0]);
7485 			m0.transform(COMPARISON_EQUALS, m_zero);
7486 			EvaluationOptions eo3 = eo;
7487 			eo3.approximation = APPROXIMATION_EXACT;
7488 			eo3.isolate_x = true;
7489 			eo3.isolate_var = &x_var;
7490 			m0.eval(eo3);
7491 			bool b_exit = false;
7492 			if(m0.isZero()) {
7493 				m0 = (*mabs)[0];
7494 				m0.replace(x_var, lower_limit);
7495 				ComparisonResult cr1 = m0.compare(m_zero);
7496 				if(COMPARISON_IS_EQUAL_OR_LESS(cr1)) {
7497 					if(replace_abs(mbak, *mabs, false)) {
7498 						mbak.replace(x_var, x_var_pre);
7499 						CALCULATOR->endTemporaryStopMessages(true);
7500 						if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7501 							set(mbak);
7502 							return true;
7503 						}
7504 						if(simplify_first) set(mbak);
7505 						return false;
7506 					}
7507 				} else if(COMPARISON_IS_EQUAL_OR_GREATER(cr1)) {
7508 					if(replace_abs(mbak, *mabs, true)) {
7509 						mbak.replace(x_var, x_var_pre);
7510 						CALCULATOR->endTemporaryStopMessages(true);
7511 						if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7512 							set(mbak);
7513 							return true;
7514 						}
7515 						if(simplify_first) set(mbak);
7516 						return false;
7517 					}
7518 				}
7519 			} else if(m0.isComparison() && m0.comparisonType() == COMPARISON_EQUALS && m0[0] == x_var && m0[1].contains(x_var, true) == 0) {
7520 				CALCULATOR->endTemporaryStopMessages();
7521 				CALCULATOR->beginTemporaryStopMessages();
7522 				m0.setToChild(2, true);
7523 				ComparisonResult cr1 = m0.compare(b_reversed ? m2 : m1);
7524 				ComparisonResult cr2 = m0.compare(b_reversed ? m1 : m2);
7525 				if(COMPARISON_IS_EQUAL_OR_GREATER(cr1) || COMPARISON_IS_EQUAL_OR_LESS(cr2)) {
7526 					MathStructure mtest((*mabs)[0]);
7527 					if(b_reversed) mtest.replace(x_var, COMPARISON_IS_EQUAL_OR_GREATER(cr1) ? lower_limit : upper_limit);
7528 					else mtest.replace(x_var, COMPARISON_IS_EQUAL_OR_GREATER(cr1) ? upper_limit : lower_limit);
7529 					ComparisonResult cr = mtest.compare(m_zero);
7530 					if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7531 						if(replace_abs(mbak, *mabs, false)) {
7532 							mbak.replace(x_var, x_var_pre);
7533 							CALCULATOR->endTemporaryStopMessages(true);
7534 							if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7535 								set(mbak);
7536 								return true;
7537 							}
7538 							if(simplify_first) set(mbak);
7539 							return false;
7540 						}
7541 					} else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7542 						if(replace_abs(mbak, *mabs, true)) {
7543 							mbak.replace(x_var, x_var_pre);
7544 							CALCULATOR->endTemporaryStopMessages(true);
7545 							if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7546 								set(mbak);
7547 								return true;
7548 							}
7549 							if(simplify_first) set(mbak);
7550 							return false;
7551 						}
7552 					}
7553 				} else if(cr1 == COMPARISON_RESULT_LESS && cr2 == COMPARISON_RESULT_GREATER) {
7554 					MathStructure mtest((*mabs)[0]);
7555 					mtest.replace(x_var, lower_limit);
7556 					ComparisonResult cr = mtest.compare(m_zero);
7557 					MathStructure minteg1(mbak), minteg2;
7558 					b = false;
7559 					if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7560 						if(replace_abs(minteg1, *mabs, false)) b = true;
7561 					} else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7562 						if(replace_abs(minteg1, *mabs, true)) b = true;
7563 					}
7564 					if(b) {
7565 						minteg1.replace(x_var, x_var_pre);
7566 						CALCULATOR->beginTemporaryStopMessages();
7567 						b = minteg1.integrate(lower_limit, m0, x_var_pre, eo, false, true);
7568 						b_exit = CALCULATOR->endTemporaryStopMessages(NULL, NULL, MESSAGE_ERROR) == 0;
7569 						if(!b_exit) b = false;
7570 					}
7571 					if(b) {
7572 						mtest = (*mabs)[0];
7573 						mtest.replace(x_var, upper_limit);
7574 						cr = mtest.compare(m_zero);
7575 						minteg2 = mbak;
7576 						b = false;
7577 						if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7578 							if(replace_abs(minteg2, *mabs, false)) b = true;
7579 						} else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7580 							if(replace_abs(minteg2, *mabs, true)) b = true;
7581 						}
7582 					}
7583 					if(b) {
7584 						minteg2.replace(x_var, x_var_pre);
7585 						CALCULATOR->beginTemporaryStopMessages();
7586 						b = minteg2.integrate(m0, upper_limit, x_var_pre, eo, false, true);
7587 						b_exit = CALCULATOR->endTemporaryStopMessages(NULL, NULL, MESSAGE_ERROR) == 0;
7588 						if(!b_exit) b = false;
7589 					}
7590 					if(b) {
7591 						CALCULATOR->endTemporaryStopMessages(true);
7592 						set(minteg1);
7593 						add(minteg2);
7594 						return true;
7595 					}
7596 				}
7597 			} else if(m0.isLogicalOr() && m0.size() <= 10) {
7598 				vector<MathStructure> zeroes;
7599 				bool b = true;
7600 				for(size_t i = 0; i < m0.size(); i++) {
7601 					if(!m0[i].isComparison() || m0[i].comparisonType() != COMPARISON_EQUALS || m0[i][0] != x_var) {
7602 						b = false;
7603 						break;
7604 					} else {
7605 						for(size_t i2 = 0; i2 < zeroes.size(); i2++) {
7606 							ComparisonResult cr = m0[i][1].compare(zeroes[i2]);
7607 							if(cr == COMPARISON_RESULT_GREATER) {zeroes.insert(zeroes.begin() + i2, m0[i][1]); break;}
7608 							else if(cr != COMPARISON_RESULT_LESS) {b = false; break;}
7609 						}
7610 						if(!b) break;
7611 						if(zeroes.size() == i) zeroes.push_back(m0[i][1]);
7612 					}
7613 				}
7614 				if(b) {
7615 					vector<MathStructure> integs;
7616 					for(size_t i = 0; i <= zeroes.size(); i++) {
7617 						MathStructure mtest((*mabs)[0]);
7618 						if(i == 0) {
7619 							mtest.replace(x_var, b_reversed ? upper_limit : lower_limit);
7620 						} else if(i == zeroes.size()) {
7621 							mtest.replace(x_var, b_reversed ? lower_limit : upper_limit);
7622 						} else {
7623 							MathStructure mrepl(zeroes[i - 1]);
7624 							mrepl += zeroes[i];
7625 							mrepl *= nr_half;
7626 							mtest.replace(x_var, mrepl);
7627 						}
7628 						ComparisonResult cr = mtest.compare(m_zero);
7629 						MathStructure minteg(mbak);
7630 						b = false;
7631 						if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7632 							if(replace_abs(minteg, *mabs, false)) b = true;
7633 						} else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7634 							if(replace_abs(minteg, *mabs, true)) b = true;
7635 						}
7636 						if(b) {
7637 							minteg.replace(x_var, x_var_pre);
7638 							CALCULATOR->beginTemporaryStopMessages();
7639 							b = minteg.integrate(i == 0 ? (b_reversed ? upper_limit : lower_limit) : zeroes[i - 1], i == zeroes.size() ? (b_reversed ? lower_limit : upper_limit) : zeroes[i], x_var_pre, eo, false, true);
7640 							b_exit = CALCULATOR->endTemporaryStopMessages(NULL, NULL, MESSAGE_ERROR) == 0;
7641 							if(!b_exit) b = false;
7642 							if(b_reversed) minteg.negate();
7643 						}
7644 						if(!b) break;
7645 						integs.push_back(minteg);
7646 					}
7647 					if(b) {
7648 						for(size_t i = 0; i < integs.size(); i++) {
7649 							if(i == 0) set(integs[i]);
7650 							else add(integs[i], true);
7651 						}
7652 						CALCULATOR->endTemporaryStopMessages(true);
7653 						return true;
7654 					}
7655 				}
7656 			}
7657 			if(b_exit) {
7658 				CALCULATOR->endTemporaryStopMessages();
7659 				CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7660 				if(simplify_first) {
7661 					set(mbak);
7662 					replace(x_var, x_var_pre);
7663 				}
7664 				return false;
7665 			}
7666 		}
7667 		CALCULATOR->endTemporaryStopMessages();
7668 		if(mstruct.containsInterval() && eo.approximation == APPROXIMATION_EXACT) {
7669 			CALCULATOR->error(false, _("Unable to integrate the expression exact."), NULL);
7670 			if(simplify_first) {
7671 				set(mstruct);
7672 				replace(x_var, x_var_pre);
7673 			}
7674 			return false;
7675 		}
7676 	} else {
7677 		CALCULATOR->endTemporaryStopMessages();
7678 		CALCULATOR->endTemporaryStopMessages();
7679 		restore_intervals(mstruct, mbak, vars, eo);
7680 	}
7681 
7682 	if(m1.isNumber() && m1.number().isReal() && m2.isNumber() && m2.number().isReal()) {
7683 
7684 		if(eo.approximation != APPROXIMATION_EXACT) eo2.approximation = APPROXIMATION_APPROXIMATE;
7685 
7686 		mstruct = mstruct_pre;
7687 		mstruct.eval(eo2);
7688 
7689 		eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
7690 		eo2.warn_about_denominators_assumed_nonzero = false;
7691 
7692 		Number nr_begin, nr_end;
7693 		bool b_reversed = false;
7694 		if(m1.number().isGreaterThan(m2.number())) {
7695 			nr_begin = m2.number();
7696 			nr_end = m1.number();
7697 			b_reversed = true;
7698 		} else {
7699 			nr_begin = m1.number();
7700 			nr_end = m2.number();
7701 		}
7702 		if(eo.approximation != APPROXIMATION_EXACT) {
7703 			Number nr;
7704 			CALCULATOR->beginTemporaryStopMessages();
7705 			if(romberg(mstruct, nr, x_var, eo2, nr_begin, nr_end)) {
7706 				CALCULATOR->endTemporaryStopMessages();
7707 				if(b_reversed) nr.negate();
7708 				if(!force_numerical) CALCULATOR->error(false, _("Definite integral was approximated."), NULL);
7709 				set(nr);
7710 				return true;
7711 			}
7712 			CALCULATOR->endTemporaryStopMessages();
7713 			CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7714 			if(simplify_first) {
7715 				set(mbak);
7716 				replace(x_var, x_var_pre);
7717 			}
7718 			return false;
7719 		}
7720 		Number nr_range(nr_end);
7721 		nr_range -= nr_begin;
7722 		MathStructure merr(mstruct);
7723 		CALCULATOR->beginTemporaryStopMessages();
7724 		eo2.expand = false;
7725 		for(size_t i = 0; i < 4; i++) {
7726 			if(merr.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) > 0 || !merr.differentiate(x_var, eo2)) {
7727 				break;
7728 			}
7729 			merr.calculatesub(eo2, eo2, true);
7730 			if(CALCULATOR->aborted() || merr.countTotalChildren() > 200) {
7731 				break;
7732 			}
7733 		}
7734 		eo2.expand = eo.expand;
7735 		CALCULATOR->endTemporaryStopMessages();
7736 		if(merr.isZero()) {
7737 			Number nr;
7738 			if(numerical_integration(mstruct, nr, x_var, eo2, nr_begin, nr_end, 12, 0)) {
7739 				if(b_reversed) nr.negate();
7740 				set(nr);
7741 				return true;
7742 			}
7743 		}
7744 		CALCULATOR->error(false, _("Unable to integrate the expression exact."), NULL);
7745 		if(simplify_first) {
7746 			set(mbak);
7747 			replace(x_var, x_var_pre);
7748 		}
7749 		return false;
7750 	}
7751 	if(simplify_first) {
7752 		set(mbak);
7753 		replace(x_var, x_var_pre);
7754 	}
7755 	CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7756 	return false;
7757 }
7758 
7759 
7760 
7761