1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the constraint compiler.
5 ///////////////////////////////////////////////////////////////////////////////
7 #include <AD/strings/quark.h>
10 #include "constraint.ph"
15 #include "logicgen.ph"
17 #include "datatype.ph"
20 ///////////////////////////////////////////////////////////////////////////////
22 // Method for generating the interface methods for a logic
24 ///////////////////////////////////////////////////////////////////////////////
25 void DatatypeClass::generate_logic_interface(CodeGen&) {}
26 void DatatypeClass::generate_logic_implementation(CodeGen&, Tys, DefKind) {}
28 ///////////////////////////////////////////////////////////////////////////////
30 // Constructor for the constraint compiler implementation
32 ///////////////////////////////////////////////////////////////////////////////
33 ConstraintCompilerInternal::ConstraintCompilerInternal (Id id)
35 rule_map (string_hash,string_equal),
36 typing_map (string_hash,string_equal),
37 instness_map (string_hash,string_equal),
38 det_map (string_hash,string_equal)
42 ///////////////////////////////////////////////////////////////////////////////
44 // Destructor for the constraint compiler implementation
46 ///////////////////////////////////////////////////////////////////////////////
47 ConstraintCompilerInternal::~ConstraintCompilerInternal() {}
49 ///////////////////////////////////////////////////////////////////////////////
51 // Method to compile a set of constraint rules
53 ///////////////////////////////////////////////////////////////////////////////
54 void ConstraintCompiler::compile_ruleset (Id id, ConstraintSet rule_set)
56 ConstraintCompilerInternal G(id);
59 ////////////////////////////////////////////////////////////////////////////
63 ////////////////////////////////////////////////////////////////////////////
64 ConstraintRules rules = #[];
65 List<.[Id, Ty]> typing_rules = #[];
66 List<.[Id, Pat]> instness_rules = #[];
67 List<.[Id, Pats, Determinism]> det_rules = #[];
69 ////////////////////////////////////////////////////////////////////////////
71 // Partition the rules by kind.
73 ////////////////////////////////////////////////////////////////////////////
76 { ConstraintDefs ds = defs;
80 CONSTRAINTruledef r: { rules = #[r ... rules]; }
81 | CONSTRAINTtype(id,ty):
82 { typing_rules = #[.(id,ty) ... typing_rules]; }
83 | CONSTRAINTinstness(id,pat):
84 { instness_rules = #[.(id,pat) ... instness_rules]; }
85 | CONSTRAINTdet(id,pats,det):
86 { det_rules = #[.(id,pats,det) ... det_rules]; }
95 typing_rules = rev(typing_rules);
96 instness_rules = rev(instness_rules);
97 det_rules = rev(det_rules);
99 ////////////////////////////////////////////////////////////////////////////
101 // Process each kind of rules.
103 ////////////////////////////////////////////////////////////////////////////
104 process_typing_rules(id, typing_rules);
105 process_ruleset(id, rules);
107 ////////////////////////////////////////////////////////////////////////////
109 // Translate the rules into constraint abstract machine instructions.
111 ////////////////////////////////////////////////////////////////////////////
114 ///////////////////////////////////////////////////////////////////////////////
116 // Method to add a predicate : type judgement into the typing map.
118 ///////////////////////////////////////////////////////////////////////////////
119 void ConstraintCompiler::add_predicate_type(Id id, Ty ty)
120 { HashTable::Entry * e = internal->typing_map.lookup(id);
122 { Ty old_ty = Ty(internal->typing_map.value(e));
123 if (! unify(ty,old_ty))
124 { error("%Lpredicate %s: expecting type %T but found %T\n",
128 { internal->typing_map.insert(id,ty);
132 ///////////////////////////////////////////////////////////////////////////////
134 // Method to process the typing rules.
136 ///////////////////////////////////////////////////////////////////////////////
137 void ConstraintCompiler::process_typing_rules(Id id, List<.[Id,Ty]> typing_rules)
138 { match while (typing_rules)
139 { #[.(id,ty) ... rest]:
140 { add_predicate_type(id,ty); typing_rules = rest; }
144 ///////////////////////////////////////////////////////////////////////////////
146 // Method to partition a set of constraint rules by functor name and type.
148 ///////////////////////////////////////////////////////////////////////////////
149 void ConstraintCompiler::process_ruleset(Id id, ConstraintRules rules)
151 ////////////////////////////////////////////////////////////////////////////
153 // Perform type checking on each of the rule.
155 ////////////////////////////////////////////////////////////////////////////
156 for_each (ConstraintRule, r, rules)
158 { CONSTRAINTrule { id, pat, body, ty }:
162 HashTable::Entry * e = internal->rule_map.lookup(id);
164 // Infer the type of pattern.
165 ty = mkfunty(type_of(pat),mktypety());
166 add_predicate_type(id,ty);
168 // Insert into the type
169 if (e) // append rule
170 { ConstraintRules old_rules = ConstraintRules(e->v);
172 #[ CONSTRAINTrule { ty = old_ty ... } ... _ ]:
173 { if (! unify(ty,old_ty))
174 { error("%Ltype mismatch in rule %s%p\n"
175 "%Lexpecting %T but found %T\n",
176 id, pat, old_ty, ty);
181 internal->rule_map.insert(id,#[r ... old_rules]);
182 } else // insert new rule
183 { internal->rule_map.insert(id,#[r]);
189 ////////////////////////////////////////////////////////////////////////////
191 // Makes sure all the rules have all the type information annotated.
193 ////////////////////////////////////////////////////////////////////////////
194 for_each (ConstraintRule, R, rules)
196 { CONSTRAINTrule { id, pat, body, ty }:
198 // Check to make sure it has all the type information.
200 { error("%Lmissing type info in rule: %s%p : %T\n", id, pat, ty); }
201 pat = unifier_of(pat);
202 debug_msg("%s %p :- ...\n", id, pat);