/// <summary> /// Handles an inferred equality theorem by communicating it with the normalization helper and scheduler, and also handling proof /// construction is the proof data is provided. /// </summary> /// <param name="equality">The equality theorem to be handled.</param> /// <param name="helper">The normalization helper that verifies and normalizes the theorem.</param> /// <param name="scheduler">The scheduler of inference rules used for the new objects and theorems this equality might have brought.</param> /// <param name="proofData">Either the data needed to mark the theorem's inference in case it's correct; or null, if we are not constructing proofs.</param> /// <param name="isValid">Indicates whether the theorem has been found geometrically valid.</param> /// <param name="anyChangeOfNormalVersion">Indicates whether this equality caused any change of the normal version of some object.</param> private void HandleEquality(Theorem equality, NormalizationHelper helper, Scheduler scheduler, ProofData proofData, out bool isValid, out bool anyChangeOfNormalVersion) { // Mark the equality to the helper helper.MarkProvedEquality(equality, out var isNew, out isValid, out var result); // If it turns out not new or valid, we're done if (!isNew || !isValid) { // No removed objects anyChangeOfNormalVersion = false; // We're done return; } // If we should construct proof, mark the inference to the proof builder proofData?.ProofBuilder.AddImplication(proofData.InferenceData, equality, proofData.Assumptions); #region Handling new normalized theorems // Go through all of them foreach (var(originalTheorem, equalities, normalizedTheorem) in result.NormalizedNewTheorems) { // If we should construct proof, mark the normalized theorem to the proof builder proofData?.ProofBuilder.AddImplication(ReformulatedTheorem, normalizedTheorem, assumptions: equalities.Concat(originalTheorem).ToArray()); // Let the scheduler know about the new normalized theorem scheduler.ScheduleAfterProving(normalizedTheorem); } #endregion // Invalidate theorems result.DismissedTheorems.ForEach(scheduler.InvalidateTheorem); // Invalidate removed objects result.RemovedObjects.ForEach(scheduler.InvalidateObject); // Handle changed objects result.ChangedObjects.ForEach(changedObject => { // First we will invalidate them scheduler.InvalidateObject(changedObject); // And now schedule for them again as if they were knew because now the results of schedules might be different scheduler.ScheduleAfterDiscoveringObject(changedObject); }); // Handle entirely new objects result.NewObjects.ForEach(newObject => HandleNewObject(newObject, helper, scheduler, proofData?.ProofBuilder)); // Set if there has been any change of normal version, which is indicated by removing // an object or changing its normal version anyChangeOfNormalVersion = result.RemovedObjects.Any() || result.ChangedObjects.Any(); }
/// <summary> /// Handles an inferred theorem by communicating it with the normalization helper and scheduler, and also handling proof /// construction is the proof data is provided. /// </summary> /// <param name="theorem">The theorem to be handled.</param> /// <param name="helper">The normalization helper that verifies and normalizes the theorem.</param> /// <param name="scheduler">The scheduler of inference rules used for the theorem if it is correct.</param> /// <param name="proofData">Either the data needed to mark the theorem's inference in case it's correct; or null, if we are not constructing proofs.</param> /// <param name="isValid">Indicates whether the theorem has been found geometrically valid.</param> private void HandleNonequality(Theorem theorem, NormalizationHelper helper, Scheduler scheduler, ProofData proofData, out bool isValid) { // Mark the theorem to the helper helper.MarkProvedNonequality(theorem, out var isNew, out isValid, out var normalizedTheorem, out var equalities); // If it turns out not new or valid, we're done if (!isNew || !isValid) { return; } #region Handle proof construction // Mark the original theorem proofData?.ProofBuilder.AddImplication(proofData.InferenceData, theorem, proofData.Assumptions); // If any normalization happened if (equalities.Any()) { // Mark the normalized theorem too proofData?.ProofBuilder.AddImplication(ReformulatedTheorem, normalizedTheorem, assumptions: equalities.Concat(theorem).ToArray()); } #endregion // Let the scheduler know scheduler.ScheduleAfterProving(normalizedTheorem); #region Inference from symmetry // If the theorem use an object that is not part of the original configuration, // then we will not do any symmetry inference. If it could prove a new theorem, // then this new theorem would be inferable conventionally if (!normalizedTheorem.GetInnerConfigurationObjects().All(helper.Configuration.AllObjects.Contains)) { return; } // Otherwise try to infer new theorems using this one foreach (var inferredTheorem in normalizedTheorem.InferTheoremsFromSymmetry(helper.Configuration)) { // If it can be done, make sure the proof builder knows it proofData?.ProofBuilder.AddImplication(InferableFromSymmetry, inferredTheorem, assumptions: new[] { normalizedTheorem }); // Call this method to handle this new inferred theorem, without caring if it is valid (it should be logically) HandleNonequality(inferredTheorem, helper, scheduler, proofData, isValid: out var _); } #endregion }