private boolean simplifyRules() {
		boolean simplifyPerformed = true;
        final List<RuleConstraint<T>> addedRules = new ArrayList<RuleConstraint<T>>();
        final Analyze<T> analyze = new Analyze<T>() {
            @Override
            public int getDepth() {
                return GameAnalyze.this.getDepth();
            }

            @Override
            public void addRule(RuleConstraint<T> rule) {
                addedRules.add(rule);
            }

            @Override
            public GroupValues<T> getKnownValues() {
                return GameAnalyze.this.getKnownValues();
            }
        };
        RuleListener<T> ruleListener = new RuleListener<T>() {
            @Override
            public void onValueSet(FieldGroup<T> group, int value) {
                listener.onValueSet(analyze, group, value);
            }
        };
        while (simplifyPerformed) {
			simplifyPerformed = false;
			Iterator<RuleConstraint<T>> it = rules.iterator();
			while (it.hasNext()) {
				RuleConstraint<T> ruleSimplify = it.next();
				SimplifyResult simplifyResult = ruleSimplify.simplify(knownValues, ruleListener);
				if (simplifyResult == SimplifyResult.SIMPLIFIED) {
					simplifyPerformed = true;
				}
				else if (simplifyResult.isFailure()) {
					return false;
				}
				if (ruleSimplify.isEmpty()) {
					it.remove();
				}
			}
            if (!addedRules.isEmpty()) {
                this.rules.addAll(addedRules);
                // as rules have been added, we need to split into field groups again
                AnalyzeFactory.splitFieldRules(this.rules);
                addedRules.clear();
                simplifyPerformed = true;
            }
		}
		return true;
	}