/// <summary> /// Copies the candidate graph, transfers the L-mapping, and returns the resultant candidate. /// </summary> public candidate CopyAndApplyOption(option opt, candidate cand, bool doMinimize) { var newCand = cand.copy(); var newOpt = opt.copy(); SearchProcess.transferLmappingToChild(newCand.graph, cand.graph, newOpt); ApplyOption(newOpt, newCand, doMinimize); return(newCand); }
/// <summary> /// Does a full invalidation check through empirical evidence. That is, it makes /// a copy of the graph and tests to see if this is true. /// </summary> /// <param name="p">The p.</param> /// <param name="q">The q.</param> /// <param name="cand">The cand.</param> /// <returns></returns> static int fullInvalidationCheck(option p, option q, candidate cand) { var testGraph = cand.graph.copy(); var qCopy = q.copy(); var pCopy = p.copy(); SearchProcess.transferLmappingToChild(testGraph, cand.graph, pCopy); SearchProcess.transferLmappingToChild(testGraph, cand.graph, qCopy); pCopy.apply(testGraph, null); var newOptions = q.rule.recognize(testGraph); if (newOptions.Any(newOpt => sameLocation(qCopy, newOpt))) { return(-1); } // find if there is an option in newOptions that is the SAME elements as q.location // then return false - p does NOT invalidate q return(1); }
/// <summary> /// Returns whether the graph violates angle or carboxyl-blocking constraints. /// </summary> private static bool IsValidChild(candidate cand, option opt) { var newCand = cand.copy(); var newOpt = opt.copy(); SearchProcess.transferLmappingToChild(newCand.graph, cand.graph, newOpt); newOpt.apply(newCand.graph, null); var mol = OBFunctions.designgraphtomol(newCand.graph); var mapping = OBFunctions.findcarboxylates(mol); if (mapping.Count < 2) { return(true); } var carbA = mol.GetAtom(mapping[0][1]); // carbon in carboxylate var aA = mol.GetAtom(mapping[0][3]); // atom that the carbon connects to var carbB = mol.GetAtom(mapping[1][1]); var aB = mol.GetAtom(mapping[1][3]); var pAngle = OBFunctions.pairwiseangle(carbA, aA, carbB, aB); // angle between carboxylates return(!OBFunctions.carboxylatesBlocked(mol, aA, carbA, aB, carbB) && pAngle >= AngleFloor); }
public static void Run(designGraph seed, grammarRule rule, Relaxation RelaxationTemplate = null) { try { if (RelaxationTemplate == null) { RelaxationTemplate = new Relaxation(0); } var rnd = new Random(); int k = 0; var continueTesting = true; SearchIO.output("begin recognizing rule: " + rule.name + "on graph :" + seed.name, 2); var dummyRS = new ruleSet(); dummyRS.Add(rule); if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } var options = dummyRS.recognize(seed, false, RelaxationTemplate.copy()); if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } var numOptions = options.Count; if (numOptions == 0) { if (MessageBox.Show("There were no recognized options. Should the rule be relaxed?", "Test Rule Status", MessageBoxButton.YesNo, MessageBoxImage.Asterisk, MessageBoxResult.No) == MessageBoxResult.Yes) { Run(seed, rule, new Relaxation(RelaxationTemplate.NumberAllowable + 1)); } return; } do { var status = "There "; int choice = -1; switch (numOptions) { case 0: throw new Exception("Should not be able to reach here. (Test Rule Chooser, zero options.)"); case 1: status += "was only one recognized option and it applied as shown.\n"; choice = 0; status += options[choice].Relaxations.RelaxationSummary; break; default: status += "were " + numOptions + " recognized locations.\n"; choice = rnd.Next(options.Count); status += options[choice].Relaxations.RelaxationSummary; option.AssignOptionConfluence(options, new candidate(seed, 0), ConfluenceAnalysis.Full); var numberWithConfluence = options.Count(o => (o.confluence.Count > 0)); var maxConfluence = options.Max(o => o.confluence.Count); var withMaxConfluence = options.Count(o => (o.confluence.Count == maxConfluence)); if (numberWithConfluence > 0) { status += "Confluence existed between " + numberWithConfluence + " of them"; if (maxConfluence > 1) { status += "; \nwith " + withMaxConfluence + " options having a confluence with " + maxConfluence + " other options.\n"; } else { status += ".\n"; } } status += "Option #" + choice + " was randomly chosen, and invoked.\n"; break; } if (!continueTesting) { continue; } if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } var chosenOption = options[choice]; { var seedCopy = seed.copy(); SearchProcess.transferLmappingToChild(seedCopy, seed, chosenOption); seed = seedCopy; } chosenOption.apply(seed, null); SearchIO.output("Rule sucessfully applied", 4); SearchIO.addAndShowGraphWindow(seed, "After calling " + ++k + " rules"); if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } options = dummyRS.recognize(seed, true, RelaxationTemplate.copy()); if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } numOptions = options.Count; switch (numOptions) { case 0: status += "There are no recognized locations on the new graph"; continueTesting = false; MessageBox.Show(status, "Test Rule Status", MessageBoxButton.OK, MessageBoxImage.Asterisk); break; case 1: status += "There is one recognized location on the new graph. Would you like to invoke it?"; continueTesting = (MessageBox.Show(status, "Continue Applying?", MessageBoxButton.YesNo, MessageBoxImage.Asterisk, MessageBoxResult.No) == MessageBoxResult.Yes); break; default: status += "There are " + options.Count + " recognized locations on the new graph. Would you " + "like to randomly invoke one?"; continueTesting = (MessageBox.Show(status, "Continue Applying?", MessageBoxButton.YesNo, MessageBoxImage.Asterisk, MessageBoxResult.No) == MessageBoxResult.Yes); break; } } while (continueTesting); } catch (Exception exc) { ErrorLogger.Catch(exc); } }