/Nyaya/Model/NyayaNode+Random.m

https://github.com/AleGit/NyPad · Objective C · 162 lines · 116 code · 38 blank · 8 comment · 27 complexity · e044f6957b636a64d6f3e6f3a314a201 MD5 · raw file

  1. //
  2. // NyayaNode+Random.m
  3. // Nyaya
  4. //
  5. // Created by Alexander Maringele on 27.09.12.
  6. // Copyright (c) 2012 private. All rights reserved.
  7. //
  8. #import "NyayaNode+Random.h"
  9. #import "NyayaNode_Cluster.h"
  10. #import "NyayaNode+Creation.h"
  11. #import "NyayaNode+Type.h"
  12. @interface NSArray (Random)
  13. - (id)randomObject:(NSUInteger)maxLength;
  14. @end
  15. @implementation NSArray (Random)
  16. - (id)randomObject:(NSUInteger)maxLength {
  17. if (maxLength == 0) maxLength = 1;
  18. NyayaNode *node = nil;
  19. do {
  20. NSUInteger xth = arc4random() % [self count];
  21. node = [self objectAtIndex:xth];
  22. }
  23. while (maxLength < [node length]);
  24. return node;
  25. }
  26. @end
  27. @interface NSIndexSet (Random)
  28. - (NSUInteger)randomIndex;
  29. @end
  30. @implementation NSIndexSet (Random)
  31. - (NSUInteger)randomIndex {
  32. NSUInteger xth = arc4random() % [self count];
  33. __block NSUInteger ith = 0;
  34. __block NSUInteger result = NSNotFound;
  35. [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
  36. if (ith == xth) {
  37. result = idx;
  38. *stop = YES;
  39. }
  40. ith++;
  41. }];
  42. return result;
  43. }
  44. @end
  45. @implementation NyayaNode (Random)
  46. + (NyayaNode*)randomTree {
  47. NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSetWithIndex:NyayaNegation];
  48. [indexSet addIndex:NyayaConjunction];
  49. [indexSet addIndex:NyayaDisjunction];
  50. [indexSet addIndex:NyayaImplication];
  51. return [NyayaNode randomTreeWithRootTypes:indexSet
  52. nodeTypes:indexSet
  53. lengths:NSMakeRange(1,11)
  54. variables:@[@"p",@"q",@"r"]];
  55. }
  56. + (NyayaNode *)randomTreeWithRootTypes:(NSIndexSet *)rootTypes
  57. nodeTypes:(NSIndexSet *)nodeTypes
  58. lengths:(NSRange)lengths
  59. variables:(NSArray *)variables {
  60. if (!nodeTypes) nodeTypes = rootTypes;
  61. NyayaNode* result = nil;
  62. NyayaNode* first = nil;
  63. NyayaNode* second = nil;
  64. NSUInteger minLength = lengths.location;
  65. NSUInteger maxLength = lengths.location + lengths.length;
  66. if (minLength < maxLength)
  67. minLength += arc4random() % lengths.length;
  68. // NyayaNodeType rootType = (NyayaNodeType)[rootTypes randomIndex];
  69. NSMutableArray *subTrees = [NSMutableArray arrayWithCapacity:maxLength];
  70. for (NSString *var in variables) {
  71. [subTrees addObject:[NyayaNode atom:var]];
  72. }
  73. if ([subTrees count] == 0) {
  74. [subTrees addObject:[NyayaNode atom:@"T"]];
  75. [subTrees addObject:[NyayaNode atom:@"F"]];
  76. }
  77. NyayaNodeType rootType = [rootTypes randomIndex];
  78. NyayaNodeType type = rootType;
  79. if (maxLength < 2 && 0 < [subTrees count]) return [subTrees randomObject:1];
  80. NSInteger outerLoopCount = 0;
  81. NSInteger resultLength = 0;
  82. do {
  83. resultLength = [result length];
  84. NSUInteger count = 0;
  85. do {
  86. if (type != NyayaConstant) {
  87. first = [subTrees randomObject: maxLength -1 - (type != NyayaNegation)];
  88. second = type != NyayaNegation ? [subTrees randomObject: maxLength - 1 - [first length]] : nil;
  89. }
  90. }
  91. while ([second isEqual: first] && ++count < [subTrees count]*3);
  92. switch (type) {
  93. case NyayaNegation:
  94. result = [NyayaNode negation:first];
  95. break;
  96. case NyayaDisjunction:
  97. result = [NyayaNode conjunction:first with:second];
  98. break;
  99. case NyayaConjunction:
  100. result = [NyayaNode disjunction:first with:second];
  101. break;
  102. case NyayaXdisjunction:
  103. result = [NyayaNode xdisjunction:first with:second];
  104. break;
  105. case NyayaImplication:
  106. result = [NyayaNode implication:first with:second];
  107. break;
  108. case NyayaConstant:
  109. if (arc4random() % 2) result = [NyayaNode atom:@"T"];
  110. else result = [NyayaNode atom:@"F"];
  111. break;
  112. default:
  113. continue;
  114. }
  115. [subTrees addObject:result];
  116. type = [nodeTypes randomIndex];
  117. }
  118. while ([result length] < minLength && resultLength < [result length] && ++outerLoopCount < 150);
  119. if (!result || [result length] == 0) {
  120. result = [subTrees randomObject:maxLength];
  121. }
  122. return result;
  123. }
  124. @end