Skip to content

Commit 9ac972a

Browse files
memo33jflann
authored andcommitted
make loading of RHD/LHD rules more robust against duplicates or conflicts
1 parent 7410e11 commit 9ac972a

2 files changed

Lines changed: 17 additions & 19 deletions

File tree

src/main/scala/module/Rul2Model.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,11 @@ object Rul2Model {
102102
case Some((rule, RhdAndLhd)) =>
103103
val key = new EquivRule(rule)
104104
if (!rulesShared.contains(key)) {
105-
if (!rulesRhd.contains(key) && !rulesLhd.contains(key))
106-
rulesShared.addOne(key, rule)
107-
else
108-
require(
109-
rulesRhd.contains(key) == rulesLhd.contains(key),
110-
s"There's an unexpected rule conflict that differs between RHD and LHD: $rule"
111-
)
105+
(rulesRhd.get(key).filterNot(rulesHaveSameOutput(rule, _)), rulesLhd.get(key).filterNot(rulesHaveSameOutput(rule, _))) match {
106+
case (None, None) => rulesShared.addOne(key, rule)
107+
case (Some(rule2), Some(rule3)) => // ignore, as both RHD/LHD already define a different rule, so this rule never has an effect
108+
case _ => require(false, s"There's an unexpected rule conflict that differs between RHD and LHD: $rule")
109+
}
112110
}
113111
case None => // ignore
114112
}
@@ -124,6 +122,17 @@ object Rul2Model {
124122
lookupRule.unapply(key).flatMap(rule => applyRule(rule, t0, t1))
125123
}
126124

125+
/** Check if two rules with equivalent LHS actually lead to the same output on
126+
* the RHS (and thus are not at conflict with each other).
127+
*/
128+
def rulesHaveSameOutput(x: Rule[IdTile], y: Rule[IdTile]): Boolean = (
129+
x(0) == y(0) && x(1) == y(1) && x(2) == y(2) && x(3) == y(3) ||
130+
x(0) == y(0) * R2F1 && x(1) == y(1) * R2F1 && x(2) == y(2) * R2F1 && x(3) == y(3) * R2F1 ||
131+
x(0) == y(1) * R2F0 && x(1) == y(0) * R2F0 && x(2) == y(3) * R2F0 && x(3) == y(2) * R2F0 ||
132+
x(0) == y(1) * R0F1 && x(1) == y(0) * R0F1 && x(2) == y(3) * R0F1 && x(3) == y(2) * R0F1 ||
133+
(x(2).id == 0 || x(3).id == 0) && (y(2).id == 0 || y(3).id == 0)
134+
)
135+
127136
}
128137

129138
/** Holds all RUL2 code in memory. Instantiate this with `Rul2Model.load`. */

src/main/scala/scripts/ConflictingOverridesChecker.scala

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import java.nio.file.{Files, Paths}
44
import io.github.memo33.metarules.meta.{RotFlip, EquivRule, Rule, IdTile}
55
import RotFlip._
66
import com.sc4nam.module._
7-
import Rul2Model.{iterateRulFiles, parseRuleWithRestrictedDriveside, Driveside, Rhd, Lhd, RhdAndLhd, drivesideOfFile}
7+
import Rul2Model.{iterateRulFiles, parseRuleWithRestrictedDriveside, Driveside, Rhd, Lhd, RhdAndLhd, drivesideOfFile, rulesHaveSameOutput}
88
import SanityChecker.{fileEndsWithNewline, linePatternIncludingNewlines}
99

1010
/** Checks for conflicting/duplicate RUL2 code. There are two modes of operation:
@@ -183,15 +183,4 @@ object ConflictingOverridesChecker {
183183
if (add.isDefined) s"$line0; ${add.get}" else line0
184184
}
185185

186-
/** Check if two rules with equivalent LHS actually lead to the same output on
187-
* the RHS (and thus are not at conflict with each other).
188-
*/
189-
def rulesHaveSameOutput(x: Rule[IdTile], y: Rule[IdTile]): Boolean = (
190-
x(0) == y(0) && x(1) == y(1) && x(2) == y(2) && x(3) == y(3) ||
191-
x(0) == y(0) * R2F1 && x(1) == y(1) * R2F1 && x(2) == y(2) * R2F1 && x(3) == y(3) * R2F1 ||
192-
x(0) == y(1) * R2F0 && x(1) == y(0) * R2F0 && x(2) == y(3) * R2F0 && x(3) == y(2) * R2F0 ||
193-
x(0) == y(1) * R0F1 && x(1) == y(0) * R0F1 && x(2) == y(3) * R0F1 && x(3) == y(2) * R0F1 ||
194-
(x(2).id == 0 || x(3).id == 0) && (y(2).id == 0 || y(3).id == 0)
195-
)
196-
197186
}

0 commit comments

Comments
 (0)