///|
/// Bio.Seq.Approximate module example - Approximate string matching.
///
/// Run: moon run examples/seq_approx_demo/main.mbt
fn main {
println("=== Bio.Seq.Approximate Module Demo ===")
println("")
// Count mismatches
println("=== Count Mismatches ===")
println("ACGT vs ACGT: \{@bio.count_mismatches("ACGT", "ACGT")}")
println("ACGT vs ACGA: \{@bio.count_mismatches("ACGT", "ACGA")}")
println("ACGT vs TTTT: \{@bio.count_mismatches("ACGT", "TTTT")}")
println("")
// Exact search
println("=== Approximate Search (Exact) ===")
let m1 = @bio.approx_search("ACGT", "AACGTG", 0)
println("Search 'ACGT' in 'AACGTG' (max 0 mismatches):")
println(" Found: \{m1.is_match}")
println(" Start: \{m1.start}, End: \{m1.end}")
println(" Mismatches: \{m1.mismatches}")
println("")
// Search with mismatches
println("=== Approximate Search (With Mismatches) ===")
let m2 = @bio.approx_search("ACGT", "AACGAG", 1)
println("Search 'ACGT' in 'AACGAG' (max 1 mismatch):")
println(" Found: \{m2.is_match}")
println(" Mismatches: \{m2.mismatches}")
println("")
// No match
println("=== Approximate Search (No Match) ===")
let m3 = @bio.approx_search("ACGT", "AAAAAA", 0)
println("Search 'ACGT' in 'AAAAAA' (max 0 mismatches):")
println(" Found: \{m3.is_match}")
println("")
// Levenshtein distance
println("=== Levenshtein Distance ===")
println("ACGT vs ACGT: \{@bio.levenshtein_distance("ACGT", "ACGT")}")
println("ACGT vs ACGA: \{@bio.levenshtein_distance("ACGT", "ACGA")}")
println("ACGT vs XXGT: \{@bio.levenshtein_distance("ACGT", "XXGT")}")
println("ACGT vs ACGAT: \{@bio.levenshtein_distance("ACGT", "ACGAT")}")
println("ACGT vs AGT: \{@bio.levenshtein_distance("ACGT", "AGT")}")
println("ACGT vs '' (empty): \{@bio.levenshtein_distance("ACGT", "")}")
println("'' vs '' (both empty): \{@bio.levenshtein_distance("", "")}")
println("")
// Approximate search with indels
println("=== Approximate Search With Indels ===")
let m4 = @bio.approx_search_with_indels("ACGT", "ACXGT", 1)
println("Search 'ACGT' in 'ACXGT' (max 1 error):")
println(" Found: \{m4.is_match}")
println(" Errors: \{m4.mismatches}")
println("")
let m5 = @bio.approx_search_with_indels("ACGT", "ACGXT", 1)
println("Search 'ACGT' in 'ACGXT' (max 1 error):")
println(" Found: \{m5.is_match}")
println(" Errors: \{m5.mismatches}")
println("")
let m6 = @bio.approx_search_with_indels("ACGT", "AGT", 1)
println("Search 'ACGT' in 'AGT' (max 1 error, deletion):")
println(" Found: \{m6.is_match}")
println(" Errors: \{m6.mismatches}")
println("")
let m7 = @bio.approx_search_with_indels("AAAA", "TCGTCG", 1)
println("Search 'AAAA' in 'TCGTCG' (max 1 error):")
println(" Found: \{m7.is_match}")
println("")
// Find all approximate matches
println("=== Find All Approximate Matches ===")
let results = @bio.approx_find_all("ACG", "AACGACGTCG", 0)
println("Find all 'ACG' in 'AACGACGTCG' (exact): \{results.length()} matches")
let results2 = @bio.approx_find_all("ACG", "AACGACGTCG", 1)
println(
"Find all 'ACG' in 'AACGACGTCG' (max 1 mismatch): \{results2.length()} matches",
)
println("")
// Approx word search
println("=== Approx Word Search ===")
let w1 = @bio.approx_word_search("ACGT", "AACGTG", 0)
println("Word search 'ACGT' in 'AACGTG' (max 0 errors):")
println(" Found: \{w1.is_found}")
println(" Edit distance: \{w1.edit_distance}")
println(" Match start: \{w1.match_start}")
println("")
let w2 = @bio.approx_word_search("ZZZZ", "ACGTACGT", 0)
println("Word search 'ZZZZ' in 'ACGTACGT' (max 0 errors):")
println(" Found: \{w2.is_found}")
println("")
// Approx best match
println("=== Approx Best Match ===")
let bm = @bio.approx_best_match("ACGT", "ACXGTACGT", 0.25)
println("Best match 'ACGT' in 'ACXGTACGT' (max 25%% error rate):")
println(" Found: \{bm.is_match}")
println(" Mismatches: \{bm.mismatches}")
println("")
// Match to string
println("=== Match String Representation ===")
let mstr = @bio.approx_match_new("ACGT", "ACGT", 0, 4, 0, 4, true)
println("Match: \{mstr.to_string()}")
println("")
println("=== Done ===")
}