///|
/// Trie (prefix tree) demo - efficient prefix matching for bioinformatics.
///
/// Demonstrates the trie data structure for:
/// - Restriction enzyme site detection
/// - Primer matching in sequences
/// - Prefix-based search
///
/// Inspired by Biopython's Bio.trie and Bio.triefind modules.
/// Run: moon run examples/trie_demo
fn main {
println("=== Trie Module Demo ===")
println("Prefix tree for efficient string matching")
println("Reference: Biopython Bio.trie / Bio.triefind")
println("")
// ------------------------------------------------------------------
// 1. Restriction enzyme site detection
// ------------------------------------------------------------------
println("=== 1. Restriction Enzyme Site Detection ===")
let trie = @bio.trie_sample_restriction_sites()
println("Loaded restriction enzyme sites:")
let items = @bio.trie_items(trie)
let mut i = 0
while i < items.length() {
println(" " + items[i].0 + " -> " + items[i].1)
i = i + 1
}
println("")
// Scan a sequence for restriction sites
let sequence = "ATGCGAATTCGGATCCGCGGCCGCTTAAAGAATTCTTT"
println("Scanning sequence: " + sequence)
let matches = @bio.triefind_find(trie, sequence)
println("Found " + matches.length().to_string() + " restriction sites:")
let mut m = 0
while m < matches.length() {
let (key, enzyme, start, end) = matches[m]
println(
" " +
enzyme +
" (" +
key +
") at position " +
start.to_string() +
"-" +
end.to_string(),
)
m = m + 1
}
println("")
// ------------------------------------------------------------------
// 2. Primer matching
// ------------------------------------------------------------------
println("=== 2. Primer Matching ===")
let primer_trie = @bio.trie_sample_primers()
println("Loaded primers:")
let primers = @bio.trie_items(primer_trie)
let mut p = 0
while p < primers.length() {
println(" " + primers[p].0 + " -> " + primers[p].1)
p = p + 1
}
println("")
// Find longest matching primer at sequence start
let seq5 = "ATCGATCGATCGGGGCC"
println("Matching primers at 5' end of: " + seq5)
let result = @bio.triefind_match(primer_trie, seq5)
match result {
Some((key, val)) => println(" Best match: " + val + " (" + key + ")")
None => println(" No match found")
}
println("")
// ------------------------------------------------------------------
// 3. Prefix search
// ------------------------------------------------------------------
println("=== 3. Prefix-Based Search ===")
let trie3 = @bio.Trie::new()
@bio.trie_insert(trie3, "ATCGATCGAT", "Primer_Fwd_1")
@bio.trie_insert(trie3, "ATCGATCGAC", "Primer_Fwd_2")
@bio.trie_insert(trie3, "ATCGATCGTT", "Primer_Fwd_3")
@bio.trie_insert(trie3, "GCTAGCTAGC", "Primer_Rev_1")
println("Searching for keys with prefix 'ATCGATCG':")
let prefix_results = @bio.trie_with_prefix(trie3, "ATCGATCG")
let mut pr = 0
while pr < prefix_results.length() {
println(" " + prefix_results[pr].0 + " -> " + prefix_results[pr].1)
pr = pr + 1
}
println("")
// ------------------------------------------------------------------
// 4. Trie operations
// ------------------------------------------------------------------
println("=== 4. Trie Operations ===")
let trie4 = @bio.Trie::new()
println("Inserting keys: AAA, AAB, AAC, BBB")
@bio.trie_insert(trie4, "AAA", "val1")
@bio.trie_insert(trie4, "AAB", "val2")
@bio.trie_insert(trie4, "AAC", "val3")
@bio.trie_insert(trie4, "BBB", "val4")
println("Trie size: " + @bio.trie_size(trie4).to_string())
println("Has key 'AAA': " + @bio.trie_has_key(trie4, "AAA").to_string())
println("Has key 'XXX': " + @bio.trie_has_key(trie4, "XXX").to_string())
println("Has prefix 'AA': " + @bio.trie_has_prefix(trie4, "AA").to_string())
println("Has prefix 'XX': " + @bio.trie_has_prefix(trie4, "XX").to_string())
println("")
println("Removing key 'AAB'...")
let removed = @bio.trie_remove(trie4, "AAB")
println("Removed: " + removed.to_string())
println("Trie size: " + @bio.trie_size(trie4).to_string())
println("Has key 'AAB': " + @bio.trie_has_key(trie4, "AAB").to_string())
println("")
// ------------------------------------------------------------------
// 5. Word matching
// ------------------------------------------------------------------
println("=== 5. Word Boundary Matching ===")
let word_trie = @bio.Trie::new()
@bio.trie_insert(word_trie, "EcoRI", "enzyme1")
@bio.trie_insert(word_trie, "BamHI", "enzyme2")
@bio.trie_insert(word_trie, "HindIII", "enzyme3")
let text = "Use EcoRI and BamHI for DNA digestion, not HindIII today."
println("Text: " + text)
println("Word matches:")
let words = @bio.triefind_find_words(word_trie, text)
let mut w = 0
while w < words.length() {
let (key, val, start, end) = words[w]
println(
" " +
val +
" (" +
key +
") at position " +
start.to_string() +
"-" +
end.to_string(),
)
w = w + 1
}
println("")
println("=== Trie Demo Complete ===")
}