New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicate rules and sentences in compiled output #3906
Comments
Related: #3540 |
The most common cause of duplicated sentences in the frontend is due to incorrectly implemented functions which call If it does indeed prove to be specific to sort predicates, the most likely explanation is that we're declaring the same sort in multiple modules and then combining those modules later. It might be worth making sorts unable to be redeclared explicitly or implicitly. |
Hmmmm, perhaps here we are using
|
That class only adds the sentence if it doesn't already exist in one of its submodules, so it should be fine. You were noticing duplicated rules in the example you mentioned above; that pass only adds productions. Did you see duplicated productions also? |
Related to the compiler pipeline auditing in #3891 |
I've found that the diff --git a/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateRules.java b/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateRules.java
index 9ec11724e1..fa49185a5c 100644
--- a/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateRules.java
+++ b/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateRules.java
@@ -43,7 +43,7 @@ public class GenerateSortPredicateRules {
mod.imports(),
(Set<Sentence>)
mod.localSentences()
- .$bar(stream(mod.allSorts()).flatMap(this::gen).collect(Collections.toSet())),
+ .$bar(stream(mod.localSorts()).flatMap(this::gen).collect(Collections.toSet())),
mod.att());
}
diff --git a/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateSyntax.java b/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateSyntax.java
index f1a5b0b757..485a2c0252 100644
--- a/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateSyntax.java
+++ b/kernel/src/main/java/org/kframework/compile/GenerateSortPredicateSyntax.java
@@ -20,7 +20,7 @@ public class GenerateSortPredicateSyntax {
public Module gen(Module mod) {
Set<Sentence> res = new HashSet<>();
- for (Sort sort : iterable(mod.allSorts())) {
+ for (Sort sort : iterable(mod.localSorts())) {
res.addAll(gen(mod, sort));
}
if (!res.isEmpty()) {
diff --git a/kore/src/main/scala/org/kframework/definition/outer.scala b/kore/src/main/scala/org/kframework/definition/outer.scala
index 3afffbc43c..23f8e93e1a 100644
--- a/kore/src/main/scala/org/kframework/definition/outer.scala
+++ b/kore/src/main/scala/org/kframework/definition/outer.scala
@@ -342,11 +342,19 @@ case class Module(
private def mergeAttributes[T <: Sentence](p: Set[T]) =
Att.mergeAttributes(p.map(_.att))
+ private def sortsFromSentences(s: Set[Sentence]) =
+ s.collect {
+ case SyntaxSort(_, sort, _) => sort
+ case p @ Production(_, _, sort, _, _) if !p.isSortVariable(sort) => sort
+ }
+
lazy val definedSorts: Set[SortHead] = (productions
.filter(p => !p.isSortVariable(p.sort))
.map(_.sort.head)) ++ (sortDeclarations.filter(s => s.params.isEmpty).map {
_.sort.head
}) ++ definedInstantiations.values.flatten.flatMap(_.params).filter(_.isNat).map(_.head)
+ lazy val importedSorts: Set[Sort] = sortsFromSentences(importedSentences)
+ lazy val localSorts: Set[Sort] = sortsFromSentences(localSentences) -- importedSorts
lazy val definedInstantiations: Map[SortHead, Set[Sort]] = {
val nonempty = ((productions
.filter { p => However, this solution doesn't work at the moment. If the definition uses any parameterized sorts like |
@gtrepta there is an |
Drafted a PR for this ^^^. There are still a number of duplicated rules after this, one reason for this is because a sort will be declared locally in multiple modules but not in any of those modules' imports, and the pipeline doesn't have a way to know whether or not the sort predicates in any of those modules will be necessary. Additionally, there are stages in the pipeline before sort predicate generation that add sort declarations of common sorts like K to the module and predicates for those will be added for the reason above. Interestingly, I also noticed that the pipeline is doing the predicate generation and some other stages more than once: k/kernel/src/main/java/org/kframework/backend/kore/KoreBackend.java Lines 248 to 259 in 2d40661
|
Interesting, well spotted @gtrepta! |
Unassigning myself after finishing my PR for this. There is still some work left to do based on my comment above. |
The work remaining here is to work out which passes in the compilation pipeline are declaring rules / productions over (say) the K sort; the compiler can't globally identify where there are redundancies and so ends up repeating work. |
Moving to the backlog for now as we've made some headway, but will need more of the ongoing work on the compiler pipeline to be resolved to make further progress here. |
Using the following definition:
I call
kompile test.k
, to get outputtest-kompiled/compiled.txt
.Then I search for a rule that looks like this (the
isK
sort predicate):And find that there are 50 occurrences of the same rule! This is not the only sort predicate with many duplicate occurrences.
Can we eliminate these duplicates by:
K
andKItem
andList
are declared early so their sort predicates only occur once?KSEQ
declares theisK
predicate, and moduleKSEQ-SYMBOLIC
importsKSEQ
but still also redeclares this sort predicate! So maybe there is a way to minimize the number of sentences directly already by not regenerating sort predicates if they already exist in imported modules.Example from
compiled.txt
(snipped):The text was updated successfully, but these errors were encountered: