@@ -359,6 +359,16 @@ impl Function {
359359 self . decl . internal_hidden
360360 }
361361
362+ /// Whether this table is a constructor or relation table.
363+ pub fn is_constructor ( & self ) -> bool {
364+ self . decl . subtype == FunctionSubtype :: Constructor
365+ }
366+
367+ /// Whether this constructor is excluded from ordinary extraction.
368+ pub fn is_unextractable ( & self ) -> bool {
369+ self . decl . unextractable
370+ }
371+
362372 /// The term-constructor name associated with this function table, if
363373 /// any. Set on view tables created by the term/proof encoding to refer
364374 /// back to the user-visible constructor name.
@@ -2242,6 +2252,30 @@ impl EGraph {
22422252 self . functions . get ( name)
22432253 }
22442254
2255+ /// Find the canonical representative of an eq-sort value.
2256+ ///
2257+ /// If `sort` does not have an internal union-find table, or if `value` is
2258+ /// not currently mapped in that table, this returns `value` unchanged.
2259+ pub fn canonical_value ( & self , sort : & ArcSort , value : Value ) -> Value {
2260+ let Some ( uf_name) = self . proof_state . uf_parent . get ( sort. name ( ) ) else {
2261+ return value;
2262+ } ;
2263+ let Some ( uf_func) = self . functions . get ( uf_name) else {
2264+ return value;
2265+ } ;
2266+
2267+ let mut canonical = value;
2268+ self . backend
2269+ . for_each ( uf_func. backend_id , |row : egglog_bridge:: ScanEntry | {
2270+ // The internal UF table stores `(child, parent)` and is kept at
2271+ // one hop to the canonical representative.
2272+ if row. vals [ 0 ] == value {
2273+ canonical = row. vals [ 1 ] ;
2274+ }
2275+ } ) ;
2276+ canonical
2277+ }
2278+
22452279 /// Returns `true` if a user-defined command with the given name is
22462280 /// registered in this e-graph.
22472281 pub fn has_command ( & self , name : & str ) -> bool {
0 commit comments