/// <summary> /// The Reflexive Property states that for every real number x, x = x. /// </summary> /// <param name="equation"></param> /// <returns>True: Satisfy, False: Un-satisfy, null: </returns> private bool?Satisfy(Equation equation) { bool lhsNumeric = LogicSharp.IsNumeric(equation.Lhs); bool rhsNumeric = LogicSharp.IsNumeric(equation.Rhs); if (lhsNumeric && rhsNumeric) { return(equation.Lhs.Equals(equation.Rhs)); } var leftVar = equation.Lhs as Var; var rightVar = equation.Rhs as Var; if (leftVar != null && rightVar != null) { bool result = leftVar.Equals(rightVar); if (result) { return(true); } return(null); } /* var leftTerm = equation.Lhs as Term; * var rightTerm = equation.Rhs as Term; * if (leftTerm != null && rightTerm != null) * { * * return leftTerm.Equals(rightTerm); * }*/ return(null); }
private static bool SatisfyCalcCondition( Func <Expression, Expression, BinaryExpression> func, object x, object y, out object output) { output = null; if (func.Method.Name.Equals("Divide")) { return(false); } if (LogicSharp.IsNumeric(x) && LogicSharp.IsNumeric(y)) { double xDoubleVal; double yDoubleVal; bool isXDouble = LogicSharp.IsDouble(x, out xDoubleVal); bool isYDouble = LogicSharp.IsDouble(y, out yDoubleVal); if (isXDouble || isYDouble) { var xExpr = Expression.Constant(xDoubleVal); var yExpr = Expression.Constant(yDoubleVal); var rExpr = func(xExpr, yExpr); output = Expression.Lambda <Func <double> >(rExpr).Compile().Invoke(); int iResult; if (LogicSharp.IsInt(output, out iResult)) { output = iResult; return(true); } return(true); } } return(false); }
public static bool IsQuadraticTerm(this Term term) { if (term == null) { return(false); } if (!term.ContainsVar()) { return(false); } var cond1 = term.Op == Expression.Power; var lst = term.Args as List <object>; if (lst == null || lst.Count != 2) { return(false); } var isNum = LogicSharp.IsNumeric(lst[1]); if (!isNum) { return(false); } double number; LogicSharp.IsDouble(lst[1], out number); var cond2 = number.Equals(2.0); return(cond1 && cond2); }
private static bool SatisfyGoalCondition(Equation eq) { var lhs = eq.Lhs; var rhs = eq.Rhs; bool rhsNumeral = LogicSharp.IsNumeric(rhs); return(Var.IsVar(lhs) && rhsNumeral); }
private static bool SatisfySymmetricCondition(object lhs, object rhs) { bool lhsNumeric = LogicSharp.IsNumeric(lhs); bool rhsNumeric = LogicSharp.IsNumeric(rhs); if (lhsNumeric && !rhsNumeric) { return(true); } return(false); }
public override bool Equals(object obj) { var eqGoal = obj as EqGoal; if (eqGoal != null) { if (Rhs == null) { return(Lhs.Equals(eqGoal.Lhs)); } bool isNum1 = LogicSharp.IsNumeric(Rhs); bool isNum2 = LogicSharp.IsNumeric(eqGoal.Rhs); bool result; if (isNum1 && isNum2) { result = LogicSharp.NumericEqual(Rhs, eqGoal.Rhs); } else { result = Rhs.Equals(eqGoal.Rhs); } return(Lhs.Equals(eqGoal.Lhs) && result); } var eq = obj as Equation; if (eq != null) { if (Rhs == null) { return(Lhs.Equals(eq.Lhs)); } bool isNum1 = LogicSharp.IsNumeric(Rhs); bool isNum2 = LogicSharp.IsNumeric(eq.Rhs); bool result; if (isNum1 && isNum2) { result = LogicSharp.NumericEqual(Rhs, eq.Rhs); } else { result = Rhs.Equals(eq.Rhs); } if (eq.Lhs == null) { return(false); } return(Lhs.ToString().Equals(eq.Lhs.ToString()) && result); } return(false); }
/* * Move sqare root head to the rhs * E.g x^2=4 -> x=4^(0.5) * */ private static bool SatisfyTransitiveCondition2(object lhs, object rhs) { bool rhsNumeric = LogicSharp.IsNumeric(rhs); var lhsTerm = lhs as Term; if (lhsTerm != null) { if (lhsTerm.Op.Method.Name.Equals("Power") && rhsNumeric) { return(true); } } return(false); }
public override bool Equals(object obj) { if (obj is Term) { var term = obj as Term; if (!Op.Equals(term.Op)) { return(false); } var lst = Args as List <object>; var lst1 = term.Args as List <object>; Debug.Assert(lst != null); Debug.Assert(lst1 != null); if (lst.Count != lst1.Count) { return(false); } for (int i = 0; i < lst.Count; i++) { var curr1 = lst[i]; var curr2 = lst1[i]; bool isNum1 = LogicSharp.IsNumeric(curr1); bool isNum2 = LogicSharp.IsNumeric(curr2); bool result; if (isNum1 && isNum2) { result = LogicSharp.NumericEqual(curr1, curr2); } else { if (curr1 == null || curr2 == null) { return(false); } result = curr1.Equals(curr2); } if (!result) { return(false); } } return(true); //return !lst.Where((t, i) => !t.Equals(lst1[i])).Any(); } return(false); }
/* * E.g -1*x=2 */ private static bool SatisfyTransitiveCondition3(object lhs, object rhs) { return(false); bool rhsNumeric = LogicSharp.IsNumeric(rhs); if (!rhsNumeric) { return(false); } var lhsTerm = lhs as Term; if (lhsTerm == null) { return(false); } if (!lhsTerm.Op.Method.Name.Equals("Multiply")) { return(false); } var lst = lhsTerm.Args as List <object>; Debug.Assert(lst != null); foreach (var temp in lst) { bool isNumber = LogicSharp.IsNumeric(temp); if (isNumber) { return(true); } var term = temp as Term; if (term != null && !term.ContainsVar()) { return(true); } } return(false); }
private static bool SatisfyTransitiveCondition5( object lhs, object rhs, out object newLhs, out object newRhs) { newLhs = null; newRhs = null; var lhsTerm = lhs as Term; if (lhsTerm != null && lhsTerm.Op.Method.Name.Equals("Divide")) { var lst = lhsTerm.Args as List <object>; Debug.Assert(lst != null); Debug.Assert(lst.Count == 2); bool denomIsNum = LogicSharp.IsNumeric(lst[1]); if (denomIsNum) { newLhs = lst[0]; newRhs = new Term(Expression.Multiply, new List <object> { lst[1], rhs }); return(true); } } var rhsTerm = rhs as Term; if (rhsTerm != null && rhsTerm.Op.Method.Name.Equals("Divide")) { var lst = rhsTerm.Args as List <object>; bool denomIsNum = LogicSharp.IsNumeric(lst[1]); if (denomIsNum) { newLhs = new Term(Expression.Multiply, new List <object> { lst[1], lhs }); newRhs = lst[0]; return(true); } } return(false); }
/* * E.g 2/y=4, x/2=4 */ private static bool SatisfyTransitiveCondition4(object lhs, object rhs) { bool rhsNumeric = LogicSharp.IsNumeric(rhs); if (!rhsNumeric) { return(false); } var lhsTerm = lhs as Term; if (lhsTerm == null) { return(false); } if (!lhsTerm.Op.Method.Name.Equals("Divide")) { return(false); } var lst = lhsTerm.Args as List <object>; Debug.Assert(lst != null); if (lst.Count != 2) { return(false); } foreach (var temp in lst) { bool isNumber = LogicSharp.IsNumeric(temp); if (isNumber) { return(true); } } return(false); }
public override string ToString() { var builder = new StringBuilder(); var tuple = Args as Tuple <object, object>; if (tuple != null) { #region Tuple Format builder.Append('('); var lTerm = tuple.Item1; var rTerm = tuple.Item2; builder.Append(lTerm); if (Op.Method.Name.Equals("Add")) { builder.Append('+'); } else if (Op.Method.Name.Equals("Substract")) { builder.Append('-'); } else if (Op.Method.Name.Equals("Multiply")) { builder.Append('*'); } else if (Op.Method.Name.Equals("Divide")) { builder.Append('/'); } builder.Append(rTerm.ToString()); builder.Append(')'); #endregion } var lst = Args as List <object>; if (lst != null) { for (int i = 0; i < lst.Count; i++) { var variable = lst[i] as Var; bool number = LogicSharp.IsNumeric(lst[i]); var localTerm = lst[i] as Term; #region Var if (variable != null) { if (Op.Method.Name.Equals("Add")) { if (i != 0) { builder.Append("+"); } } if (Op.Method.Name.Equals("Power")) { if (i != 0) { builder.Append("^"); } } builder.Append(variable); } #endregion #region Numerics if (number) { if (Op.Method.Name.Equals("Add")) { if (i != 0) { double dnum; bool result = LogicSharp.IsDouble(lst[i], out dnum); if (dnum < 0.0) { builder.Append("-"); double absNum = Math.Abs(dnum); builder.Append(absNum); } else { builder.Append("+"); builder.Append(lst[i].ToString()); } } else { builder.Append(lst[i].ToString()); } } else if (Op.Method.Name.Equals("Multiply")) { double dnum; LogicSharp.IsDouble(lst[i], out dnum); double absNum = Math.Abs(dnum) - 1.0; if (absNum > 0.0001) { builder.Append(lst[i]); } else { if (dnum < 0.0d) { builder.Append("-"); } } } else if (Op.Method.Name.Equals("Divide")) { if (i != 0) { builder.Append("/"); builder.Append(lst[i].ToString()); } else { builder.Append(lst[i].ToString()); } } else if (Op.Method.Name.Equals("Power")) { if (i != 0) { builder.Append("^"); } builder.Append(lst[i].ToString()); } } #endregion #region Term if (localTerm != null) { //precatch if (Op.Method.Name.Equals("Add")) { if (i != 0) { bool result = localTerm.InvertOp(); if (!result) { builder.Append("+"); } /*else * { * builder.Append("-"); * }*/ } builder.Append(localTerm.ToString()); } if (Op.Method.Name.Equals("Multiply") || Op.Method.Name.Equals("Power") ) { bool needBrace = false; needBrace = localTerm.NeedBracket(); if (needBrace) { builder.Append("("); builder.Append(localTerm.ToString()); builder.Append(")"); } else { builder.Append(localTerm.ToString()); } } if (Op.Method.Name.Equals("Divide")) { if (i != 0) { builder.Append("/"); } bool needBrace = false; needBrace = localTerm.NeedBracket(); if (needBrace) { builder.Append("("); builder.Append(localTerm.ToString()); builder.Append(")"); } else { builder.Append(localTerm.ToString()); } } } #endregion } } return(builder.ToString()); }
private static bool SatisfyAssociativeCondition(Term inTerm, object obj1, object obj2, out object output1, out object output2) { output1 = null; output2 = null; if (inTerm.Op.Method.Name.Equals("Add")) { var term1 = obj1 as Term; var term2 = obj2 as Term; if (term1 != null && term2 != null) { if (term1.Op.Method.Name.Equals("Add") && term2.Op.Method.Name.Equals("Add")) { var term1Args = term1.Args as List <object>; var term2Args = term2.Args as List <object>; if (term1Args != null && term2Args != null) { var term1Arg2 = term1Args[1]; var term2Arg2 = term2Args[1]; if (LogicSharp.IsNumeric(term1Arg2) && LogicSharp.IsNumeric(term2Arg2)) { output1 = new Term(Expression.Add, new List <object> { term1Args[0], term2Args[0] }); output2 = new Term(Expression.Add, new List <object> { term1Arg2, term2Arg2 }); return(true); } } } /* if (term1.Op.Method.Name.Equals("Add") && term2.Op.Method.Name.Equals("Multiply")) * { * var lst = term1.Args as List<object>; * object obj = lst[lst.Count-1]; * if (LogicSharp.IsNumeric(obj) || NotSpecialVariables(obj)) * { * var newLst = new List<object>(); * for (var i = 0; i < lst.Count - 1; i++) * { * newLst.Add(lst[i]); * } * output1 = newLst.Count == 1 ? newLst[0] : new Term(Expression.Add, newLst); * output2 = new Term(Expression.Add, new List<object>() { obj, obj2 }); * return true; * } * }*/ if (term1.Op.Method.Name.Equals("Multiply") && term2.Op.Method.Name.Equals("Add")) { var lst = term2.Args as List <object>; object obj = lst[lst.Count - 1]; if (LogicSharp.IsNumeric(obj) || NotSpecialVariables(obj)) { var newLst = new List <object>(); for (var i = 0; i < lst.Count - 1; i++) { newLst.Add(lst[i]); } newLst.Insert(0, obj1); output1 = new Term(Expression.Add, newLst); output2 = obj; return(true); } } } if (term1 != null && term2 == null) { if (!term1.Op.Method.Name.Equals("Add")) { return(false); } var lst = term1.Args as List <object>; Debug.Assert(lst != null); object obj = lst[lst.Count - 1]; if (LogicSharp.IsNumeric(obj) || NotSpecialVariables(obj)) { var newLst = new List <object>(); for (var i = 0; i < lst.Count - 1; i++) { newLst.Add(lst[i]); } output1 = newLst.Count == 1 ? newLst[0] : new Term(Expression.Add, newLst); output2 = new Term(Expression.Add, new List <object>() { obj, obj2 }); return(true); } return(false); } } else if (inTerm.Op.Method.Name.Equals("Multiply")) { var term1 = obj1 as Term; var term2 = obj2 as Term; if (term1 == null && term2 != null) { if (term2.Op.Method.Name.Equals("Multiply")) { var lst = term2.Args as List <object>; Debug.Assert(lst != null); object obj = lst[0]; if (LogicSharp.IsNumeric(obj) || NotSpecialVariables(obj)) { output1 = new Term(Expression.Multiply, new List <object>() { obj1, obj }); var newLst = new List <object>(); for (var i = 1; i < lst.Count; i++) { newLst.Add(lst[i]); } output2 = newLst.Count == 1 ? newLst[0] : new Term(Expression.Multiply, newLst); return(true); } } } } return(false); }
//commutative law private static bool SatisfyCommutativeCondition(Term inTerm, object obj1, object obj2) { if (inTerm.Op.Method.Name.Equals("Add")) { //e.g 3+x => x+3 if (LogicSharp.IsNumeric(obj1)) { var variable = obj2 as Var; if (variable != null) { return(true); } var term = obj2 as Term; if (term != null && term.ContainsVar()) { return(true); } } //e.g (1+1)+(x+1)=>(x+1)+(1+1) var term1 = obj1 as Term; if (term1 != null && !term1.ContainsVar()) { var variable = obj2 as Var; if (variable != null) { return(true); } var term = obj2 as Term; if (term != null && term.ContainsVar()) { return(true); } } var variable11 = obj1 as Var; var term2 = obj2 as Term; if (variable11 != null && term2.QuadraticTerm()) { return(true); } //(2*y)+(2*x) -> (2*x)+(2*y) // x + x^2 -> x^2 + x if (term1 != null && term2 != null) { var term1Lst = term1.Args as List <object>; Debug.Assert(term1Lst != null); var term1Var = term1Lst[1] as Var; var term2Lst = term2.Args as List <object>; Debug.Assert(term2Lst != null); var term2Var = term2Lst[1] as Var; if (term1Var != null && term2Var != null) { bool condition1 = term1Var.ToString().Equals("Y") || term1Var.ToString().Equals("y"); bool condition2 = term2Var.ToString().Equals("X") || term2Var.ToString().Equals("x"); if (condition1 && condition2) { return(true); } } if (!term1.QuadraticTerm() && term2.QuadraticTerm()) { return(true); } } } else if (inTerm.Op.Method.Name.Equals("Multiply")) { var term1 = obj1 as Term; var term2 = obj2 as Term; /* if (term1 != null && term2 == null) * { * return true; * }*/ //e.g x*3 -> 3*x //e.g 3*x*3 -> x*3*3 if (LogicSharp.IsNumeric(obj2)) { var variable = obj1 as Var; if (variable != null) { return(true); } var term = obj1 as Term; if (term != null && term.ContainsVar()) { return(true); } } } return(false); }
/// <summary> /// if x = y and y = z, then x = z /// if x = y, then x + a = y + a /// if x^2 = y^2, then x = y /// if x = y, then ax = ay /// ax = ay -> x=y /// </summary> /// <param name="goal"></param> /// <param name="gGoal"></param> /// <returns></returns> public static object ApplyTransitive(this Equation currentEq, Equation rootEq, bool withEqRule, bool lineCheck = false) { Equation localEq = currentEq; object lhs = currentEq.Lhs; object rhs = currentEq.Rhs; if (!withEqRule) { return(localEq); } //Power Inverse if (SatisfyTransitiveCondition2(lhs, rhs)) { #region Condition2 var cloneEq = currentEq.Clone(); var cloneEq2 = currentEq.Clone(); var lhsTerm = cloneEq.Lhs as Term; Debug.Assert(lhsTerm != null); var cloneLst = lhsTerm.Args as List <object>; Debug.Assert(cloneLst != null); cloneEq.Lhs = cloneLst[0]; cloneEq.Rhs = new Term(Expression.Power, new List <object>() { cloneEq.Rhs, 0.5 }); var lhsTerm2 = cloneEq2.Lhs as Term; Debug.Assert(lhsTerm2 != null); var cloneLst2 = lhsTerm2.Args as List <object>; Debug.Assert(cloneLst2 != null); cloneEq2.Lhs = cloneLst2[0]; var internal1 = new Term(Expression.Power, new List <object>() { cloneEq2.Rhs, 0.5 }); cloneEq2.Rhs = new Term(Expression.Multiply, new List <object>() { -1, internal1 }); string rule = EquationsRule.Rule(EquationsRule.EquationRuleType.Transitive); string appliedRule = EquationsRule.Rule( EquationsRule.EquationRuleType.Transitive, localEq, null); string KC = EquationsRule.RuleConcept(EquationsRule.EquationRuleType.Transitive); var ts = new TraceStep(localEq, cloneEq, KC, rule, appliedRule); rootEq._innerLoop.Add(ts); //localEq = cloneEq; var lst = new List <Equation>(); lst.Add(cloneEq); lst.Add(cloneEq2); return(lst); #endregion } if (!lineCheck) { //Add Inverse if (SatifyTransitiveCondition0(lhs, rhs)) { #region condition0 var cloneEq = currentEq.Clone(); var rhsTerm = new Term(Expression.Add, new List <object>() { cloneEq.Rhs }); var lhsTerm = cloneEq.Lhs as Term; Debug.Assert(lhsTerm != null); var lst = lhsTerm.Args as List <object>; Debug.Assert(lst != null); for (int i = 0; i < lst.Count; i++) { var temp = lst[i]; bool isNumber = LogicSharp.IsNumeric(temp); if (isNumber) { var inverseRhs = new Term(Expression.Multiply, new List <object>() { -1, temp }); lst.Remove(temp); var rhsArgLst = rhsTerm.Args as List <object>; Debug.Assert(rhsArgLst != null); rhsArgLst.Add(inverseRhs); break; } var term = temp as Term; if (term != null && !term.ContainsVar()) { var inverseRhs = new Term(Expression.Multiply, new List <object>() { -1, temp }); lst.Remove(i); var rhsArgLst = rhsTerm.Args as List <object>; Debug.Assert(rhsArgLst != null); rhsArgLst.Add(inverseRhs); break; } } cloneEq.Rhs = rhsTerm; if (lst.Count == 1) { cloneEq.Lhs = lst[0]; } string rule = EquationsRule.Rule(EquationsRule.EquationRuleType.Transitive); string appliedRule = EquationsRule.Rule( EquationsRule.EquationRuleType.Transitive, localEq, null); string KC = EquationsRule.RuleConcept(EquationsRule.EquationRuleType.Transitive); var traceStep = new TraceStep(localEq, cloneEq, KC, rule, appliedRule); rootEq._innerLoop.Add(traceStep); localEq = cloneEq; return(localEq); #endregion } } else { if (SatisfyTransitiveCondition1(lhs, rhs)) { #region Condition1 var cloneEq = currentEq.Clone(); var inverseRhs = new Term(Expression.Multiply, new List <object>() { -1, rhs }); var lhsTerm = cloneEq.Lhs as Term; if (lhsTerm != null) { var cloneLst = lhsTerm.Args as List <object>; Debug.Assert(cloneLst != null); if (lhsTerm.Op.Method.Name.Equals("Add")) { cloneLst.Add(inverseRhs); } else { cloneEq.Lhs = new Term(Expression.Add, new List <object>() { lhs, inverseRhs }); } } else { cloneEq.Lhs = new Term(Expression.Add, new List <object>() { lhs, inverseRhs }); } cloneEq.Rhs = 0; string rule = EquationsRule.Rule(EquationsRule.EquationRuleType.Transitive); string appliedRule = EquationsRule.Rule( EquationsRule.EquationRuleType.Transitive, localEq, null); string KC = EquationsRule.RuleConcept(EquationsRule.EquationRuleType.Transitive); var traceStep = new TraceStep(localEq, cloneEq, KC, rule, appliedRule); rootEq._innerLoop.Add(traceStep); localEq = cloneEq; #endregion } } //Mutliply Inverse if (SatisfyTransitiveCondition3(lhs, rhs)) { #region condition3 var cloneEq = currentEq.Clone(); var rhsTerm = new Term(Expression.Multiply, new List <object>() { cloneEq.Rhs }); var lhsTerm = cloneEq.Lhs as Term; Debug.Assert(lhsTerm != null); var lst = lhsTerm.Args as List <object>; Debug.Assert(lst != null); for (int i = 0; i < lst.Count; i++) { var temp = lst[i]; bool isNumber = LogicSharp.IsNumeric(temp); if (isNumber) { var inverseRhs = new Term(Expression.Divide, new List <object>() { 1, temp }); lst.Remove(temp); var rhsArgLst = rhsTerm.Args as List <object>; Debug.Assert(rhsArgLst != null); rhsArgLst.Add(inverseRhs); break; } var term = temp as Term; if (term != null && !term.ContainsVar()) { var inverseRhs = new Term(Expression.Divide, new List <object>() { 1, temp }); lst.Remove(i); var rhsArgLst = rhsTerm.Args as List <object>; Debug.Assert(rhsArgLst != null); rhsArgLst.Add(inverseRhs); break; } } cloneEq.Rhs = rhsTerm; if (lst.Count == 1) { cloneEq.Lhs = lst[0]; } string rule = EquationsRule.Rule(EquationsRule.EquationRuleType.Transitive); string appliedRule = EquationsRule.Rule( EquationsRule.EquationRuleType.Transitive, localEq, null); string KC = EquationsRule.RuleConcept(EquationsRule.EquationRuleType.Transitive); var traceStep = new TraceStep(localEq, cloneEq, KC, rule, appliedRule); rootEq._innerLoop.Add(traceStep); localEq = cloneEq; return(localEq); #endregion } //Divide Inverse if (SatisfyTransitiveCondition4(lhs, rhs)) { #region condition4 var cloneEq = currentEq.Clone(); var lhsTerm = cloneEq.Lhs as Term; Debug.Assert(lhsTerm != null); var lst = lhsTerm.Args as List <object>; Debug.Assert(lst != null); Debug.Assert(lst.Count == 2); bool numerator = LogicSharp.IsNumeric(lst[0]); bool deNumerator = LogicSharp.IsNumeric(lst[1]); if (deNumerator) { var rhsTerm = new Term(Expression.Multiply, new List <object>() { lst[1], cloneEq.Rhs }); var newEq = new Equation(lst[0], rhsTerm); string rule = EquationsRule.Rule(EquationsRule.EquationRuleType.Transitive); string appliedRule = EquationsRule.Rule( EquationsRule.EquationRuleType.Transitive, localEq, newEq); string KC = EquationsRule.RuleConcept(EquationsRule.EquationRuleType.Transitive); var traceStep = new TraceStep(localEq, newEq, KC, rule, appliedRule); rootEq._innerLoop.Add(traceStep); localEq = newEq; return(localEq); } if (numerator) { var rhsTerm = new Term(Expression.Divide, new List <object>() { lst[0], cloneEq.Rhs }); var newEq = new Equation(lst[1], rhsTerm); string rule = EquationsRule.Rule(EquationsRule.EquationRuleType.Transitive); string appliedRule = EquationsRule.Rule( EquationsRule.EquationRuleType.Transitive, localEq, newEq); string KC = EquationsRule.RuleConcept(EquationsRule.EquationRuleType.Transitive); var traceStep = new TraceStep(localEq, newEq, KC, rule, appliedRule); rootEq._innerLoop.Add(traceStep); localEq = newEq; return(localEq); } #endregion } return(localEq); }