@@ -37,9 +37,41 @@ RewriteSystem::~RewriteSystem() {
3737 Context.RuleTrieRootHistogram );
3838}
3939
40+ // / Initialize the rewrite system using rewrite rules built by the RuleBuilder.
41+ // /
42+ // / - recordLoops: Whether this is a rewrite system built from user-written
43+ // / requirements, in which case we will perform minimization using rewrite
44+ // / loops recorded during completion.
45+ // /
46+ // / - protos: If this is a rewrite system built from a protocol connected
47+ // / component, this contains the members of the protocol. For a rewrite
48+ // / system built from a generic signature, this is empty. Used by
49+ // / RewriteSystem::isInMinimizationDomain().
50+ // /
51+ // / These parameters should be populated from the corresponding fields of the
52+ // / RuleBuilder instance:
53+ // /
54+ // / - writtenRequirements: The user-written requirements, if any, used to
55+ // / track source locations for redundancy diagnostics.
56+ // /
57+ // / - importedRules: Rewrite rules for referenced protocols. These come from
58+ // / the Requirement Machine instances for these protocols' connected
59+ // / components, so they are already confluent and can be imported verbatim.
60+ // /
61+ // / - permanentRules: Permanent rules, such as associated type introduction
62+ // / rules for associated types defined in protocols in this connected
63+ // / component.
64+ // /
65+ // / - requirementRules: Rules corresponding to generic requirements written
66+ // / by the user.
67+ // /
68+ // / This can only be called once. It adds the rules to the rewrite system,
69+ // / allowing computeConfluentCompletion() to be called to compute the
70+ // / complete rewrite system.
4071void RewriteSystem::initialize (
4172 bool recordLoops, ArrayRef<const ProtocolDecl *> protos,
4273 ArrayRef<StructuralRequirement> writtenRequirements,
74+ std::vector<Rule> &&importedRules,
4375 std::vector<std::pair<MutableTerm, MutableTerm>> &&permanentRules,
4476 std::vector<std::tuple<MutableTerm, MutableTerm, Optional<unsigned >>>
4577 &&requirementRules) {
@@ -50,6 +82,36 @@ void RewriteSystem::initialize(
5082 Protos = protos;
5183 WrittenRequirements = writtenRequirements;
5284
85+ // Pre-populate our rules vector with the list of imported rules, and note
86+ // the position of the first local (not imported) rule.
87+ Rules = std::move (importedRules);
88+ FirstLocalRule = Rules.size ();
89+
90+ // Add the imported rules to the trie.
91+ for (unsigned newRuleID : indices (Rules)) {
92+ const auto &newRule = Rules[newRuleID];
93+ // Skip simplified rules. At the very least we need to skip RHS-simplified
94+ // rules since their left hand sides might duplicate existing rules; the
95+ // others are skipped purely as an optimization.
96+ if (newRule.isLHSSimplified () ||
97+ newRule.isRHSSimplified () ||
98+ newRule.isSubstitutionSimplified ())
99+ continue ;
100+
101+ auto oldRuleID = Trie.insert (newRule.getLHS ().begin (),
102+ newRule.getLHS ().end (),
103+ newRuleID);
104+ if (oldRuleID) {
105+ llvm::errs () << " Imported rules have duplicate left hand sides!\n " ;
106+ llvm::errs () << " New rule #" << newRuleID << " : " << newRule << " \n " ;
107+ const auto &oldRule = getRule (*oldRuleID);
108+ llvm::errs () << " Old rule #" << *oldRuleID << " : " << oldRule << " \n\n " ;
109+ dump (llvm::errs ());
110+ abort ();
111+ }
112+ }
113+
114+ // Now add our own rules.
53115 for (const auto &rule : permanentRules)
54116 addPermanentRule (rule.first , rule.second );
55117
0 commit comments