Skip to content

Commit 5eb1b9d

Browse files
author
Jesus Lapastora Núñez
committed
[wip] annotate & arrange processing order (dependency lists)
Only done for if branches. Should be done for the rest, slowly.
1 parent 9ec5b21 commit 5eb1b9d

File tree

2 files changed

+105
-76
lines changed

2 files changed

+105
-76
lines changed

engine/baml-lib/ast/src/ast/baml_vis/graph.rs

Lines changed: 102 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,12 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
239239

240240
// NOTE: we may wont to make the caches have more lifetime
241241
// than build so that we can return &'cache [NodeId] after writing.
242+
// TODO: in process of changing signature so that it does not return anything & we just get
243+
// from the built cache.
242244
fn build_header(
243245
&mut self,
244246
hid: Hid,
247+
// TODO: understand why this exists!
245248
visited_scopes: &mut HashSet<ScopeId>,
246249
parent_cluster: Option<ClusterId>,
247250
) -> (NodeId, Vec<NodeId>) {
@@ -260,11 +263,8 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
260263
.get(&hid)
261264
.map(Vec::as_slice)
262265
.unwrap_or(&[]);
263-
let has_md = !md_children.is_empty();
264-
let has_nested = !nested_children.is_empty();
265-
let is_branching = header.label_kind == HeaderLabelKind::If;
266266

267-
if !has_md && !has_nested {
267+
if md_children.is_empty() && nested_children.is_empty() {
268268
let node_id = self.new_node_id();
269269
let span = SerializedSpan::serialize(&header.span);
270270
self.span_map.insert(node_id, span.clone());
@@ -282,65 +282,19 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
282282
return (node_id, vec![node_id]);
283283
}
284284

285-
let total_children = md_children.len() + nested_children.len();
286-
let mut single_nested_child_has_multiple_items = false;
287-
if nested_children.len() == 1 {
288-
let child_root = self.by_hid[&nested_children[0]];
289-
let count = self.index.headers_in_scope_iter(child_root.scope).count();
290-
single_nested_child_has_multiple_items = count > 1;
291-
}
292-
let should_flatten = !is_branching
293-
&& total_children <= MAX_CHILDREN_TO_FLATTEN
294-
&& !(nested_children.len() == 1 && single_nested_child_has_multiple_items);
295-
296-
if should_flatten {
297-
let node_id = self.new_node_id();
298-
let span = SerializedSpan::serialize(&header.span);
299-
self.span_map.insert(node_id, span.clone());
300-
let kind = if is_branching {
301-
NodeKind::Decision(hid, Some(span.clone()))
302-
} else {
303-
NodeKind::Header(hid, Some(span.clone()))
304-
};
305-
self.graph.nodes.push(Node {
306-
id: node_id,
307-
label: header.title.as_ref(),
308-
kind,
309-
cluster: parent_cluster,
310-
});
311-
self.header_entry.insert(hid, node_id);
312-
let exits = if md_children.len() == 1 {
313-
let (c_entry, c_exits) =
314-
self.build_header(md_children[0], visited_scopes, parent_cluster);
315-
self.graph.edges.push(Edge {
316-
from: node_id,
317-
to: c_entry,
318-
});
319-
c_exits
320-
} else if nested_children.len() == 1 {
321-
let child_root_hid = nested_children[0];
322-
let child_scope = self.by_hid[&child_root_hid].scope;
323-
self.build_scope_sequence(child_scope, visited_scopes, parent_cluster);
324-
let (c_entry, c_exits) =
325-
self.build_header(child_root_hid, visited_scopes, parent_cluster);
326-
self.graph.edges.push(Edge {
327-
from: node_id,
328-
to: c_entry,
329-
});
330-
c_exits
331-
};
332-
self.header_exits.insert(hid, exits);
333-
return (node_id, exits);
334-
}
285+
if header.label_kind == HeaderLabelKind::If {
286+
// pre-order/post-order notation:
287+
// <pre/post>-order: <name> [[output] <- <dependency list>]
335288

336-
if is_branching {
289+
// pre-order: assign cluster ids: cluster_id <- header, parent_cluster
337290
let cluster_id = self.new_cluster_id();
338291
self.graph.clusters.push(Cluster {
339292
id: cluster_id,
340293
label: header.title.as_ref(),
341294
parent: parent_cluster,
342295
});
343296

297+
// pre-order: insert entry <- header, cluster_id
344298
let decision_id = self.new_node_id();
345299
let span = SerializedSpan::serialize(&header.span);
346300
self.span_map.insert(decision_id, span.clone());
@@ -351,33 +305,56 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
351305
cluster: Some(cluster_id),
352306
});
353307
self.header_entry.insert(hid, decision_id);
308+
309+
// unordered: render_calls_for_header <- header_entry, cluster_id
310+
354311
if self.cfg.show_call_nodes {
355312
self.render_calls_for_header(hid, decision_id, Some(cluster_id));
356313
}
357314

358-
let mut branch_exits = Vec::new();
359-
for child_root_hid in nested_children.iter() {
360-
let child_scope = self.by_hid[child_root_hid].scope;
315+
// post-order: build scope sequence for scope & build header
316+
// header_entry, header_exit <- cluster_id.
317+
// For some reason it can't work without a visited_scopes? That's pre-order data.
318+
for child_root_id in nested_children {
319+
let child_scope = self.by_hid[child_root_id].scope;
361320
self.build_scope_sequence(child_scope, visited_scopes, Some(cluster_id));
362-
let (entry, exits) =
363-
self.build_header(*child_root_hid, visited_scopes, Some(cluster_id));
364-
self.graph.edges.push(Edge {
321+
self.build_header(*child_root_id, visited_scopes, Some(cluster_id));
322+
}
323+
324+
// post-order: build header for each of the markdown children <- cluster_id.
325+
// Same doubt wrt visited_scopes.
326+
for child in md_children {
327+
self.build_header(*child, visited_scopes, Some(cluster_id));
328+
}
329+
330+
// unordered: add edges from decision id to children <- decision_id
331+
self.graph
332+
.edges
333+
.extend(nested_children.iter().map(|child_root_id| Edge {
365334
from: decision_id,
366-
to: entry,
367-
});
368-
if self.cfg.show_call_nodes {
369-
self.render_calls_for_header(*child_root_hid, entry, Some(cluster_id));
335+
to: self.header_entry[child_root_id],
336+
}));
337+
338+
// unordered: render_calls_for_header <- header_entry, cluster_id
339+
if self.cfg.show_call_nodes {
340+
for child_root_hid in nested_children {
341+
self.render_calls_for_header(
342+
*child_root_hid,
343+
self.header_entry[child_root_hid],
344+
Some(cluster_id),
345+
);
370346
}
371-
branch_exits.extend(exits);
372347
}
373348

374-
// NOTE: here we discard the Vec<> from `build_header`!
375-
let md_ids_only: Vec<_> = md_children
349+
// post-order: collect branch exits <- header_exits
350+
let branch_exits: Vec<_> = nested_children
376351
.iter()
352+
.flat_map(|child_hid| &self.header_exits[child_hid])
377353
.copied()
378-
.map(|ch| self.build_header(ch, visited_scopes, Some(cluster_id)).0)
379354
.collect();
380355

356+
let md_ids_only: Vec<_> = md_children.iter().map(|ch| self.header_entry[ch]).collect();
357+
381358
if let Some(first_md) = md_ids_only.first().copied() {
382359
if !branch_exits.is_empty() {
383360
for e in branch_exits.iter() {
@@ -393,10 +370,11 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
393370
});
394371
}
395372
}
396-
for win in md_ids_only.windows(2) {
397-
let (a, b) = (&win[0], &win[1]);
398-
self.graph.edges.push(Edge { from: *a, to: *b });
399-
}
373+
self.graph.edges.extend(md_ids_only.windows(2).map(|win| {
374+
let from = win[0];
375+
let to = win[1];
376+
Edge { from, to }
377+
}));
400378
let outward = if let Some(last) = md_ids_only.last().copied() {
401379
vec![last]
402380
} else {
@@ -406,6 +384,54 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
406384
return (decision_id, outward);
407385
}
408386

387+
let single_nested_child_has_multiple_items = nested_children.len() == 1 && {
388+
let child_root = self.by_hid[&nested_children[0]];
389+
let count = self.index.headers_in_scope_iter(child_root.scope).count();
390+
count > 1
391+
};
392+
393+
let total_children = md_children.len() + nested_children.len();
394+
395+
let should_flatten =
396+
total_children <= MAX_CHILDREN_TO_FLATTEN && !single_nested_child_has_multiple_items;
397+
398+
if should_flatten {
399+
let node_id = self.new_node_id();
400+
let span = SerializedSpan::serialize(&header.span);
401+
self.span_map.insert(node_id, span.clone());
402+
self.graph.nodes.push(Node {
403+
id: node_id,
404+
label: header.title.as_ref(),
405+
kind: NodeKind::Header(hid, Some(span.clone())),
406+
cluster: parent_cluster,
407+
});
408+
self.header_entry.insert(hid, node_id);
409+
let exits = if md_children.len() == 1 {
410+
let (c_entry, c_exits) =
411+
self.build_header(md_children[0], visited_scopes, parent_cluster);
412+
self.graph.edges.push(Edge {
413+
from: node_id,
414+
to: c_entry,
415+
});
416+
c_exits
417+
} else if nested_children.len() == 1 {
418+
let child_root_hid = nested_children[0];
419+
let child_scope = self.by_hid[&child_root_hid].scope;
420+
self.build_scope_sequence(child_scope, visited_scopes, parent_cluster);
421+
let (c_entry, c_exits) =
422+
self.build_header(child_root_hid, visited_scopes, parent_cluster);
423+
self.graph.edges.push(Edge {
424+
from: node_id,
425+
to: c_entry,
426+
});
427+
c_exits
428+
} else {
429+
vec![node_id]
430+
};
431+
self.header_exits.insert(hid, exits.clone());
432+
return (node_id, exits);
433+
}
434+
409435
let cluster_id = self.new_cluster_id();
410436
self.graph.clusters.push(Cluster {
411437
id: cluster_id,
@@ -415,6 +441,7 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
415441
});
416442

417443
// Merge markdown children and direct nested roots, preserving each list's internal order
444+
// NOTE: we could do this merge beforehand! & get both nested & md_children.
418445
let items_merged = merge_by_pos(self.by_hid, &md_children, &nested_children);
419446

420447
let mut first_rep: Option<_> = None;
@@ -472,6 +499,8 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
472499
(entry, exits)
473500
}
474501

502+
/// If header is in [`HeaderIndex::header_calls`], inserts & links a call node to the
503+
/// given header node.
475504
fn render_calls_for_header(
476505
&mut self,
477506
hid: Hid,

engine/baml-lib/baml/tests/validation_files/headers/nested_if_statements.mmd

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@ flowchart TD
4545
end
4646
n3 --> n4
4747
n3 --> n5
48-
n2 --> n3
4948
n6 --> n7
5049
n6 --> n8
50+
n2 --> n3
5151
n2 --> n6
52-
n1 --> n2
5352
n10 --> n11
5453
n10 --> n12
55-
n9 --> n10
5654
n13 --> n14
5755
n13 --> n15
56+
n9 --> n10
5857
n9 --> n13
58+
n1 --> n2
5959
n1 --> n9
6060
n0 --> n1
6161
%%__BAML_SPANMAP__={"n0":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":0,"start":0,"end_line":1,"end":0},"n1":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":2,"start":4,"end_line":3,"end":0},"n2":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":5,"start":8,"end_line":6,"end":0},"n3":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":7,"start":12,"end_line":8,"end":0},"n4":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":9,"start":16,"end_line":10,"end":0},"n5":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":12,"start":16,"end_line":13,"end":0},"n6":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":18,"start":12,"end_line":19,"end":0},"n7":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":20,"start":16,"end_line":21,"end":0},"n8":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":23,"start":16,"end_line":24,"end":0},"n9":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":31,"start":8,"end_line":32,"end":0},"n10":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":33,"start":12,"end_line":34,"end":0},"n11":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":35,"start":16,"end_line":36,"end":0},"n12":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":38,"start":16,"end_line":39,"end":0},"n13":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":44,"start":12,"end_line":45,"end":0},"n14":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":46,"start":16,"end_line":47,"end":0},"n15":{"file_path":"tests/validation_files/headers/nested_if_statements.baml","start_line":49,"start":16,"end_line":50,"end":0}}

0 commit comments

Comments
 (0)