@@ -13,7 +13,7 @@ use crate::ascent_syntax::{
13
13
RuleNode , Signatures ,
14
14
} ;
15
15
use crate :: syn_utils:: { expr_get_vars, pattern_get_vars} ;
16
- use crate :: utils:: { expr_to_ident, is_wild_card, tuple_type} ;
16
+ use crate :: utils:: { dedup_all_keep_last_by , expr_to_ident, is_wild_card, tuple_type} ;
17
17
18
18
#[ derive( Clone ) ]
19
19
pub ( crate ) struct AscentConfig {
@@ -233,8 +233,12 @@ pub(crate) fn compile_ascent_program_to_hir(prog: &AscentProgram, is_parallel: b
233
233
let mut relations_metadata = HashMap :: with_capacity ( num_relations) ;
234
234
// let mut relations_no_indices = HashMap::new();
235
235
let mut lattices_full_indices = HashMap :: new ( ) ;
236
- for rel in prog. relations . iter ( ) {
237
- let rel_identity = RelationIdentity :: from ( rel) ;
236
+
237
+ let mut rel_identities = prog. relations . iter ( ) . map ( |rel| ( rel, RelationIdentity :: from ( rel) ) ) . collect_vec ( ) ;
238
+ dedup_all_keep_last_by ( & mut rel_identities, |x, y| RelationIdentity :: eq ( & x. 1 , & y. 1 ) ) ;
239
+
240
+ for ( rel, rel_identity) in rel_identities {
241
+ let ds_attribute = get_ds_attr ( & rel. attrs ) ?;
238
242
239
243
if rel. is_lattice {
240
244
let indices = ( 0 ..rel_identity. field_types . len ( ) - 1 ) . collect_vec ( ) ;
@@ -252,9 +256,8 @@ pub(crate) fn compile_ascent_program_to_hir(prog: &AscentProgram, is_parallel: b
252
256
if let Some ( init_expr) = & rel. initialization {
253
257
relations_initializations. insert ( rel_identity. clone ( ) , Rc :: new ( init_expr. clone ( ) ) ) ;
254
258
}
255
- let ds_attribute = get_ds_attr ( & rel. attrs ) ?;
256
-
257
- let ds_attribute = match ( ds_attribute, rel. is_lattice ) {
259
+
260
+ let ds_attr = match ( ds_attribute, rel. is_lattice ) {
258
261
( None , true ) => None ,
259
262
( None , false ) => Some ( config. default_ds . clone ( ) ) ,
260
263
( Some ( attr) , true ) =>
@@ -273,7 +276,7 @@ pub(crate) fn compile_ascent_program_to_hir(prog: &AscentProgram, is_parallel: b
273
276
. cloned ( )
274
277
. collect_vec ( ) ,
275
278
) ,
276
- ds_attr : ds_attribute ,
279
+ ds_attr,
277
280
} ) ;
278
281
// relations_no_indices.insert(rel_identity, rel_no_index);
279
282
}
@@ -449,13 +452,9 @@ fn compile_rule_to_ir_rule(rule: &RuleNode, prog: &AscentProgram) -> syn::Result
449
452
let mut head_clauses = vec ! [ ] ;
450
453
for hcl_node in rule. head_clauses . iter ( ) {
451
454
let hcl_node = hcl_node. clause ( ) ;
452
- let rel = prog. relations . iter ( ) . find ( |r| hcl_node. rel == r. name ) ;
453
- let rel = match rel {
454
- Some ( rel) => rel,
455
- None => return Err ( Error :: new ( hcl_node. rel . span ( ) , format ! ( "relation `{}` is not defined" , hcl_node. rel) ) ) ,
456
- } ;
457
-
455
+ let rel = prog_get_relation ( prog, & hcl_node. rel , hcl_node. args . len ( ) ) ?;
458
456
let rel = RelationIdentity :: from ( rel) ;
457
+
459
458
let head_clause = IrHeadClause {
460
459
rel,
461
460
args : hcl_node. args . iter ( ) . cloned ( ) . collect ( ) ,
@@ -514,7 +513,7 @@ pub fn get_indices_given_grounded_variables(args: &[Expr], vars: &[Ident]) -> Ve
514
513
pub ( crate ) fn prog_get_relation < ' a > (
515
514
prog : & ' a AscentProgram , name : & Ident , arity : usize ,
516
515
) -> syn:: Result < & ' a RelationNode > {
517
- let relation = prog. relations . iter ( ) . find ( |r| name == & r. name ) ;
516
+ let relation = prog. relations . iter ( ) . rev ( ) . find ( |r| name == & r. name ) ;
518
517
match relation {
519
518
Some ( rel) =>
520
519
if rel. field_types . len ( ) != arity {
0 commit comments