private List <Expression> DeepProof(Expression expression, Dictionary <Constant, bool> values) { switch (expression) { case Constant c: var value = Evaluator.Evaluate(c, values); var proof = ProofCollection.GetProof(typeof(Negation), value); for (int i = 0; i < proof.Count; i++) { proof[i] = SubstituteExprsToExpr(proof[i], c, null); } return(proof); case UnaryOperation uo: proof = new List <Expression>(); value = Evaluator.Evaluate(uo.Expression, values); if (!(uo.Expression is Constant)) { proof.AddRange(DeepProof(uo.Expression, values)); } var tempProof = ProofCollection.GetProof(uo.GetType(), value); for (int i = 0; i < tempProof.Count; i++) { tempProof[i] = SubstituteExprsToExpr(tempProof[i], uo.Expression, null); } proof.AddRange(tempProof); return(proof); case BinaryOperation bo: proof = new List <Expression>(); var leftValue = Evaluator.Evaluate(bo.Left, values); var rightValue = Evaluator.Evaluate(bo.Right, values); proof.AddRange(DeepProof(bo.Left, values)); proof.AddRange(DeepProof(bo.Right, values)); tempProof = ProofCollection.GetProof(bo.GetType(), leftValue, rightValue); for (int i = 0; i < tempProof.Count; i++) { tempProof[i] = SubstituteExprsToExpr(tempProof[i], bo.Left, bo.Right); } proof.AddRange(tempProof); return(proof); } throw new Exception(); }