diff --git a/Cargo.lock b/Cargo.lock index 25042cf..c439fac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,14 +130,16 @@ dependencies = [ [[package]] name = "compact_str" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5138945395949e7dfba09646dc9e766b548ff48e23deb5246890e6b64ae9e1b9" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" dependencies = [ "castaway", + "cfg-if", "itoa", "ryu", "serde", + "static_assertions", ] [[package]] diff --git a/vidyut-cheda/Cargo.toml b/vidyut-cheda/Cargo.toml index 295ba99..7cc08e9 100644 --- a/vidyut-cheda/Cargo.toml +++ b/vidyut-cheda/Cargo.toml @@ -18,7 +18,7 @@ multimap = "0.8.3" modular-bitfield = "0.11.2" priority-queue = "1.2.3" regex = "1.6.0" -compact_str = "0.6.1" +compact_str = "0.7.1" rustc-hash = "1.1.0" [dev-dependencies] diff --git a/vidyut-prakriya/Cargo.toml b/vidyut-prakriya/Cargo.toml index 196029c..66efb05 100644 --- a/vidyut-prakriya/Cargo.toml +++ b/vidyut-prakriya/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] clap = { version = "4.0.12", features = ["derive"] } -compact_str = { version = "0.6.1", features = ["serde"] } +compact_str = { version = "0.7.1", features = ["serde"] } csv = "1.1.6" enumset = { version = "1.1.3", features = ["serde"] } lazy_static = "1.4.0" diff --git a/vidyut-prakriya/Makefile b/vidyut-prakriya/Makefile index 517bb74..22c8a65 100644 --- a/vidyut-prakriya/Makefile +++ b/vidyut-prakriya/Makefile @@ -37,10 +37,6 @@ create_test_files: ../target/release/create_krdantas --krt ktvA > test-files/krdantas-ktvA.csv ../target/release/create_krdantas --krt kta > test-files/krdantas-kta.csv -create_subantas: - # Work-in-progress tests for subantas. - cargo run --bin create_subantas > test-files/subantas.csv - # Runs a full evaluation over all forms generated by vidyut-prakriya. `hash` is # the SHA-256 hash of the test file. We use `hash` to verify test file # integrity and ensure that our test cases are stable. @@ -53,19 +49,19 @@ test_tinantas: cargo build --release ../target/release/test_tinantas \ --test-cases test-files/tinantas-basic-kartari.csv \ - --hash "f8934f99631e811c333c41ddd4925229d2faab0dd875bc549bb38350319706db" + --hash "13ca3874fc1624c7ba74b3586e4040da7d47fbdd1bbbe12b4987992d266d1e3c" ../target/release/test_tinantas \ --test-cases test-files/tinantas-nic-kartari.csv \ - --hash "2e3d0f56c4e6d375b7064df034a7ee04a7cc91f10838ceee32cbeb37ad2870c5" + --hash "1122c23a5dc53b74b1c140b6d7f0256e83926010783ae9fd25de8eb9e342697b" ../target/release/test_tinantas \ --test-cases test-files/tinantas-san-kartari.csv \ - --hash "0dfec6333abf094ed8199694e2e55436991f837cacf223de3fd1223b576712e3" + --hash "21b1dc3c5f7c6598be919022f8a09f865bd39827f99455fa24cb0e07244dc4e3" ../target/release/test_tinantas \ --test-cases test-files/tinantas-yan-kartari.csv \ - --hash "08c5b0f9b6b2fa857018653583b63571eac3074804025d90c12e0c30a0db0616" + --hash "640447e069abd4bdbd0522e886152c4fdf251f61e54f6d8af1e2d0bd4b7f5313" ../target/release/test_tinantas \ --test-cases test-files/tinantas-basic-karmani.csv \ - --hash "da0e4771bec284661bfd0f537734d44eb6e019e41a387e80dfaa80cf7dc27b03" + --hash "6dec033579ce574d4f64e7d224cc5c1c573f457d6a74900ad64d9706afa545ff" test_krdantas: cargo build --release diff --git a/vidyut-prakriya/scripts/check_rule_coverage.py b/vidyut-prakriya/scripts/check_rule_coverage.py index a1195c5..e8d7cd6 100755 --- a/vidyut-prakriya/scripts/check_rule_coverage.py +++ b/vidyut-prakriya/scripts/check_rule_coverage.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 from pathlib import Path +from collections import Counter import re import glob @@ -41,23 +42,50 @@ def print_legend(): for match in re.findall(r"(\d+_\d+_\d+)", line): tested_rules.add(match.replace('_', '.')) -print_legend() -num_ok = 0 -num_untested = 0 -num_missing = 0 for rule in all_rules: status = None if rule in tested_rules: status = RULE_OK - num_ok += 1 elif rule in implemented_rules: status = RULE_UNTESTED - num_untested += 1 else: status = RULE_MISSING - num_missing += 1 print(f"{status}\t\t{rule}") + print_legend() -print(f"Num tested : {num_ok}") -print(f"Num untested : {num_untested}") -print(f"Num missing : {num_missing}") + +pada_total = Counter() +pada_written = Counter() +pada_tested = Counter() +pada_missing = Counter() +for rule in all_rules: + ap, _, sutra = rule.rpartition('.') + pada_total[ap] += 1 + if rule in tested_rules: + pada_tested[ap] += 1 + elif rule in implemented_rules: + pada_written[ap] += 1 + else: + pada_missing[ap] += 1 + +print("Coverage by pada:") +print() +print(f"+---------+------------+------------+------------+------------+") +print(f"| Pada | Written | Tested | Missing | Total |") +print(f"+---------+------------+------------+------------+------------+") +for key, total in pada_total.items(): + written = pada_written[key] + tested = pada_tested[key] + missing = pada_missing[key] + print(f"| {key} | {written:>10} | {tested:>10} | {missing:>10} | {total:>10} |") +written = pada_written.total() +total = pada_total.total() +tested = pada_tested.total() +missing = pada_missing.total() +print(f"+---------+------------+------------+------------+------------+") +print(f"| All | {written:>10} | {tested:>10} | {missing:>10} | {total:>10} |") +print(f"+---------+------------+------------+------------+------------+") + +print() +num_ok = total - pada_missing.total() +print("Num tested or implemented: {}".format(num_ok)) diff --git a/vidyut-prakriya/src/ac_sandhi.rs b/vidyut-prakriya/src/ac_sandhi.rs index d1cc86b..db32c5a 100644 --- a/vidyut-prakriya/src/ac_sandhi.rs +++ b/vidyut-prakriya/src/ac_sandhi.rs @@ -2,7 +2,7 @@ //! ========= //! (6.1.66 - 6.1.101) -use crate::core::char_view::{get_at, xy, CharPrakriya}; +use crate::core::char_view::{get_at, get_term_index_at, xy, CharPrakriya}; use crate::core::iterators::xy_rule; use crate::core::operators as op; use crate::core::Prakriya; @@ -34,7 +34,7 @@ pub fn try_lopo_vyor_vali(p: &mut Prakriya) { None => return false, }; let vyor_vali = (x == 'v' || x == 'y') && VAL.contains(y); - let t = get_at(p, i).expect("should be present"); + let t_x = get_at(p, i).expect("should be present"); // Ignore if it starts an upadesha, otherwise roots like "vraj" would by vyartha. // - Likewise for roots ending with 'v'. // - Likewise for pratipadikas. @@ -43,9 +43,9 @@ pub fn try_lopo_vyor_vali(p: &mut Prakriya) { // - Exclude pratyayas (yAyA[y]vara -> yAyAvara). // // For now, just check if the term is a dhatu. - let is_mula_dhatu = t.is_dhatu() && !t.is_pratyaya(); - let is_upadesha_adi = is_mula_dhatu && (t.has_adi('v') || t.has_adi('y')); - vyor_vali && !is_upadesha_adi && !t.is_pratipadika() + let is_mula_dhatu = t_x.is_dhatu() && !t_x.is_pratyaya(); + let is_upadesha_adi = is_mula_dhatu && (t_x.has_adi('v') || t_x.has_adi('y')); + vyor_vali && !is_upadesha_adi && !(t_x.is_pratipadika() && !t_x.is_pratyaya()) }, |p, _, i| { p.run("6.1.66", |p| p.set_char_at(i, "")); @@ -55,10 +55,11 @@ pub fn try_lopo_vyor_vali(p: &mut Prakriya) { } fn try_ver_aprktasya(p: &mut Prakriya) -> Option<()> { - let i = p.find_last(T::Pratyaya)?; - let last = p.get(i)?; - if last.has_text("v") { - p.run_at("6.1.67", i, op::lopa); + for i in 0..p.terms().len() { + let t = p.get(i)?; + if t.is_pratyaya() && t.has_text("v") { + p.run_at("6.1.67", i, op::lopa); + } } Some(()) @@ -91,11 +92,16 @@ pub fn apply_general_ac_sandhi(p: &mut Prakriya) { } cp.for_chars(xy(|x, y| AC.contains(x) && AC.contains(y)), |p, text, i| { - p.dump(); let x = text.as_bytes()[i] as char; let y = text.as_bytes()[i + 1] as char; - let t_x = get_at(p, i).expect("ok"); + let i_x = get_term_index_at(p, i).expect("ok"); + let i_y = get_term_index_at(p, i + 1).expect("ok"); + let t_x = p.get(i_x).expect("ok"); + let t_y = p.get(i_y).expect("ok"); + + let eti_edhati = || t_y.has_adi(&*EN) && t_y.has_u_in(&["i\\R", "eDa~\\"]); + let is_uth = || t_y.has_adi('U') && t_y.has_tag(T::FlagUth); if t_x.has_tag(T::Pragrhya) { // agnI iti, ... @@ -131,68 +137,37 @@ pub fn apply_general_ac_sandhi(p: &mut Prakriya) { }; p.run("6.1.77", |p| p.set_char_at(i, res)); true - } else { - false - } - }); - - // upa + fcCati -> upArcCati - cp.for_terms( - |x, y| x.is_upasarga() && x.has_antya(&*A) && y.is_dhatu() && y.has_adi('f'), - |p, i, j| { - p.set(i, |t| t.set_antya("")); - p.set(j, |t| t.set_adi("Ar")); - p.step("6.1.91"); - }, - ); - - // upa + eti -> upEti - cp.for_terms( - |x, y| { - let eti_edhati = y.has_adi(&*EN) && y.has_u_in(&["i\\R", "eDa~\\"]); - let is_uth = y.has_adi('U') && y.has_tag(T::FlagUth); - !x.is_agama() && x.has_antya(&*A) && (eti_edhati || is_uth) - }, - |p, _i, j| { - let y = p.get(j).expect("ok"); - let adi = y.adi().expect("ok"); + } else if t_x.is_upasarga() && t_x.has_antya(&*A) && t_y.is_dhatu() && t_y.has_adi('f') { + // upa + fcCati -> upArcCati + p.run("6.1.91", |p| { + p.set(i_x, |t| t.set_antya("")); + p.set(i_y, |t| t.set_adi("Ar")); + }); + true + } else if !t_x.is_agama() && t_x.has_antya(&*A) && (eti_edhati() || is_uth()) { + // upa + eti -> upEti + let adi = t_y.adi().expect("ok"); let sub = al::to_vrddhi(adi).expect("ok"); - p.run_at("6.1.89", j, |t| t.set_adi(sub)); - }, - ); - - // HACK for KOnAti, DOta, and a few others - cp.for_terms( - |x, _| x.has_suffix_in(&["aU", "AU"]), - |p, i, _| { - p.run_at("6.1.89", i, |t| { + p.run_at("6.1.89", i_y, |t| t.set_adi(sub)); + true + } else if t_x.has_suffix_in(&["aU", "AU"]) { + // HACK for KOnAti, DOta, and a few others + p.run_at("6.1.89", i_x, |t| { t.set_antya(""); t.set_antya("O") }); - }, - ); - - // upa + elayati -> upelayati - cp.for_terms( - |x, y| x.is_upasarga() && x.has_antya(&*A) && y.is_dhatu() && y.has_adi(&*EN), - |p, i, _j| { - p.set(i, |t| t.set_antya("")); - p.step("6.1.94"); - }, - ); - - // General guna/vrddhi rules. - cp.for_chars( - // [dummy comment for cargo fmt] - xy(|x, y| A.contains(x) && AC.contains(y)), - |p, text, i| { + true + } else if t_x.is_upasarga() && t_x.has_antya(&*A) && t_y.is_dhatu() && t_y.has_adi(&*EN) { + // upa + elayati -> upelayati + p.run_at("6.1.94", i_x, |t| t.set_antya("")); + true + } else if A.contains(x) && AC.contains(y) { + // General guna/vrddhi rules. if is_upasarga_sanadi_dhatu(p, i) { return false; } let j = i + 1; - let y = text.as_bytes()[i + 1] as char; - if EC.contains(y) { p.run("6.1.88", |p| { p.set_char_at(j, al::to_vrddhi(y).expect("should have vrddhi")); @@ -205,8 +180,10 @@ pub fn apply_general_ac_sandhi(p: &mut Prakriya) { }); } true - }, - ); + } else { + false + } + }); } pub fn try_sup_sandhi_before_angasya(p: &mut Prakriya) -> Option<()> { @@ -279,7 +256,7 @@ pub fn try_sup_sandhi_after_angasya(p: &mut Prakriya) -> Option<()> { /// Runs vowel sandhi rules that apply between terms (as opposed to between sounds). fn apply_ac_sandhi_at_term_boundary(p: &mut Prakriya, i: usize) -> Option<()> { - let j = p.find_next_where(i, |t| !t.text.is_empty())?; + let j = p.find_next_where(i, |t| !t.is_empty())?; let x = p.get(i)?; let y = p.get(j)?; diff --git a/vidyut-prakriya/src/angasya.rs b/vidyut-prakriya/src/angasya.rs index a9d8249..1470ebe 100644 --- a/vidyut-prakriya/src/angasya.rs +++ b/vidyut-prakriya/src/angasya.rs @@ -116,7 +116,7 @@ fn try_cchvoh(p: &mut Prakriya) -> Option<()> { let kvi_jhaloh_kniti = (n.has_adi(&*JHAL) || n.has_u("kvi~p")) && n.is_knit(); let anunasike = n.has_adi(&*ANUNASIKA); - let is_cchvoh = anga.text.ends_with("tC") || anga.has_antya('v'); + let is_cchvoh = anga.ends_with("tC") || anga.has_antya('v'); // Check for 'U' explicitly since the dhatu might have been processed in an earlier round // (e.g. when creating the sanAdyanta-dhAtu). if kvi_jhaloh_kniti && anga.has_u_in(JVARA_ADI) && !anga.text.contains('U') { @@ -124,9 +124,9 @@ fn try_cchvoh(p: &mut Prakriya) -> Option<()> { t.set_upadha(""); t.find_and_replace_text("v", "U"); }); - } else if kvi_jhaloh_kniti && (anga.text.ends_with("rv") || anga.text.ends_with("rC")) { + } else if kvi_jhaloh_kniti && (anga.ends_with("rv") || anga.ends_with("rC")) { p.run_at("6.4.21", i, |t| { - if t.text.ends_with("rC") { + if t.ends_with("rC") { t.set_antya("") } else { t.set_antya(""); @@ -145,95 +145,6 @@ fn try_cchvoh(p: &mut Prakriya) -> Option<()> { Some(()) } -fn try_run_dirgha_for_sarvanamasthane_asambuddhau( - p: &mut Prakriya, - i: usize, - i_sup: usize, -) -> Option<()> { - let anga = p.get(i)?; - let sup = p.get(i_sup)?; - let sau = sup.has_u("su~"); - - if !(sup.is_sarvanamasthana() && !sup.has_tag(T::Sambuddhi)) { - return None; - } - - if anga.has_antya('n') { - if anga.ends_with("in") || anga.has_text("pUzan") { - let sub = al::to_dirgha(anga.upadha()?)?; - if sup.has_u("Si") { - // yogIni - p.run_at("6.4.12", i, op::upadha(&sub.to_string())); - } else if sau { - // yogI - p.run_at("6.4.13", i, op::upadha(&sub.to_string())); - } - } else if !sup.is_lupta() { - // PalAni - let sub = al::to_dirgha(anga.upadha()?)?; - p.run_at("6.4.8", i, op::upadha(&sub.to_string())); - } - } else if (anga.ends_with("ns") && anga.text.len() >= 3) || anga.has_text("mahant") { - let c = anga.text.len() - 3; - let sub = al::to_dirgha(anga.get_at(c)?)?; - p.run_at("6.4.10", i, |t| { - t.set_at(c, &sub.to_string()); - }); - } else if anga.has_text("ap") - || anga.has_tag_in(&[T::TrnTrc, T::FlagTrjvat]) - || anga.has_u_in(&[ - "svasf", "naptf", "nezwf", "tvaswf", "kzawf", "hotf", "potf", "praSAstf", - ]) - { - let sub = al::to_dirgha(anga.upadha()?)?; - p.run_at("6.4.11", i, op::upadha(&sub.to_string())); - } else if anga.has_text("svanp") { - // for svAmpi and svampi (svap + [jas -> Si]) - p.optional_run_at(Rule::Kaumudi("446"), i, |t| { - t.set_at(t.text.len() - 3, "A"); - }); - } - - Some(()) -} - -/// Runs various rules that cause dirgha-adesha in the anga. -/// -/// 6.4.2 - 6.4.19 -fn try_dirgha_adesha_for_sup(p: &mut Prakriya) -> Option<()> { - let i_sup = p.find_last(T::Sup)?; - let i_anga = p.find_prev_where(i_sup, |t| !t.is_agama())?; - - let anga = p.get(i_anga)?; - let sup = p.get(i_sup)?; - let has_nuw_agama = if i_anga + 1 != i_sup { - p.get(i_anga + 1)?.has_u("nu~w") - } else { - false - }; - - if sup.has_text("Am") && has_nuw_agama { - if anga.has_text_in(&["tisf", "catasf"]) { - // No change. - p.step("6.4.4") - } else if anga.has_text("nf") { - // nfRAm, nFRAm - let sub = al::to_dirgha(anga.antya()?)?; - p.optional_run_at("6.4.6", i_anga, op::antya(&sub.to_string())); - } else if anga.has_antya('n') { - let sub = al::to_dirgha(anga.upadha()?)?; - p.run_at("6.4.7", i_anga, op::upadha(&sub.to_string())); - } else if anga.has_antya(&*AC) { - let sub = al::to_dirgha(anga.antya()?)?; - p.run_at("6.4.3", i_anga, op::antya(&sub.to_string())); - } - } else { - try_run_dirgha_for_sarvanamasthane_asambuddhau(p, i_anga, i_sup); - } - - Some(()) -} - /// Applies rules that replace an initial "J" in a pratyaya with the appropriate sounds. /// /// (7.1.3 - 7.1.7) @@ -294,70 +205,75 @@ fn replace_pha_dha_and_others(t: &Term) -> Option<&'static str> { /// Examples: Bava + Ji -> Bavanti, kar + yu -> karaNa. /// /// (7.1.1 - 7.1.35 + 3.1.83) -pub fn try_pratyaya_adesha(p: &mut Prakriya) -> Option<()> { - let len = p.terms().len(); - if len < 2 { - return None; +pub fn try_pratyaya_adesha(p: &mut Prakriya) { + for i in 0..p.terms().len() { + try_pratyaya_adesha_at_index(p, i); } +} - let i = len - 1; - let last = p.get_if(i, |t| t.is_pratyaya())?; - let prev = p.get(i - 1)?; - - if last.is_final() { - return None; - } +pub fn try_pratyaya_adesha_at_index(p: &mut Prakriya, i_anga: usize) -> Option<()> { + let anga = p.get(i_anga)?; + let i_n = p.find_next_where(i_anga, |t| !t.is_empty())?; + let n = p.get_if(i_n, |t| t.is_pratyaya() && !t.is_final())?; - if last.has_text_in(&["yu~", "vu~"]) { - if last.has_text("yu~") { - p.run_at("7.1.1", i, op::text("ana")); + if n.has_text_in(&["yu~", "vu~"]) { + if n.has_text("yu~") { + p.run_at("7.1.1", i_n, op::text("ana")); } else { - p.run_at("7.1.1", i, op::text("aka")); + p.run_at("7.1.1", i_n, op::text("aka")); } - } else if let Some(sub) = replace_pha_dha_and_others(last) { - p.run_at("7.1.2", i, op::adi(sub)); - } else if last.has_adi('W') { + } else if let Some(sub) = replace_pha_dha_and_others(n) { + p.run_at("7.1.2", i_n, op::adi(sub)); + } else if n.has_adi('W') { // Run 7.3.50 and 7.3.51 because they have no clear place otherwise. - if prev.has_suffix_in(&["is", "us", "t"]) || prev.has_antya(&*UK) { - p.run_at("7.3.51", i, |t| t.set_adi("k")); + if anga.has_suffix_in(&["is", "us", "t"]) || anga.has_antya(&*UK) { + p.run_at("7.3.51", i_n, |t| t.set_adi("k")); } else { - p.run_at("7.3.50", i, |t| t.set_adi("ik")); + p.run_at("7.3.50", i_n, |t| t.set_adi("ik")); } - - // 7.1.34 (daDyA -> daDyO) happens later on after the dhatu's vowel change (DyE -> DyA) - } else if p.has(i, |t| t.has_tag(T::Tin) && t.has_text_in(&["tu", "hi"])) { + } else if n.is_tin() && n.has_text_in(&["tu", "hi"]) { + // 7.1.34 (daDyA -> daDyO) happens later on after the dhatu's vowel change (DyE -> DyA) // -tAt substitution needs to occur early because it conditions samprasarana. // N is to block pit-guNa, not for replacement of the last letter. - op::optional_adesha("7.1.35", p, i, "tAta~N"); + op::optional_adesha("7.1.35", p, i_n, "tAta~N"); } // Run 3.1.83 here because it has no clear place otherwise. // TODO: is there a better place for this? - if len > 2 { - let t = p.get(i)?; - if p.has(i - 2, |t| t.has_antya(&*HAL)) - && p.has(i - 1, |t| t.has_u("SnA")) - && t.has_text("hi") - { - let mut blocked = false; - if p.is_chandasi() { - // gfBAya, ... - blocked = op::optional_adesha("3.1.84", p, i - 1, "SAyac"); - } - if !blocked { - op::adesha("3.1.83", p, i - 1, "SAnac"); - } + let anga = p.get(i_anga)?; + let n = p.get(i_anga + 1)?; + if (i_anga > 0 && p.has(i_anga - 1, |t| t.has_antya(&*HAL))) + && anga.has_u("SnA") + && n.has_text("hi") + { + let mut blocked = false; + if p.is_chandasi() { + // gfBAya, ... + blocked = op::optional_adesha("3.1.84", p, i_anga, "SAyac"); + } + if !blocked { + op::adesha("3.1.83", p, i_anga, "SAnac"); } } - try_pratyaya_adesha_for_dhatu(p); + let anga = p.get(i_anga)?; + if anga.is_dhatu() { + let n = p.get(i_n)?; + + if anga.has_u("vida~") && anga.has_gana(Adadi) && n.has_u("Satf~") { + op::optional_adesha("7.1.36", p, i_n, "vasu~"); + } else if n.has_u("ktvA") && p.terms().first()?.is_pratipadika() { + op::adesha("7.1.37", p, i_n, "lyap"); + } + } Some(()) } + /// Runs rules that are conditioned on a following Sit-pratyaya. fn try_shiti(p: &mut Prakriya) -> Option<()> { let i = p.find_last(T::Dhatu)?; - let i_n = p.find_next_where(i, |t| !t.text.is_empty())?; + let i_n = p.find_next_where(i, |t| !t.is_empty())?; let pa_ghra = &[ "pA\\", "GrA\\", "DmA\\", "zWA\\", "mnA\\", "dA\\R", "df\\Si~r", "f\\", "sf\\", "Sa\\dx~", @@ -379,14 +295,14 @@ fn try_shiti(p: &mut Prakriya) -> Option<()> { // Check ganas to avoid `Bramu~ anavasTAne` (BrAmyati). p.run_at("7.3.74", i, op::upadha("A")); } else if anga.has_u_in(&["zWivu~", "klamu~"]) - || (anga.has_u("camu~") && i > 0 && p.has(i - 1, |t| t.has_u("AN"))) + || (anga.has_u("camu~") && p.has_prev_non_empty(i, |t| t.has_u("AN"))) { // zWIvati, kAmati, AcAmati p.run_at("7.3.75", i, |t| { match t.text.as_str() { - "zWiv" => t.text.replace_range(.., "zWIv"), - "klam" => t.text.replace_range(.., "klAm"), - "cam" => t.text.replace_range(.., "cAm"), + "zWiv" => t.set_text("zWIv"), + "klam" => t.set_text("klAm"), + "cam" => t.set_text("cAm"), _ => (), }; }); @@ -430,7 +346,7 @@ fn try_shiti(p: &mut Prakriya) -> Option<()> { fn try_pvadinam_hrasva(p: &mut Prakriya) -> Option<()> { let i = p.find_last(T::Dhatu)?; - let i_n = p.find_next_where(i, |t| !t.text.is_empty())?; + let i_n = p.find_next_where(i, |t| !t.is_empty())?; let _n = p.get_if(i_n, |t| t.has_tag(T::Sit))?; let anga = p.get(i)?; @@ -493,7 +409,7 @@ fn try_add_num_agama_for_dhatu(p: &mut Prakriya) -> Option<()> { let yi = n.has_adi('y'); let has_upasarga = p.find_prev_where(i, |t| t.is_upasarga()).is_some(); - if has_upasarga && i == 1 && p.has(i - 1, |t| t.has_u_in(&["su", "dur"])) { + if i == 2 && p.has_prev_non_empty(i, |t| t.has_u_in(&["su", "dur"])) { // sulABa, durlABa p.step("7.1.68"); } else if n.has_u_in(&["Kal", "GaY"]) { @@ -506,9 +422,11 @@ fn try_add_num_agama_for_dhatu(p: &mut Prakriya) -> Option<()> { p.optional_run_at("7.1.69", i, add_num); } else if n.has_adi(&*AC) && !n.has_u("Sap") && !liti { p.run_at("7.1.64", i, add_num); - } else if yi && i > 0 && p.has(i - 1, |t| t.has_u("AN")) { + } else if yi && p.has_prev_non_empty(i, |t| t.has_u("AN")) { + // AlamByA, ... p.run_at("7.1.65", i, add_num); - } else if yi && i > 0 && p.has(i - 1, |t| t.has_u("upa")) { + } else if yi && p.has_prev_non_empty(i, |t| t.has_u("upa")) { + // upalamByA, upalaBya, ... p.optional_run_at("7.1.66", i, add_num); } } else if n.has_adi(&*AC) { @@ -545,7 +463,7 @@ pub fn try_add_iit_agama(p: &mut Prakriya) -> Option<()> { let anga = p.get(i_anga)?; let n = p.pratyaya(i_pratyaya_start)?; - let is_aprkta = n.slice().iter().map(|t| t.text.len()).sum::() == 1; + let is_aprkta = n.slice().iter().map(|t| t.len()).sum::() == 1; if n.has_adi(&*HAL) && n.has_tag(T::Sarvadhatuka) { // HACK to avoid yAsut and prevent bruvIyAt, etc. @@ -631,14 +549,13 @@ fn try_sarvadhatuke(p: &mut Prakriya) -> Option<()> { } /// (7.4.21 - 7.4.31) -fn try_change_anga_before_y(p: &mut Prakriya) -> Option<()> { - let i = p.find_first_where(|t| t.is_dhatu() || t.is_pratipadika())?; +fn try_change_anga_before_y(p: &mut Prakriya, i: usize) -> Option<()> { + let anga = p.get_if(i, |t| t.is_anga())?; let i_n = p.find_next_where(i, |t| !t.is_empty())?; - let anga = p.get(i)?; let n = p.pratyaya(i_n)?; let akrt_sarva = !n.has_tag_in(&[T::Sarvadhatuka, T::Krt]); - let has_upasarga = i > 0 && p.has(i - 1, |t| t.is_upasarga()); + let has_upasarga = p.has_prev_non_empty(i, |t| t.is_upasarga()); let yi_kniti = n.has_adi('y') && n.is_knit(); if anga.has_u("SIN") && n.has_tag(T::Sarvadhatuka) { @@ -690,8 +607,11 @@ fn try_change_anga_before_y(p: &mut Prakriya) -> Option<()> { p.run_at("7.4.31", i, op::antya("I")); } else if n.has_adi('y') { let sub = al::to_dirgha(anga.antya()?)?; - if akrt_sarva && n.is_knit() { - // suKAyate + if anga.has_antya(&*AA) && n.has_u("kyac") { + // putrIyati, ... + p.run_at("7.4.33", i, op::antya("I")); + } else if akrt_sarva && n.is_knit() { + // suKAyate, ... p.run_at("7.4.25", i, op::antya(&sub.to_string())); } } @@ -738,7 +658,7 @@ fn try_anga_changes_to_t(p: &mut Prakriya, i_anga: usize) -> Option<()> { // Only `o~hA\\k`. ("jahāternideśāt jihīterna bhavati। hātvā" -- KV) p.run_at("7.4.43", i_anga, op::text("hi")); } else if anga.has_tag(T::Ghu) && anga.has_adi('d') { - if i_anga > 0 && p.has(i_anga - 1, |t| t.is_upasarga() && t.has_antya(&*AC)) { + if p.has_prev_non_empty(i_anga, |t| t.is_upasarga() && t.has_antya(&*AC)) { p.run_at("7.4.47", i_anga, op::text("t")); } else { p.run_at("7.4.46", i_anga, op::text("dat")); @@ -886,7 +806,7 @@ fn try_change_cu_to_ku(p: &mut Prakriya, i: usize) -> Option<()> { let n = p.pratyaya(i_n)?; let has_c_j_antya = anga.has_antya('c') || anga.has_antya('j'); let sanlitoh = n.has_u("san") || n.has_lakshana("li~w"); - let has_upasarga = |s| i > 0 && p.has(i - 1, |t| t.has_u(s)); + let has_upasarga = |s| p.has_prev_non_empty(i, |t| t.has_u(s)); let blocked = if anga.has_adi(&*KU) && has_c_j_antya { p.step("7.3.59"); @@ -983,12 +903,12 @@ fn try_ato_dirgha(p: &mut Prakriya, i: usize) -> Option<()> { p.run_at("7.3.101", i, op::antya("A")); } } else if n.last().is_sup() { - let anga = p.nyap_pratipadika(i)?; + let anga = p.nyapu_pratipadika(i)?; let is_aap = anga.last().is_aap_pratyaya(); let i_last_non_empty = anga.end_non_empty()?; let sup = p.pratyaya(i_next)?; - let is_sambuddhi = sup.has_tag(T::Sambuddhi); + let is_sambuddhi = sup.last().is_sambuddhi(); // > bhyamādeśe kṛte śeṣelope ca bahuvacane jhalyet iti etvaṃ prāpnoti, tadaṅgavṛtte // > punarvṛttāvavidhir niṣṭhitasya iti na bhavati @@ -1115,11 +1035,11 @@ fn try_sic_vrddhi(p: &mut Prakriya) -> Option<()> { p.run_at("7.2.1", i, op::antya(sub)); } else if dhatu.is_samyoganta() { // 7.2.3 applies to the final vowel generally, even if samyoganta - let n_3 = dhatu.get_at(dhatu.text.len() - 3)?; + let n_3 = dhatu.get_at(dhatu.len() - 3)?; p.run_at("7.2.3", i, |t| { if let Some(sub) = al::to_vrddhi(n_3) { - let i = t.text.len() - 3; - t.text.replace_range(i..=i, sub); + let i = t.len() - 3; + t.set_at(i, sub); } else { // e.g. "mansj", "pracC" t.find_and_replace_text("a", "A"); @@ -1368,21 +1288,6 @@ fn try_didhi_vevi_lopa(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } -fn try_pratyaya_adesha_for_dhatu(p: &mut Prakriya) -> Option<()> { - let i_dhatu = p.find_first(T::Dhatu)?; - let i_n = p.find_next_where(i_dhatu, |t| !t.is_empty())?; - - let dhatu = p.get(i_dhatu)?; - let n = p.get(i_n)?; - - if dhatu.has_u("vida~") && dhatu.has_gana(Adadi) && n.has_u("Satf~") { - op::optional_adesha("7.1.36", p, i_n, "vasu~"); - } else if n.has_u("ktvA") && i_dhatu > 0 && p.has(i_dhatu - 1, |t| !t.is_dhatu()) { - op::adesha("7.1.37", p, i_n, "lyap"); - } - Some(()) -} - pub fn run_before_stritva(p: &mut Prakriya) -> Option<()> { subanta::run_before_stritva(p); Some(()) @@ -1419,7 +1324,10 @@ pub fn run_before_dvitva(p: &mut Prakriya) -> Option<()> { p.debug("==== Guna-vrddhi ===="); guna_vrddhi::run(p); - try_change_anga_before_y(p); + for i in 0..p.terms().len() { + try_change_anga_before_y(p, i); + } + try_cchvoh(p); // Must precede ft-AdeSa (f -> ir) @@ -1496,7 +1404,5 @@ pub fn run_after_dvitva(p: &mut Prakriya) -> Option<()> { try_dhatu_rt_adesha(p, index); } - try_dirgha_adesha_for_sup(p); - Some(()) } diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index 23d7a80..056be0f 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -73,9 +73,11 @@ fn try_abhyasa_lopa_and_dhatu_change_before_san(p: &mut Prakriya) -> Option<()> let mut do_abhyasa_lopa = true; let dhatu = p.get(i)?; - if dhatu.has_u_in(&["mI\\Y", "qumi\\Y", "mA\\", "mA\\N", "me\\N"]) + if (dhatu.has_u_in(&["mI\\Y", "qumi\\Y", "mA\\", "mA\\N", "me\\N"]) || dhatu.has_tag(T::Ghu) - || dhatu.has_u_in(&["ra\\Ba~\\", "qula\\Ba~\\z", "Sa\\kx~", "patx~", "pa\\da~\\"]) + || dhatu.has_u_in(&["ra\\Ba~\\", "qula\\Ba~\\z", "Sa\\kx~", "patx~", "pa\\da~\\"])) + // Temporary HACK to avoid running this rule twice. + && !dhatu.text.contains("is") { // mitsati, ripsati, lipsati, Sikzati, pitsati, ... let code = "7.4.54"; @@ -136,7 +138,7 @@ fn run_for_sani_or_cani_at_index(p: &mut Prakriya, i: usize) -> Option<()> { let anga = p.get(i_abhyasta)?; // quick HACK for jAgr - let is_laghuni = anga.is_laghu() && !anga.text.starts_with("jA"); + let is_laghuni = anga.is_laghu() && !anga.starts_with("jA"); let has_at_lopa = p.has(i_abhyasta, |t| t.has_tag(T::FlagAtLopa)); let is_ni = p .find_next_where(i_abhyasta, |t| t.is_ni_pratyaya()) diff --git a/vidyut-prakriya/src/angasya/asiddhavat.rs b/vidyut-prakriya/src/angasya/asiddhavat.rs index aa92db2..18e2948 100644 --- a/vidyut-prakriya/src/angasya/asiddhavat.rs +++ b/vidyut-prakriya/src/angasya/asiddhavat.rs @@ -45,7 +45,7 @@ fn is_knit(n: &TermView) -> bool { /// Returns whether the given slice has multiple vowels. fn is_anekac(p: &Prakriya, i: usize) -> bool { - let mut num_ac = 0_u8; + let mut num_ac = 0; for t in p.terms()[..=i].iter().rev() { // HACK to skip aw/Aw-Agama (a-gacchat) which should not be counted because it, too, is added // in the asiddhavat section. (6.4.71 - 6.4.72). @@ -53,13 +53,9 @@ fn is_anekac(p: &Prakriya, i: usize) -> bool { continue; } - for c in t.text.chars().rev() { - if AC.contains(c) { - num_ac += 1; - if num_ac >= 2 { - return true; - } - } + num_ac += t.num_vowels(); + if num_ac >= 2 { + return true; } } false @@ -70,7 +66,7 @@ fn is_samyogapurva(p: &Prakriya, i: usize) -> bool { let mut num_hal = 0_u8; let mut first = true; for t in p.terms()[..=i].iter().rev() { - for c in t.text.chars().rev() { + for c in t.chars().rev() { if HAL.contains(c) { num_hal += 1; if num_hal >= 2 { @@ -432,8 +428,7 @@ fn try_et_adesha_and_abhyasa_lopa_for_lit(p: &mut Prakriya, i: usize) -> Option< // No change. p.step("6.4.126") } else { - let is_eka_hal_madhya = - dhatu.text.len() == 3 && dhatu.has_adi(&*HAL) && dhatu.has_antya(&*HAL); + let is_eka_hal_madhya = dhatu.len() == 3 && dhatu.has_adi(&*HAL) && dhatu.has_antya(&*HAL); let is_a = dhatu.has_upadha('a'); let is_lit = n.has_lakshana("li~w"); // Aspirated consonants become unaspirated in the tripAdi, which hasn't run @@ -475,8 +470,8 @@ fn try_ardhadhatuke(p: &mut Prakriya, i: usize) -> Option<()> { } let is_halah = |p: &Prakriya, i| { - if p.has(i, |t| t.text.len() >= 3) { - p.has(i, |t| t.has_at(t.text.len() - 3, &*HAL)) + if p.has(i, |t| t.len() >= 3) { + p.has(i, |t| t.has_at(t.len() - 3, &*HAL)) } else { let i_prev = p.find_prev_where(i, |t| !t.is_empty()); if let Some(i_prev) = i_prev { @@ -489,7 +484,8 @@ fn try_ardhadhatuke(p: &mut Prakriya, i: usize) -> Option<()> { if anga.has_text("Brasj") { p.optional_run_at("6.4.47", i, op::text("Barj")); - } else if anga.text.ends_with("ya") && is_halah(p, i) { + } else if anga.ends_with("ya") && is_halah(p, i) && !anga.has_u("kyac") { + // TODO: why block kyac? SK mentions the "sannipAta-pariBAzA" in 2658 p.run("6.4.49", |p| { p.set(i, op::antya("")); p.set(i, op::antya("")); @@ -531,7 +527,7 @@ fn try_upadha_nalopa(p: &mut Prakriya, i: usize) -> Option<()> { } else if anidit_hal && is_kniti && anga.has_upadha('n') { let mut blocked = false; // ancu gati-pUjanayoH - if anga.has_u("ancu~") { + if anga.has_u("ancu~") && !p.has(i + 1, |t| t.has_u("kvi~n")) { blocked = p.optional_run("6.4.30", |_| {}); } if !blocked { @@ -576,7 +572,6 @@ fn try_upadha_nalopa(p: &mut Prakriya, i: usize) -> Option<()> { /// Runs rules that delete the final n of a term. /// /// (6.4.36 - 6.4.44) -/// TODO: 6.4.41 fn try_antya_nalopa(p: &mut Prakriya, i: usize) -> Option<()> { let i_n = p.find_next_where(i, |t| !t.is_empty())?; @@ -595,9 +590,11 @@ fn try_antya_nalopa(p: &mut Prakriya, i: usize) -> Option<()> { if anga.has_u("ha\\na~") && n.last().has_text("hi") { // jahi p.run_at("6.4.36", i, op::text("ja")); - } else if anga.has_text("gam") && n.has_u("kvip") { + } else if anga.has_text("gam") && n.has_u("kvi~p") { // TODO: other kvi-pratyayas? p.run_at("6.4.40", i, op::antya("")); + } else if anga.has_antya('n') && n.last().has_u_in(&["vi~w", "vani~p"]) { + p.run_at("6.4.41", i, op::antya("A")); } else if anga.has_u_in(&["jana~", "janI~\\", "zaRa~", "zaRu~^", "Kanu~^"]) { if n.has_adi('y') && kniti { // sanyAt, sAyAt @@ -676,7 +673,7 @@ fn try_add_a_agama(p: &mut Prakriya) -> Option<()> { // Dhatu may be multi-part, so insert before abhyasa. // But abhyasa may follow main dhatu (e.g. undidizati) -- // So, use the first match we find that's not a prefix. - let i_start = p.find_first_where(|t| !t.is_upasarga())?; + let i_start = p.find_first_where(|t| !t.is_upasarga() && !t.is_lupta())?; // Agama already added in a previous iteration, so return. // (To prevent infinite loops) @@ -751,15 +748,16 @@ pub fn run_before_guna(p: &mut Prakriya, i: usize) -> Option<()> { // Runs rules that are conditioned on an anga ending in an "i" or "v" sound. // // (6.4.77 - 6.4.100) -fn run_for_final_i_or_u(p: &mut Prakriya, i: usize) -> Option<()> { - let anga = p.get_if(i, |t| !t.is_agama())?; - let j = p.find_next_where(i, |t| !t.is_empty())?; - let n = p.pratyaya(j)?; +fn run_for_final_i_or_u(p: &mut Prakriya, i_anga: usize) -> Option<()> { + let i_n = p.find_next_where(i_anga, |t| !t.is_empty())?; + let anga = p.get_if(i_anga, |t| !t.is_agama())?; + let n = p.pratyaya(i_n)?; if !anga.has_antya(&*I_U) || !n.has_adi(&*AC) || anga.is_upasarga() { return None; } + // Helper function to perform iyaN-uvaN-Adeza. let to_iy_uv = |p: &mut Prakriya, i| { if p.has(i, |t| t.has_antya(&*II)) { p.set(i, op::antya("iy")); @@ -768,14 +766,14 @@ fn run_for_final_i_or_u(p: &mut Prakriya, i: usize) -> Option<()> { } }; - let is_asamyogapurva = !is_samyogapurva(p, i); - let anga = p.get(i)?; - let n = p.pratyaya(j)?; + let is_asamyogapurva = !is_samyogapurva(p, i_anga); + let anga = p.get(i_anga)?; + let n = p.pratyaya(i_n)?; if anga.has_text("strI") && n.last().is_pratyaya() { if n.last().has_u_in(&["am", "Sas"]) { - p.optional_run_at("6.4.80", i, op::antya("iy")); + p.optional_run_at("6.4.80", i_anga, op::antya("iy")); } else { - p.run_at("6.4.79", i, op::antya("iy")); + p.run_at("6.4.79", i_anga, op::antya("iy")); } } else if anga.has_u_in(&["i\\R", "i\\k"]) { // Also applies to 'ik' according to some: @@ -787,47 +785,58 @@ fn run_for_final_i_or_u(p: &mut Prakriya, i: usize) -> Option<()> { // // [1]: https://archive.org/details/237131938MadhaviyaDhatuVrtti/page/n412/mode/1up if anga.has_u("i\\k") { - let used = p.optional_run_at("6.4.81", i, op::antya("y")); + let used = p.optional_run_at("6.4.81", i_anga, op::antya("y")); if !used { // Copied from below for better control flow. - p.run("6.4.77", |p| to_iy_uv(p, i)); + p.run("6.4.77", |p| to_iy_uv(p, i_anga)); } } else { - p.run_at("6.4.81", i, op::antya("y")); + p.run_at("6.4.81", i_anga, op::antya("y")); } - } else if anga.has_antya(&*II) && is_anekac(p, i) && anga.is_dhatu() && is_asamyogapurva { + } else if anga.has_antya(&*II) && is_anekac(p, i_anga) && anga.is_dhatu() && is_asamyogapurva { // `Dhatu` is understood here even if not stated in the rule. // ("dhātoḥ iti vartate" -- Kashika) if anga.has_text("suDI") { p.step("6.4.85"); } else { - p.run_at("6.4.82", i, op::antya("y")); + p.run_at("6.4.82", i_anga, op::antya("y")); } } else if anga.has_antya(&*UU) && anga.is_dhatu() - && n.has_tag(T::Sup) - && is_anekac(p, i) + && n.last().is_sup() + && is_anekac(p, i_anga) && is_asamyogapurva { if anga.has_text("BU") { p.step("6.4.85"); } else { - p.run_at("6.4.83", i, op::antya("v")); + p.run_at("6.4.83", i_anga, op::antya("v")); } } else if anga.has_text("varzABU") { - p.run_at("6.4.84", i, op::antya("v")); - } else if anga.has_u_in(&["hu\\", "Snu"]) && n.has_tag(T::Sarvadhatuka) && is_asamyogapurva { - p.run_at("6.4.87", i, op::antya("v")); - } else if anga.is_dhatu() || anga.has_u("Snu") || anga.has_text("BrU") { - p.run("6.4.77", |p| to_iy_uv(p, i)); - } else { - let abhyasa = p.get_if(i, |t| t.is_abhyasa())?; - let next = p.get(j)?; - let x = abhyasa.antya()?; - let y = next.adi()?; - // HACKY implementation of asavarna - if al::to_dirgha(x) != al::to_dirgha(y) { - p.run("6.4.78", |p| to_iy_uv(p, i)); + p.run_at("6.4.84", i_anga, op::antya("v")); + } else if anga.has_text("BU") + && p.has_prev_non_empty(i_anga, |t| t.has_text_in(&["dfn", "kara", "punar"])) + { + p.run_at("6.4.84.v1", i_anga, op::antya("v")); + } + + let anga = p.get(i_anga)?; + let n = p.pratyaya(i_n)?; + // Check for this condition again in case these sounds were changed above. + if anga.has_antya(&*I_U) { + if anga.has_u_in(&["hu\\", "Snu"]) && n.last().is_sarvadhatuka() && is_asamyogapurva { + p.run_at("6.4.87", i_anga, op::antya("v")); + } else if anga.is_dhatu() || anga.has_u("Snu") || anga.has_text("BrU") { + // Apnuvanti, ... + p.run("6.4.77", |p| to_iy_uv(p, i_anga)); + } else { + let abhyasa = p.get_if(i_anga, |t| t.is_abhyasa())?; + let next = p.get(i_n)?; + let x = abhyasa.antya()?; + let y = next.adi()?; + if !al::is_savarna(x, y) { + p.run("6.4.78", |p| to_iy_uv(p, i_anga)); + } } } @@ -937,7 +946,7 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { ]; let bha = p.get_if(i, |t| t.has_tag(T::Bha))?; - let bha_prati = p.nyap_pratipadika(i)?; + let bha_prati = p.nyapu_pratipadika(i)?; let next = p.get(i + 1)?; let taddhita = next.is_taddhita(); @@ -995,6 +1004,17 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { }); } else if bha.has_text_in(&["Svan", "yuvan", "maGavan"]) && !next.has_tag(T::Taddhita) { p.run_at("6.4.133", i, |t| t.find_and_replace_text("va", "u")); + } else if bha_prati.last_non_empty()?.has_text("ac") { + // daDIcaH, ... + let i_start = bha_prati.start(); + let i_end = bha_prati.end_non_empty()?; + // HACK: also change previous 'y' to 'i', 'v' to 'u' + if p.has(i_start, |t| t.has_antya('y')) { + p.set(i_start, |t| t.set_antya("i")); + } else if p.has(i_start, |t| t.has_antya('v')) { + p.set(i_start, |t| t.set_antya("u")); + } + p.run_at("6.4.138", i_end, |t| t.set_adi("")); } else if bha.has_antya('n') { if taddhita { let ani = next.has_u("aR"); @@ -1013,7 +1033,7 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { ]) { p.run_at("6.4.144.v1", i, op::ti("")); } else if ani && bha.ends_with("in") { - let n = bha.text.len(); + let n = bha.len(); if bha.has_text_in(&["gATin", "vidaTin", "keSin", "gaRin", "paRin"]) { // gATina, vEdATina, ... p.step("6.4.165"); @@ -1026,7 +1046,10 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { } } else if ani && bha.ends_with("an") { p.step("6.4.167"); - } else if next.has_adi('y') && p.has_artha(Artha::Taddhita(TaddhitaArtha::TatraSadhu)) { + } else if bha.ends_with("an") + && next.has_adi('y') + && !p.has_artha(Artha::Taddhita(TaddhitaArtha::TatraBhava)) + { // TODO: expand conditions here. p.step("6.4.168"); } else if bha.has_text_in(&["Atman", "aDvan"]) && next.has_u("Ka") { @@ -1041,9 +1064,9 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { } } else if bha.ends_with("an") { let mut blocked = false; - let n = bha.text.len(); + let n = bha.len(); if n >= 4 - && (bha.text.ends_with("man") || bha.text.ends_with("van")) + && (bha.ends_with("man") || bha.ends_with("van")) && HAL.contains(bha.get_at(n - 4)?) { p.step("6.4.137"); @@ -1094,11 +1117,11 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { "hiraRmaya" }; p.run(code, op::nipatana(sub)); - } else if bha.has_antya(&*UU) && taddhita { - if next.has_tag(T::Qit) && !bha.has_text("kadrU") { - p.run_at("6.4.147", i, |t| t.set_antya("")); + } else if bha_prati.has_antya(&*UU) && taddhita { + if next.has_u_in(&["Qa", "QaY", "Qak"]) && !bha_prati.first().has_u("kadrU") { + p.run_at("6.4.147", bha_prati.end_non_empty()?, |t| t.set_antya("")); } else { - p.run_at("6.4.146", i, |t| t.set_antya("o")); + p.run_at("6.4.146", bha_prati.end_non_empty()?, |t| t.set_antya("o")); } } else if (bha_prati.has_antya(&*AA) || bha_prati.has_antya(&*II)) && (taddhita || next.has_adi('I')) diff --git a/vidyut-prakriya/src/angasya/guna_vrddhi.rs b/vidyut-prakriya/src/angasya/guna_vrddhi.rs index 62f06fb..e72bdbe 100644 --- a/vidyut-prakriya/src/angasya/guna_vrddhi.rs +++ b/vidyut-prakriya/src/angasya/guna_vrddhi.rs @@ -135,14 +135,13 @@ impl<'a> GunaVrddhiPrakriya<'a> { } /// Tries rules that cause vrddhi when a taddhita-pratyaya follows. -fn try_taddhita_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { +fn try_taddhita_vrddhi(p: &mut Prakriya, i_anga: usize, i_n: usize) -> Option<()> { const DVARA_ADI: &[&str] = &[ "dvAra", "svara", "svADyAya", "vyalkaSa", "svasti", "svar", "sPyakfta", "Svas", "Svan", "sva", ]; - let anga = p.get(i)?; - let i_n = p.find_next_where(i, |t| !t.is_empty())?; + let anga = p.get(i_anga)?; let n = p.get_if(i_n, |t| t.is_taddhita())?; let rule = if n.has_tag_in(&[T::Yit, T::Rit]) { @@ -156,16 +155,16 @@ fn try_taddhita_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { if anga.has_text_in(&["devikA", "SiMSapA", "dityavAh", "dIrGasatra", "Sreyas"]) { // dAvikA, ... let adi_ac = anga.text.find(al::is_ac)?; - p.run_at("7.3.1", i, |t| t.set_at(adi_ac, "A")); + p.run_at("7.3.1", i_anga, |t| t.set_at(adi_ac, "A")); } else if anga.has_text_in(&["kekaya", "mitrayu", "pralaya"]) { - p.run_at("7.3.2", i, |t| t.find_and_replace_text("y", "iy")); - } else if anga.text.starts_with("vy") { + p.run_at("7.3.2", i_anga, |t| t.find_and_replace_text("y", "iy")); + } else if anga.starts_with("vy") { // HACK: should properly be only with vi-upasarga. // TODO: also apply for sv-, .etc. - p.run_at("7.3.3", i, |t| t.text.replace_range(..2, "vEy")); + p.run_at("7.3.3", i_anga, |t| t.text.replace_range(..2, "vEy")); } else if anga.has_u_in(DVARA_ADI) { // dvAra -> dOvArika, ... - p.run_at("7.3.4", i, |t| { + p.run_at("7.3.4", i_anga, |t| { let i_yan = t.text.rfind(|c| c == 'y' || c == 'v').expect("ok"); if t.get_at(i_yan) == Some('y') { t.text.insert(i_yan, 'E'); @@ -174,12 +173,14 @@ fn try_taddhita_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { } }); } else if anga.has_text("nyagroDa") { - p.run_at("7.3.5", i, |t| t.text.replace_range(..2, "nEy")); + p.run_at("7.3.5", i_anga, |t| t.text.replace_range(..2, "nEy")); } else { - let adi_ac = anga.text.find(al::is_ac)?; - let ac = anga.get_at(adi_ac)?; + let i_ac = p.find_first_where(|t| t.has_ac())?; + let adi = p.get(i_ac)?; + let adi_ac = adi.text.find(al::is_ac)?; + let ac = adi.get_at(adi_ac)?; let vrddhi = al::to_vrddhi(ac)?; - p.run_at(rule, i, |t| { + p.run_at(rule, i_ac, |t| { t.set_at(adi_ac, vrddhi); }); } @@ -191,24 +192,25 @@ fn try_taddhita_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { /// /// (7.2.115 - 7.3.35) /// Taddhita rules: 7.2.117 - 7.3.31 -fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { - let i_next = p.find_next_where(i, |t| !t.is_empty())?; +fn try_nnit_vrddhi(p: &mut Prakriya, i_anga: usize, i_n: usize) -> Option<()> { + let mut gp = GunaVrddhiPrakriya::new(p, i_anga, i_n); - let mut gp = GunaVrddhiPrakriya::new(p, i, i_next); let n = gp.next(); - let is_nnit = n.has_tag_in(&[T::Yit, T::Rit]); + if !n.has_tag_in(&[T::Yit, T::Rit]) { + return None; + } + // Allow RiN even though it is Nit. Without this check, RiN will be excluded by // `can_use_guna_or_vrddhi`. if !n.has_u("RiN") { gp.check_guna_vrddhi_blocks(); + if gp.done { + return None; + } } - if !is_nnit || gp.done { - return None; - } - - let anga = p.get(i)?; - let n = p.pratyaya(i_next)?; + let anga = p.get(i_anga)?; + let n = p.pratyaya(i_n)?; let is_cin = n.has_u("ciR") || n.has_tag(T::Cinvat); let is_cin_krt = is_cin || n.has_tag(T::Krt); let has_udatta = !anga.has_tag(T::Anudatta); @@ -216,7 +218,7 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { let is_aacam_adi = { let is_aacam = anga.has_u("camu~") && anga.has_gana(Gana::Bhvadi) - && p.find_prev_where(i, |t| t.is_upasarga() && t.has_u("AN")) + && p.find_prev_where(i_anga, |t| t.is_upasarga() && t.has_u("AN")) .is_some(); is_aacam || anga.has_u_in(&["kamu~\\", "wuvama~"]) }; @@ -227,11 +229,11 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { // ajani, avaDi, ... p.step("7.3.35"); } else if is_cin_krt && anga.has_antya('A') { - op::append_agama("7.3.33", p, i, "yu~k"); + op::append_agama("7.3.33", p, i_anga, "yu~k"); } else if anga.has_u("ha\\na~") && !is_cin && !n.has_u("Ral") { p.run("7.3.32", |p| { - p.set(i, op::upadha("A")); - p.set(i, op::antya("t")); + p.set(i_anga, op::upadha("A")); + p.set(i_anga, op::antya("t")); }); } else if anga.has_antya(&*AC) { // The use of "acaH" in 7.2.115 indicates that we should ignore "iko guNavRddhI" which @@ -240,7 +242,7 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { let antya = anga.antya()?; if !al::is_vrddhi(antya) { let sub = al::to_vrddhi(antya)?; - p.run_at("7.2.115", i, op::antya(sub)); + p.run_at("7.2.115", i_anga, op::antya(sub)); } } else if anga.has_upadha('a') { if anga.has_u_in(&["kamu~\\", "wuvama~"]) { @@ -249,7 +251,7 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { } // pAcayati - p.run_at("7.2.116", i, op::upadha("A")); + p.run_at("7.2.116", i_anga, op::upadha("A")); } Some(()) @@ -258,19 +260,18 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { /// Tries rules that replace an anga's vowel with a vrddhi substitute. /// /// Example: kf + i + ta -> kArita -fn try_vrddhi_adesha(p: &mut Prakriya, i: usize) -> Option<()> { - let dhatu = p.get_if(i, |t| !t.has_tag(T::FlagGunaApavada))?; - let i_n = p.find_next_where(i, |t| !t.is_empty())?; +fn try_vrddhi_adesha(p: &mut Prakriya, i_anga: usize, i_n: usize) -> Option<()> { + let anga = p.get_if(i_anga, |t| !t.has_tag(T::FlagGunaApavada))?; let n = p.pratyaya(i_n)?; - if dhatu.has_text("mfj") && !n.is_knit() { - let mut gp = GunaVrddhiPrakriya::new(p, i, i_n); + if anga.has_text("mfj") && !n.last().is_knit() { + let mut gp = GunaVrddhiPrakriya::new(p, i_anga, i_n); gp.check_guna_vrddhi_blocks(); gp.try_run("7.2.114", |t| t.try_upadha_vrddhi()); } else if n.first().is_taddhita() { - try_taddhita_vrddhi(p, i); + try_taddhita_vrddhi(p, i_anga, i_n); } else { - try_nnit_vrddhi(p, i); + try_nnit_vrddhi(p, i_anga, i_n); } Some(()) @@ -278,17 +279,17 @@ fn try_vrddhi_adesha(p: &mut Prakriya, i: usize) -> Option<()> { /// Runs rules that replace an anga's vowel with its corresponding guna. /// Example: buD + a + ti -> boDati -fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { - let j = p.find_next_where(i, |t| !t.is_empty() && !t.has_u("pu~k"))?; +fn try_guna_adesha(p: &mut Prakriya, i_anga: usize) -> Option<()> { + let i_n = p.find_next_where(i_anga, |t| !t.is_empty() && !t.has_u("pu~k"))?; + let anga = p.get_if(i_anga, |t| !t.is_agama() && !t.has_tag(T::FlagGunaApavada))?; - let anga = p.get_if(i, |t| !t.is_agama() && !t.has_tag(T::FlagGunaApavada))?; - let n = p.pratyaya(j)?; + let n = p.pratyaya(i_n)?; - let is_sarva_ardha = n.has_tag_in(&[T::Sarvadhatuka, T::Ardhadhatuka]); - let piti_sarvadhatuke = n.all(&[T::pit, T::Sarvadhatuka]); + let is_sarva_ardha = n.last().has_tag_in(&[T::Sarvadhatuka, T::Ardhadhatuka]); + let piti_sarvadhatuke = n.last().has_all_tags(&[T::pit, T::Sarvadhatuka]); let is_ik = anga.has_antya(&*IK); - let mut gp = GunaVrddhiPrakriya::new(p, i, j); + let mut gp = GunaVrddhiPrakriya::new(p, i_anga, i_n); let anga = gp.anga(); let n = gp.next(); @@ -303,7 +304,7 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { { // tfneQi; otherwise, tfRahAni, tfRQaH. // HACK: check for absence of `Nit` on first term to prevent tfnhyAt -> tfRihyAt - p.run_at("7.3.92", i, op::mit("i")); + p.run_at("7.3.92", i_anga, op::mit("i")); } else if is_sarva_ardha { // Exceptions if anga.has_text_in(&["BU", "sU"]) && n.has_tag(T::Tin) && piti_sarvadhatuke { @@ -324,7 +325,7 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { // If vrddhi is declined, UrRu will take guna by 7.3.84 below. gp.run_optional("7.3.90", op::antya(sub)); } - } else if gp.p.get(i + 1)?.has_tag(T::Luk) && !anga.has_tag(T::Abhyasta) { + } else if gp.p.get(i_anga + 1)?.has_tag(T::Luk) && !anga.has_tag(T::Abhyasta) { // Why check for abhyasta? // // > na abhyastasya ityetadiha anuvartate, yoyoti, roroti ityevamādyartham. @@ -338,7 +339,7 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { let anga = gp.anga(); let n = gp.next(); let is_laghu_upadha = anga.has_upadha(&*HRASVA); - let is_puganta = gp.p.has(i + 1, |t| t.has_u("pu~k")); + let is_puganta = gp.p.has(i_anga + 1, |t| t.has_u("pu~k")); // HACK to ignore antya A and avoid applying guna to it. if is_puganta || is_laghu_upadha { @@ -430,9 +431,9 @@ fn try_r_guna_before_lit(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } -fn run_for_index(p: &mut Prakriya, i: usize) -> Option<()> { - let anga = p.get_if(i, |t| !t.is_agama())?; - let i_n = p.find_next_where(i, |t| !t.is_empty())?; +fn run_for_index(p: &mut Prakriya, i_anga: usize) -> Option<()> { + let i_n = p.find_next_where(i_anga, |t| !t.is_empty())?; + let anga = p.get(i_anga)?; let n = p.get(i_n)?; if anga.has_u("jAgf") @@ -441,7 +442,7 @@ fn run_for_index(p: &mut Prakriya, i: usize) -> Option<()> { { // jAgf-guna takes priority over vrddhi. Skip if already applied (e.g. for jAgf + Ric). if anga.has_antya('f') { - p.run_at("7.3.85", i, |t| { + p.run_at("7.3.85", i_anga, |t| { t.set_antya("ar"); t.add_tag(T::FlagGuna); }); @@ -449,18 +450,21 @@ fn run_for_index(p: &mut Prakriya, i: usize) -> Option<()> { } else { // Vrddhi takes priority over guna. For example, Ric is Ardhadhatuka (guna) // and Rit (vrddhi), but it will cause vrddhi if possible. - try_vrddhi_adesha(p, i); - try_guna_adesha(p, i); + try_vrddhi_adesha(p, i_anga, i_n); + try_guna_adesha(p, i_anga); // TODO: 7.4.23-4 } + try_r_guna_before_lit(p, i_anga); + Some(()) } pub fn run(p: &mut Prakriya) -> Option<()> { for i in 0..p.terms().len() { - run_for_index(p, i); - try_r_guna_before_lit(p, i); + if p.has(i, |t| t.is_anga()) { + run_for_index(p, i); + } } p.maybe_save_sthanivat(); diff --git a/vidyut-prakriya/src/angasya/subanta.rs b/vidyut-prakriya/src/angasya/subanta.rs index bcabff1..be2b94e 100644 --- a/vidyut-prakriya/src/angasya/subanta.rs +++ b/vidyut-prakriya/src/angasya/subanta.rs @@ -2,16 +2,14 @@ subanta ======= -Various rules that create subantas. These rules come primarily from adhyaya 7. +Various rules that create subantas. These rules come primarily from adhyayas 6 nd 7. If a subanta rule is deeply intertwined with other kinds of rules, we keep it out of this module in favor of more generic modules like `angasya.rs`. */ use crate::angasya::asiddhavat; use crate::core::operators as op; -use crate::core::Prakriya; -use crate::core::Tag as T; -use crate::core::Term; +use crate::core::{Prakriya, Rule, Tag as T, Term}; use crate::it_samjna; use crate::samjna; use crate::sounds as al; @@ -42,6 +40,84 @@ fn yatha(needle: &str, old: &'static [&str], new: &'static [&str]) -> Option<&'s None } +/// Runs various rules that cause dirgha-adesha in the anga. +/// +/// 6.4.2 - 6.4.19 +fn try_dirgha_adesha_after_num_agama(p: &mut Prakriya) -> Option<()> { + let i_sup = p.find_last(T::Sup)?; + let i_anga = p.find_prev_where(i_sup, |t| !t.is_agama())?; + + let anga = p.get(i_anga)?; + let sup = p.get(i_sup)?; + let has_nuw_agama = if i_anga + 1 != i_sup { + p.get(i_anga + 1)?.has_u("nu~w") + } else { + false + }; + + if sup.has_text("Am") && has_nuw_agama { + if anga.has_text_in(&["tisf", "catasf"]) { + // No change. + p.step("6.4.4") + } else if anga.has_text("nf") { + // nfRAm, nFRAm + let sub = al::to_dirgha(anga.antya()?)?; + p.optional_run_at("6.4.6", i_anga, op::antya(&sub.to_string())); + } else if anga.has_antya('n') { + let sub = al::to_dirgha(anga.upadha()?)?; + p.run_at("6.4.7", i_anga, op::upadha(&sub.to_string())); + } else if anga.has_antya(&*AC) { + let sub = al::to_dirgha(anga.antya()?)?; + p.run_at("6.4.3", i_anga, op::antya(&sub.to_string())); + } + } else if sup.is_sarvanamasthana() && !sup.is_sambuddhi() { + let anga = p.get(i_anga)?; + let sup = p.get(i_sup)?; + let sau = sup.has_u("su~"); + if anga.has_antya('n') { + if anga.ends_with("in") || anga.has_text("pUzan") { + let sub = al::to_dirgha(anga.upadha()?)?; + if sup.has_u("Si") { + // yogIni + p.run_at("6.4.12", i_anga, op::upadha(&sub.to_string())); + } else if sau { + // yogI + p.run_at("6.4.13", i_anga, op::upadha(&sub.to_string())); + } + } else if !sup.is_lupta() { + // PalAni + let sub = al::to_dirgha(anga.upadha()?)?; + p.run_at("6.4.8", i_anga, op::upadha(&sub.to_string())); + } + } else if (anga.ends_with("ns") && anga.len() >= 3) + || p.custom_view(0, i_anga)?.has_text("mahant") + { + let c = anga.len() - 3; + let sub = al::to_dirgha(anga.get_at(c)?)?; + p.run_at("6.4.10", i_anga, |t| { + t.set_at(c, &sub.to_string()); + }); + } else if anga.has_text("ap") + || anga.has_u_in(&["tfn", "tfc"]) + || anga.has_tag(T::FlagTrjvat) + || anga.has_u_in(&[ + "svasf", "naptf", "nezwf", "tvaswf", "kzawf", "hotf", "potf", "praSAstf", + ]) + { + // Must follow guna (f -> ar) so that this rule can perform upadhA-dIrgha. + let sub = al::to_dirgha(anga.upadha()?)?; + p.run_at("6.4.11", i_anga, op::upadha(&sub.to_string())); + } else if anga.has_text("svanp") { + // for svAmpi and svampi (svap + [jas -> Si]) + p.optional_run_at(Rule::Kaumudi("446"), i_anga, |t| { + t.set_at(t.len() - 3, "A"); + }); + } + } + + Some(()) +} + /// Runs various rules that cause dirgha-adesha in the anga. /// This specific dirgha-adesha must occur before inserting num-agama. /// @@ -51,11 +127,11 @@ fn try_dirgha_adesha_before_num_agama(p: &mut Prakriya) -> Option<()> { let i_anga = p.find_prev_where(i_sup, |t| !t.is_agama())?; let anga = p.get(i_anga)?; - let sup = p.get(i_sup)?; + let sup = p.get_if(i_sup, |t| !t.is_lupta())?; let sau = sup.has_u("su~"); let is_atu = anga.has_tag(T::udit) && anga.ends_with("at"); - if sup.is_sarvanamasthana() && !sup.has_tag(T::Sambuddhi) { + if sup.is_sarvanamasthana() && !sup.is_sambuddhi() { if (is_atu || anga.ends_with("as")) && sau && !anga.is_dhatu() { let sub = al::to_dirgha(anga.upadha()?)?; p.run_at("6.4.14", i_anga, op::upadha(&sub.to_string())); @@ -73,7 +149,7 @@ fn try_dirgha_adesha_before_num_agama(p: &mut Prakriya) -> Option<()> { /// commentson that function for details. fn try_sup_adesha(p: &mut Prakriya, i_anga: usize, i_sup: usize) -> Option<()> { let anga = p.get(i_anga)?; - let sup = p.get(i_sup)?; + let sup = p.get_if(i_sup, |t| !t.is_lupta())?; let is_napumsaka = p.has_tag(T::Napumsaka); let is_jas_shas = sup.has_u_in(&["jas", "Sas"]); @@ -233,7 +309,7 @@ fn try_napumsaka_su_am_adesha(p: &mut Prakriya, i_anga: usize) -> Option<()> { fn try_add_sup_agamas(p: &mut Prakriya, i_anga: usize) -> Option<()> { let i_sup = p.find_next_where(i_anga, |t| t.is_sup())?; - let anga = p.nyap_pratipadika(i_anga)?; + let anga = p.nyapu_pratipadika(i_anga)?; let sup = p.get(i_sup)?; // Check for `Bahuvacana` explicitly to exclude the `Am`-adesha for mAlAyAm, etc. @@ -258,7 +334,11 @@ fn try_add_num_agama_to_anga(p: &mut Prakriya, i_anga: usize) -> Option<()> { let sup = p.get(i_anga + 1)?; let napum = p.has_tag(T::Napumsaka); - if anga.has_tag_in(&[T::udit, T::fdit]) && !anga.is_dhatu() { + let is_ugit = anga.has_tag_in(&[T::udit, T::fdit]); + let is_ac = i_anga > 0 && p.has(i_anga - 1, |t| t.has_u("ancu~")); + let is_sarva = sup.is_sarvanamasthana(); + + if (is_ugit && !anga.is_dhatu()) || is_ac { let shatr = anga.has_u("Satf~"); // No `?` for i_prev here to avoid exiting early for e.g. "pums". let i_prev = p.find_prev_where(i_anga, |t| !t.is_empty()); @@ -280,7 +360,7 @@ fn try_add_num_agama_to_anga(p: &mut Prakriya, i_anga: usize) -> Option<()> { p.optional_run_at("7.1.80", i_anga, add_num); } } - } else if sup.is_sarvanamasthana() { + } else if is_sarva { if shatr && p.has(i_prev?, |t| t.is_abhyasta()) { if napum { // dadati, dadanti, ... @@ -290,7 +370,8 @@ fn try_add_num_agama_to_anga(p: &mut Prakriya, i_anga: usize) -> Option<()> { p.step("7.1.78"); } } else { - p.run_at("7.1.70", i_anga, add_num); + let i_non_empty = if is_ac { i_anga - 1 } else { i_anga }; + p.run_at("7.1.70", i_non_empty, add_num); } } } else if sup.is_sarvanamasthana() { @@ -319,7 +400,7 @@ fn try_misc_rules(p: &mut Prakriya, i_anga: usize, i_sup: usize) -> Option<()> { let anga = p.get(i_anga)?; let sup = p.get(i_sup)?; let sau = sup.has_u("su~"); - let sarvanamasthane = sup.has_tag(T::Sarvanamasthana); + let sarvanamasthane = sup.is_sarvanamasthana(); if sau && anga.has_u("anaquh") { p.run_at("7.1.82", i_anga, |t| t.set_antya("nh")); @@ -356,9 +437,9 @@ fn try_misc_rules(p: &mut Prakriya, i_anga: usize, i_sup: usize) -> Option<()> { fn try_sarvanamasthane_asambuddhau(p: &mut Prakriya, i_anga: usize, i: usize) -> Option<()> { let anga = p.get(i_anga)?; - let sup = p.get(i)?; + let sup = p.get_if(i, |t| !t.is_lupta())?; - let sambuddhau = sup.has_tag(T::Sambuddhi); + let sambuddhau = sup.is_sambuddhi(); let sarve = sup.is_sarvanamasthana(); let sarve_asam = sarve && !sambuddhau; let sau = sup.has_u("su~"); @@ -379,7 +460,10 @@ fn try_sarvanamasthane_asambuddhau(p: &mut Prakriya, i_anga: usize, i: usize) -> t.add_tag(T::FlagTrjvat); t.remove_tag(T::Ghi); }; - if sarve_asam { + if p.has_tag(T::Stri) { + // krozwrI, ... + p.run_at("7.1.96", i_anga, mark_trjvat); + } else if sarve_asam { // krozwA, krozwArO, krozwAraH, ... p.run_at("7.1.95", i_anga, mark_trjvat); } else if sup.has_adi(&*AC) && sup.has_tag_in(&[T::V3, T::V4, T::V5, T::V6, T::V7]) { @@ -438,9 +522,9 @@ fn try_anga_adesha_before_vibhakti_changes(p: &mut Prakriya, i_anga: usize) -> O p.run_at("7.1.53", i_anga, op::text("traya")); } - let anga = p.nyap_pratipadika(i_anga)?; + let anga = p.nyapu_pratipadika(i_anga)?; let v = p.get(i_v)?; - if anga.first().has_text_in(&["tisf", "catasf"]) + if anga.last().has_text_in(&["tisf", "catasf"]) && p.has_tag(T::Stri) && p.has(i_anga + 1, |t| t.has_adi(&*AC)) { @@ -455,7 +539,9 @@ fn try_anga_adesha_before_vibhakti_changes(p: &mut Prakriya, i_anga: usize) -> O p.terms_mut().remove(i_start + 1); p.step(rule); }); - } else if anga.has_u_in(gana::TYAD_ADI) { + } else if anga.last().has_u_in(gana::TYAD_ADI) && !anga.last().has_text_in(&["asmad", "yuzmad"]) + { + // HACK ^ : ignore asmad and yuzmad, which we handle later. let sau = v.has_u("su~") && !v.is_lupta(); if sau && anga.has_u("adas") { @@ -472,6 +558,14 @@ fn try_anga_adesha_before_vibhakti_changes(p: &mut Prakriya, i_anga: usize) -> O } else { p.run_at("7.2.110", i_anga, |t| t.set_text("iyam")); } + } else if anga.last().has_text("kim") { + if v.has_adi('t') || v.has_adi('h') { + p.run_at("7.2.104", i_anga, op::text("ku")); + } else if v.has_u("at") { + p.run_at("7.2.105", i_anga, op::text("kva")); + } else if !v.is_empty() { + p.run_at("7.2.103", i_anga, op::text("ka")); + } } else if !v.is_empty() { // tyaH, tyO, tye, ... p.run_at("7.2.102", i_anga, op::antya("a")); @@ -491,14 +585,6 @@ fn try_anga_adesha_before_vibhakti_changes(p: &mut Prakriya, i_anga: usize) -> O t.add_tag(T::FlagSaAdeshadi); }); } - } else if anga.last().has_text("kim") { - if v.has_adi('t') || v.has_adi('h') { - p.run_at("7.2.104", i_anga, op::text("ku")); - } else if v.has_u("at") { - p.run_at("7.2.105", i_anga, op::text("kva")); - } else if !v.is_empty() { - p.run_at("7.2.103", i_anga, op::text("ka")); - } } Some(()) @@ -514,9 +600,7 @@ fn try_anga_adesha_after_vibhakti_changes(p: &mut Prakriya) -> Option<()> { return None; } - if anga.has_text("rE") && sup.has_adi(&*HAL) { - p.run_at("7.2.85", i, op::antya("A")); - } else if anga.has_text_in(&["yuzmad", "asmad"]) { + if anga.has_text_in(&["yuzmad", "asmad"]) { let anadesha = !sup.last().has_any_lakshana(); if sup.has_adi(&*AC) && anadesha { @@ -675,9 +759,19 @@ fn try_taa_adesha(p: &mut Prakriya, i_anga: usize, i: usize) -> Option<()> { /// - Drop su~ (for adas) /// - Modify sarvanAma bases (to allow wAp-pratyaya). pub fn run_before_stritva(p: &mut Prakriya) -> Option<()> { - let i_anga = p.find_last_where(|t| t.is_pratipadika_or_nyap())?; + let i_anga = p.find_last_where(|t| t.is_pratipadika_or_nyapu())?; + let i_sup = p.find_next_where(i_anga, |t| t.is_pratyaya())?; try_napumsaka_su_am_adesha(p, i_anga); + + let anga = p.get(i_anga)?; + let sup = p.get(i_sup)?; + // Must run after su-lopa (prari) + // Must run before num-Agama (prarIRAm) + if anga.has_u("rE") && sup.is_vibhakti() && sup.has_adi(&*HAL) { + p.run_at("7.2.85", i_anga, op::antya("A")); + } + try_add_sup_agamas(p, i_anga); try_anga_adesha_before_vibhakti_changes(p, i_anga); @@ -686,13 +780,20 @@ pub fn run_before_stritva(p: &mut Prakriya) -> Option<()> { /// Applies various rules before the "bhasya" section in 6.4. fn run_before_bhasya(p: &mut Prakriya) -> Option<()> { - let i_anga = p.find_last_where(|t| t.is_pratipadika_or_nyap())?; - let i_next = i_anga + 1; + // Process *all* sup-pratyayas, including those that are part of aluk-samAsas. + for i_anga in 0..p.terms().len() { + let i_sup = i_anga + 1; + let term = p.get(i_anga)?; + if term.is_pratipadika_or_nyapu() { + try_sup_adesha(p, i_anga, i_sup); + } - try_sup_adesha(p, i_anga, i_next); + // Must run before tA adesha for krozwrA, krozwunA + try_sarvanamasthane_asambuddhau(p, i_anga, i_sup); + } - // Must run before tA adesha for krozwrA, krozwunA - try_sarvanamasthane_asambuddhau(p, i_anga, i_next); + let i_anga = p.find_last_where(|t| t.is_pratipadika_or_nyapu())?; + let i_next = i_anga + 1; let anga = p.get(i_anga)?; let sup = p.get(i_next)?; @@ -722,12 +823,14 @@ fn run_after_bhasya(p: &mut Prakriya) -> Option<()> { let i_sup = p.find_next_where(i_anga, |t| t.is_sup())?; try_misc_rules(p, i_anga, i_sup); + try_dirgha_adesha_before_num_agama(p); try_add_num_agama_to_anga(p, i_anga); try_ni_adesha(p, i_anga, i_sup); try_pratipadika_guna(p, i_anga, i_sup); + try_dirgha_adesha_after_num_agama(p); // TODO: replace uses of `i_anga` above if this works. - let i_anga = p.find_last_where(|t| t.is_pratipadika() || t.is_nyap_pratyaya())?; + let i_anga = p.find_last_where(|t| t.is_pratipadika_or_nyapu())?; try_add_nit_agamas(p, i_anga); Some(()) @@ -742,7 +845,6 @@ pub fn run(p: &mut Prakriya) { samjna::try_run_for_pada_or_bha(p); asiddhavat::bhasya(p); - try_dirgha_adesha_before_num_agama(p); run_after_bhasya(p); try_anga_adesha_after_vibhakti_changes(p); } diff --git a/vidyut-prakriya/src/args.rs b/vidyut-prakriya/src/args.rs index daf8174..d77f26f 100644 --- a/vidyut-prakriya/src/args.rs +++ b/vidyut-prakriya/src/args.rs @@ -11,7 +11,7 @@ on which strings are valid arguments in `from_str`, please read the source code */ mod macros; -mod dhatu; +pub(crate) mod dhatu; mod krt; mod pada; mod pratipadika; diff --git a/vidyut-prakriya/src/args/dhatu.rs b/vidyut-prakriya/src/args/dhatu.rs index 8505a36..a8772f7 100644 --- a/vidyut-prakriya/src/args/dhatu.rs +++ b/vidyut-prakriya/src/args/dhatu.rs @@ -1,3 +1,4 @@ +use crate::args::Pratipadika; use crate::core::errors::Error; use crate::enum_boilerplate; use wasm_bindgen::prelude::wasm_bindgen; @@ -90,12 +91,23 @@ enum_boilerplate!(Antargana, { /// For details on what these pratyayas mean and what kinds of words they produce, see the comments /// below. #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +#[allow(non_camel_case_types)] #[wasm_bindgen] pub enum Sanadi { - /// `san`, which creates desiderative roots per 3.1.7. + /// `kAmyac`, which creates nAma-dhAtus per 3.1.9. + kAmyac, + + /// `kyaN`, which creates nAma-dhAtus per 3.1.11. + kyaN, + + /// `kyac`, which creates nAma-dhAtus per 3.1.8. + kyac, + + /// `Nic`, which creates causal roots per 3.1.26. /// - /// Examples: buBUzati, ninIzati. - San, + /// Examples: BAvayati, nAyayati. + Ric, + /// `yaN`, which creates intensive roots per 3.1.22. For certain dhatus, the semantics are /// instead "crooked movement" (by 3.1.23) or "contemptible" action (by 3.1.24). /// @@ -103,28 +115,42 @@ pub enum Sanadi { /// /// Constraints: can be used only if the dhatu starts with a consonant and has exactly one /// vowel. If this constraint is violated, our APIs will return an `Error`. - Yan, + yaN, + /// `yaN`, with elision per 2.4.74. This is often listed separately due to its rarity and its /// very different form. /// /// Examples: boBavIti, boBoti, nenayIti, neneti. - YanLuk, - /// `Nic`, which creates causal roots per 3.1.26. + yaNLuk, + + /// `san`, which creates desiderative roots per 3.1.7. /// - /// Examples: BAvayati, nAyayati. - Nic, + /// Examples: buBUzati, ninIzati. + san, } enum_boilerplate!(Sanadi, { - San => "san", - Yan => "yaN", - YanLuk => "yaN-luk", - Nic => "Ric", + san => "san", + kyac => "kyac", + kAmyac => "kAmyac", + kyaN => "kyaN", + yaN => "yaN", + yaNLuk => "yaN-luk", + Ric => "Ric", }); /// The verb root to use for the derivation. #[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct Dhatu { +pub enum Dhatu { + /// Indicates a muladhAtu from the Dhatupatha. + Mula(Muladhatu), + /// Indicates a nAma-dhAtu created with a sanAdi-pratyaya. + Nama(Namadhatu), +} + +/// A dhatu from the Dhatupatha. +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct Muladhatu { upadesha: String, gana: Gana, antargana: Option, @@ -132,24 +158,16 @@ pub struct Dhatu { prefixes: Vec, } -impl Dhatu { - /// Creates a new dhatu with its gana. - /// - /// `upadesha` refers to the dhatu in its *aupadeshka* form. `upadesha` should be an SLP1 - /// string and include any necessary svaras. For example values, see the `dhatupatha.tsv` file - /// included with this crate. - /// - /// `gana` refers to one of the ten major verb classes. - /// - /// For more customization, use the `builder()` API instead. - /// - /// ### Example - /// - /// ``` - /// # use vidyut_prakriya::args::{Dhatu, Gana}; - /// let bhu = Dhatu::new("BU", Gana::Bhvadi); - /// let kr = Dhatu::new("qukf\\Y", Gana::Tanadi); - /// ``` +/// A dhatu created from a subanta. +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct Namadhatu { + pratipadika: Pratipadika, + sanadi: Vec, + pub(crate) prefixes: Vec, +} + +impl Muladhatu { + /// Creates a new Muladhatu pub fn new(upadesha: &str, gana: Gana) -> Self { Self { upadesha: String::from(upadesha), @@ -159,7 +177,6 @@ impl Dhatu { prefixes: Vec::new(), } } - /// The dhatu as stated in its aupadeshka form. `upadesha` should be an SLP1 string that /// includes any necessary svaras. For examples, see the `dhatu` column in the /// `data/dhatupatha.tsv` file included in this crate. @@ -192,31 +209,144 @@ impl Dhatu { self.gana == gana.into() } - /// Sets the prefixes on the dhatu. - pub fn with_prefixes(mut self, values: &[impl AsRef]) -> Self { - self.prefixes.clear(); - self.prefixes - .extend(values.iter().map(|x| String::from(x.as_ref()))); + /// Sets the sanadi-pratyayas on the dhatu. + pub fn with_antargana(mut self, antargana: Antargana) -> Self { + self.antargana = Some(antargana); self } +} - /// Sets the sanadi-pratyayas on the dhatu. - pub fn with_sanadi(mut self, sanadi: &[Sanadi]) -> Self { - self.sanadi.clear(); - self.sanadi.extend(sanadi); - self +impl Namadhatu { + /// The pratipadika to use as the basis of this dhatu. + pub fn pratipadika(&self) -> &Pratipadika { + &self.pratipadika } - /// Sets the sanadi-pratyayas on the dhatu. - pub fn with_antargana(mut self, antargana: Option) -> Self { - self.antargana = antargana; - self + /// The sanAdi pratyayas to use with this dhatu. + pub fn sanadi(&self) -> &Vec { + &self.sanadi + } + + /// The prefixes to use with the dhatu. + pub fn prefixes(&self) -> &Vec { + &self.prefixes + } +} + +impl Dhatu { + /// Creates a new dhatu with its gana. + /// + /// `upadesha` refers to the dhatu in its *aupadeshka* form. `upadesha` should be an SLP1 + /// string and include any necessary svaras. For example values, see the `dhatupatha.tsv` file + /// included with this crate. + /// + /// `gana` refers to one of the ten major verb classes. + /// + /// For more customization, use the `builder()` API instead. + /// + /// ### Example + /// + /// ``` + /// # use vidyut_prakriya::args::{Dhatu, Gana}; + /// let bhu = Dhatu::new("BU", Gana::Bhvadi); + /// let kr = Dhatu::new("qukf\\Y", Gana::Tanadi); + /// ``` + pub fn mula(upadesha: &str, gana: Gana) -> Self { + Self::Mula(Muladhatu::new(upadesha, gana)) + } + + /// Creates a new namadhatu with its sanadi-pratyaya. + /// + /// If `sanadi` is `None`, the program will try finding a sanAdi match by appling the + /// rules in 3.1. If no match is found, the prakriya will abort. + pub fn nama(subanta: Pratipadika, sanadi: Option) -> Self { + let sanadi = match sanadi { + Some(x) => vec![x], + None => Vec::new(), + }; + Self::Nama(Namadhatu { + pratipadika: subanta, + sanadi, + prefixes: Vec::new(), + }) } /// Returns a new builder for this struct. pub fn builder() -> DhatuBuilder { DhatuBuilder::default() } + + /// The sanAdi pratyayas to use with this dhatu. + pub fn sanadi(&self) -> &Vec { + match self { + Self::Mula(m) => m.sanadi(), + Self::Nama(n) => n.sanadi(), + } + } + + /// The prefixes to use with the dhatu. + pub fn prefixes(&self) -> &Vec { + match self { + Self::Mula(m) => m.prefixes(), + Self::Nama(n) => n.prefixes(), + } + } + + /// The upadesha to use with this dhatu, if defined. + pub fn upadesha(&self) -> Option<&String> { + match self { + Self::Mula(m) => Some(m.upadesha()), + _ => None, + } + } + + /// The gana to use with this dhatu, if defined. + pub fn gana(&self) -> Option { + match self { + Self::Mula(m) => Some(m.gana()), + _ => None, + } + } + + /// The antargana to use with this dhatu, if defined. + pub fn antargana(&self) -> Option { + match self { + Self::Mula(m) => m.antargana(), + _ => None, + } + } + + /// Sets the prefixes on the dhatu. + pub fn with_prefixes(mut self, values: &[impl AsRef]) -> Self { + match self { + Self::Mula(ref mut m) => { + m.prefixes.clear(); + m.prefixes + .extend(values.iter().map(|x| String::from(x.as_ref()))); + } + Self::Nama(ref mut n) => { + n.prefixes.clear(); + n.prefixes + .extend(values.iter().map(|x| String::from(x.as_ref()))); + } + } + self + } + + /// Sets the sanadi-pratyayas on the dhatu. + pub fn with_sanadi(mut self, sanadi: &[Sanadi]) -> Self { + match self { + Self::Mula(ref mut m) => { + m.sanadi.clear(); + m.sanadi.extend(sanadi); + } + Self::Nama(ref mut n) => { + n.sanadi.clear(); + n.sanadi.extend(sanadi); + } + } + self + } } /// Convenience struct for building a `Dhatu` object. @@ -230,7 +360,10 @@ pub struct DhatuBuilder { } impl DhatuBuilder { - /// Sets the upadesha of the dhatu. + /// Sets the aupadeshika form of the dhatu. + /// + /// - For mula dhatus, this should be the dhatu as listed in the Dhatupatha, including svaras. + /// - For namadhatus, this should be the text of the pratipadika. pub fn upadesha(mut self, text: &str) -> Self { self.upadesha = Some(String::from(text)); self @@ -242,7 +375,7 @@ impl DhatuBuilder { self } - /// Sets the antargana of the dhatu, if one is necessary. + /// Sets whether or not this pub fn antargana(mut self, value: Antargana) -> Self { self.antargana = Some(value); self @@ -265,7 +398,7 @@ impl DhatuBuilder { /// Converts the arguments in this builder into a `Dhatu` struct. pub fn build(self) -> Result { - Ok(Dhatu { + Ok(Dhatu::Mula(Muladhatu { upadesha: match self.upadesha { Some(x) => x, _ => return Err(Error::missing_required_field("upadesha")), @@ -277,6 +410,6 @@ impl DhatuBuilder { antargana: self.antargana, sanadi: self.sanadi, prefixes: self.prefixes, - }) + })) } } diff --git a/vidyut-prakriya/src/args/krt.rs b/vidyut-prakriya/src/args/krt.rs index e4273aa..5ed0794 100644 --- a/vidyut-prakriya/src/args/krt.rs +++ b/vidyut-prakriya/src/args/krt.rs @@ -1,5 +1,7 @@ +use crate::args::dhatu::Dhatu; use crate::args::unadi::Unadi; use crate::args::Lakara; +use crate::args::{Linga, Vacana, Vibhakti}; use crate::core::errors::*; use crate::enum_boilerplate; use wasm_bindgen::prelude::wasm_bindgen; @@ -33,6 +35,10 @@ pub enum BaseKrt { Aluc, /// -Aru Aru, + /// -ika + ika, + /// -ikavaka + ikavaka, /// -itra itra, /// -in. The trailing `_` is to avoid colliding with Rust's `in` keyword. @@ -133,6 +139,8 @@ pub enum BaseKrt { wak, /// -a qa, + /// -ara, + qara, /// -u qu, /// -a @@ -222,6 +230,8 @@ enum_boilerplate!(BaseKrt, { ap => "ap", Aluc => "Aluc", Aru => "Aru", + ika => "ika", + ikavaka => "ikavaka", itra => "itra", in_ => "in", ini => "ini~", @@ -272,6 +282,7 @@ enum_boilerplate!(BaseKrt, { wa => "wa", wak => "wak", qa => "qa", + qara => "qara", qu => "qu", Ra => "Ra", Ramul => "Ramu~l", @@ -416,14 +427,44 @@ impl Upapada { } /// The information required to derive a krdanta in the grammar. -pub struct KrdantaArgs { +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct Krdanta { + dhatu: Dhatu, krt: Krt, artha: Option, lakara: Option, upapada: Option, + /// The sup-pratyaya to use. + sup: Option<(Linga, Vibhakti, Vacana)>, + require: Option, } -impl KrdantaArgs { +impl Krdanta { + /// Defines a simple `Krdanta`. + /// + /// For more options, use `Krdanta::builder()` instead. + pub fn new(dhatu: Dhatu, krt: impl Into) -> Self { + Self { + dhatu, + krt: krt.into(), + artha: None, + lakara: None, + upapada: None, + sup: None, + require: None, + } + } + + /// Returns a new builder for this struct. + pub fn builder() -> KrdantaBuilder { + KrdantaBuilder::default() + } + + /// The dhatu to use in the derivation. + pub fn dhatu(&self) -> &Dhatu { + &self.dhatu + } + /// The krt pratyaya to use in the derivation. pub fn krt(&self) -> Krt { self.krt @@ -458,22 +499,37 @@ impl KrdantaArgs { self.artha } - /// Returns a new builder for this struct. - pub fn builder() -> KrdantaArgsBuilder { - KrdantaArgsBuilder::default() + /// Returns the arguments for the `sup`-pratyaya that the samasa will take. If none, derive the + /// samasa as a pratipadika. + pub fn sup(&self) -> Option<(Linga, Vibhakti, Vacana)> { + self.sup + } + + /// The value that the krdanta must match, if defined. + pub fn require(&self) -> &Option { + &self.require } } /// Convenience struct for building a `KrdantaArgs` object. #[derive(Clone, Default, Eq, PartialEq)] -pub struct KrdantaArgsBuilder { +pub struct KrdantaBuilder { + dhatu: Option, krt: Option, upapada: Option, artha: Option, lakara: Option, + sup: Option<(Linga, Vibhakti, Vacana)>, + require: Option, } -impl KrdantaArgsBuilder { +impl KrdantaBuilder { + /// Sets the krt-pratyaya to use in the derivation. + pub fn dhatu(&mut self, dhatu: Dhatu) -> &mut Self { + self.dhatu = Some(dhatu); + self + } + /// Sets the krt-pratyaya to use in the derivation. pub fn krt(&mut self, val: impl Into) -> &mut Self { self.krt = Some(val.into()); @@ -501,11 +557,27 @@ impl KrdantaArgsBuilder { self } + /// Sets the samasa type to use in the derivation. + pub fn sup(&mut self, tuple: (Linga, Vibhakti, Vacana)) -> &mut Self { + self.sup = Some(tuple); + self + } + + /// Sets the value that the krdanta must have. + pub fn require(&mut self, text: impl AsRef) -> &mut Self { + self.require = Some(text.as_ref().to_string()); + self + } + /// Converts the arguments in this builder into a `TinantaArgs` struct. /// /// `build()` will fail if any args are missing. - pub fn build(&self) -> Result { - Ok(KrdantaArgs { + pub fn build(&self) -> Result { + Ok(Krdanta { + dhatu: match &self.dhatu { + Some(x) => x.clone(), + _ => return Err(Error::missing_required_field("dhatu")), + }, krt: match self.krt { Some(x) => x, _ => return Err(Error::missing_required_field("krt")), @@ -513,6 +585,8 @@ impl KrdantaArgsBuilder { upapada: self.upapada.as_ref().cloned(), lakara: self.lakara, artha: self.artha, + sup: self.sup, + require: self.require.clone(), }) } } diff --git a/vidyut-prakriya/src/args/pada.rs b/vidyut-prakriya/src/args/pada.rs index 51a6213..750c52e 100644 --- a/vidyut-prakriya/src/args/pada.rs +++ b/vidyut-prakriya/src/args/pada.rs @@ -1,47 +1,51 @@ -use crate::core::{Tag, Term}; +use crate::args::{Subanta, Tinanta}; /// Models a Sanskrit pada. -#[derive(Clone)] -pub struct Pada { - /// The terms that compose this pada. - terms: Vec, +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub enum Pada { + /// A nominal word or an indeclinable. + Subanta(Subanta), + /// A verb. + Tinanta(Tinanta), + /// A "chunk of text" without any specific morphology. This is a temporary variant that we hope + /// to clean up later. + Dummy(String), + /// A dummy variant that we hope to clean up later. + Nipata(String), } impl Pada { - /// Creates a new pada from the given text. + /// Creates a dummy pada from the given text. pub fn from_text(text: impl AsRef) -> Self { - let mut t = Term::make_upadesha(text.as_ref()); - t.add_tag(Tag::Pada); - Self { terms: vec![t] } + Self::Dummy(text.as_ref().to_string()) } - /// Creates a new pada from the given text. + /// Creates a dummy pada from the given text. pub fn nipata(text: impl AsRef) -> Self { - let mut t = Term::make_upadesha(text.as_ref()); + Self::Nipata(text.as_ref().to_string()) + } +} - // ad-hoc it-samjna rules. - if t.has_suffix_in(&["Y", "N"]) { - t.set_antya(""); - } +impl From for Pada { + fn from(s: Subanta) -> Self { + Self::Subanta(s) + } +} - t.add_tags(&[Tag::Pada, Tag::Nipata, Tag::Sup]); - Self { terms: vec![t] } +impl From<&Subanta> for Pada { + fn from(s: &Subanta) -> Self { + Self::Subanta(s.clone()) } +} - /// Creates a new pada from a list of terms. - /// - /// Returns `None` if these terms do not describe a valid pada. - pub(crate) fn from_terms(terms: Vec) -> Option { - let last = terms.last()?; - if last.is_pada() { - Some(Self { terms }) - } else { - None - } +impl From for Pada { + fn from(t: Tinanta) -> Self { + Self::Tinanta(t) } +} - /// The terms in this pada. - pub(crate) fn terms(&self) -> &[Term] { - &self.terms +impl From<&Tinanta> for Pada { + fn from(t: &Tinanta) -> Self { + Self::Tinanta(t.clone()) } } diff --git a/vidyut-prakriya/src/args/pratipadika.rs b/vidyut-prakriya/src/args/pratipadika.rs index efe5d6c..ec63d8d 100644 --- a/vidyut-prakriya/src/args/pratipadika.rs +++ b/vidyut-prakriya/src/args/pratipadika.rs @@ -1,7 +1,4 @@ -use crate::core::errors::Error; -use crate::core::Tag; -use crate::core::Term; -use enumset::EnumSet; +use crate::args::{Krdanta, Samasa, Taddhitanta}; /// A nominal stem. /// @@ -12,169 +9,69 @@ use enumset::EnumSet; /// /// A pratipadika is the base to which we add sup-pratyayas. Through this process, we create /// subantas (nominals), which are complete words. -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct Pratipadika { - /// The terms that compose this pratipadika. - terms: Vec, +#[allow(missing_docs)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub enum Pratipadika { + Basic(String, bool), + Krdanta(Box), + Taddhitanta(Box), + Samasa(Box), } +#[allow(missing_docs)] impl Pratipadika { - /// Creates a new pratipadika. - pub fn from(text: impl AsRef) -> Self { - Self { - terms: vec![Term::make_upadesha(text.as_ref())], - } + pub fn basic(text: impl AsRef) -> Self { + Self::Basic(text.as_ref().to_string(), false) } - - /// Creates a pratipadika from a list of terms. - /// - /// Returns `None` if these terms do not describe a valid pratipadika. - pub(crate) fn from_terms(terms: Vec) -> Option { - let last = terms.last()?; - if last.is_pratipadika() - || last.is_krt() - || last.is_taddhita() - || last.is_samasa() - || last.is_nyap_pratyaya() - { - // Also include nyAp-pratyayas. Though these are technically not pratipadikas, their - // association with them is so strong that we should include them here anyway. - Some(Self { terms }) - } else { - None - } - } - - /// The terms in this pratipadika. - pub(crate) fn terms(&self) -> &[Term] { - &self.terms - } - - /// The text of this pratipadika. - pub fn text(&self) -> String { - let mut ret = String::new(); - for t in self.terms() { - ret.push_str(&t.text); - } - ret - } - - /// Returns whether this pratipadika needs a `NI` or `Ap` pratyaya. - pub fn needs_nyap(&self) -> bool { - self.terms - .last() - .map_or(false, |t| t.has_tag(Tag::StriNyap)) - } - - /// Returns whether this pratipadika ends in a dhatu. - pub fn is_dhatu(&self) -> bool { - self.terms.last().map_or(false, |t| t.is_dhatu()) - } - - /// Returns a new builder for this struct. - pub fn builder() -> PratipadikaBuilder { - PratipadikaBuilder::default() + pub fn nyap(text: impl AsRef) -> Self { + Self::Basic(text.as_ref().to_string(), true) } } -/// Convenience struct for building a `Pratipadika` struct. -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct PratipadikaBuilder { - text: Option, - is_nyap: bool, - is_dhatu: bool, - is_udit: bool, - is_pratyaya: bool, -} - -impl PratipadikaBuilder { - /// Sets the text of the pratipadika. - pub fn text(&mut self, value: impl AsRef) -> &mut Self { - self.text = Some(String::from(value.as_ref())); - self - } - - /// Sets whether this pratipadika should be treated as ending in `NI` or `Ap`. - pub fn is_nyap(&mut self, val: bool) -> &mut Self { - self.is_nyap = val; - self +impl From<&str> for Pratipadika { + fn from(s: &str) -> Self { + Self::Basic(s.to_string(), false) } +} - /// Sets whether this pratipadika should be treated as ending in a dhatu. - pub fn is_dhatu(&mut self, val: bool) -> &mut Self { - self.is_dhatu = val; - self +impl From<&Pratipadika> for Pratipadika { + fn from(p: &Pratipadika) -> Self { + p.clone() } +} - /// Sets whether this pratipadika should be treated as ending in a dhatu. - pub fn is_udit(&mut self, val: bool) -> &mut Self { - self.is_udit = val; - self +impl From for Pratipadika { + fn from(k: Krdanta) -> Self { + Self::Krdanta(Box::new(k)) } +} - /// Sets whether this pratipadika should be treated as ending in a dhatu. - pub fn is_pratyaya(&mut self, val: bool) -> &mut Self { - self.is_pratyaya = val; - self +impl From<&Krdanta> for Pratipadika { + fn from(k: &Krdanta) -> Self { + Self::Krdanta(Box::new(k.clone())) } +} - /// Converts the arguments in this builder into a `Pratipadika` struct. - /// - /// `build()` will fail if `text` is missing. - pub fn build(&self) -> Result { - if let Some(text) = &self.text { - let mut term = Term::make_upadesha(&text); - let tags = self.create_tags(); - for tag in tags { - term.add_tag(tag); - } - let terms = vec![term]; - Ok(Pratipadika { terms }) - } else { - Err(Error::MissingRequiredField("text")) - } +impl From for Pratipadika { + fn from(t: Taddhitanta) -> Self { + Self::Taddhitanta(Box::new(t)) } +} - fn create_tags(&self) -> EnumSet { - let mut tags = EnumSet::default(); - if self.is_nyap { - tags.insert(Tag::StriNyap); - tags.insert(Tag::Stri); - } - if self.is_dhatu { - tags.insert(Tag::Dhatu); - } - if self.is_udit { - tags.insert(Tag::udit); - } - if self.is_dhatu { - tags.insert(Tag::Pratyaya); - } - - tags +impl From<&Taddhitanta> for Pratipadika { + fn from(t: &Taddhitanta) -> Self { + Self::Taddhitanta(Box::new(t.clone())) } } -#[cfg(test)] -#[allow(clippy::unwrap_used)] -mod tests { - use super::*; - - #[test] - fn create_pratipadika() { - let deva = Pratipadika::from("deva"); - assert_eq!(deva.text(), "deva"); - assert!(!deva.is_dhatu()); +impl From for Pratipadika { + fn from(s: Samasa) -> Self { + Self::Samasa(Box::new(s)) } +} - #[test] - fn create_pratipadika_with_dhatu() { - let senani = Pratipadika::builder() - .text("senAnI") - .is_dhatu(true) - .build() - .unwrap(); - assert_eq!(senani.text(), "senAnI"); - assert!(senani.is_dhatu()); +impl From<&Samasa> for Pratipadika { + fn from(s: &Samasa) -> Self { + Self::Samasa(Box::new(s.clone())) } } diff --git a/vidyut-prakriya/src/args/samasa.rs b/vidyut-prakriya/src/args/samasa.rs index 7462948..792eac8 100644 --- a/vidyut-prakriya/src/args/samasa.rs +++ b/vidyut-prakriya/src/args/samasa.rs @@ -1,5 +1,4 @@ -use crate::args::sup::Vibhakti; -use crate::args::Pratipadika; +use crate::args::{Linga, Subanta, Vacana, Vibhakti}; use crate::core::errors::Error; /// A samasa type. @@ -23,63 +22,27 @@ pub enum SamasaType { SamaharaDvandva, } -/// Defines a subanta argument for a samasa. -#[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct SamasaPada { - pratipadika: Pratipadika, - vibhakti: Vibhakti, - is_avyaya: bool, -} - -impl SamasaPada { - /// Creates a new pada to use when deriving the samasa. - pub fn new(pratipadika: Pratipadika, vibhakti: Vibhakti) -> Self { - Self { - pratipadika, - vibhakti, - is_avyaya: false, - } - } - - /// Creates a pada that will be bulit as an avyaya. - pub fn avyaya(pratipadika: Pratipadika) -> Self { - Self { - pratipadika, - vibhakti: Vibhakti::Prathama, - is_avyaya: true, - } - } - - /// Returns the pratipadika to use when deriving the samasa. - pub fn pratipadika(&self) -> &Pratipadika { - &self.pratipadika - } - - /// Returns the vibhakti to use when deriving the samasa. - /// - /// If deriving a tatpurusha, the choice of *vibhakti* here affects which tatpurusha rules are - /// available to the derivation. - pub fn vibhakti(&self) -> Vibhakti { - self.vibhakti - } - - pub(crate) fn is_avyaya(&self) -> bool { - self.is_avyaya - } -} - /// The information required to derive a samasa in the grammar. #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct SamasaArgs { +pub struct Samasa { /// The items to combine in the samasa. - padas: Vec, + padas: Vec, + /// The sup-pratyaya to use. + sup: Option<(Linga, Vibhakti, Vacana)>, /// The samasa type to apply. samasa_type: SamasaType, + /// Whether to add a stri-pratyaya. + stri: bool, } -impl SamasaArgs { +impl Samasa { + /// Returns a new builder for this struct. + pub fn builder() -> SamasaBuilder { + SamasaBuilder::default() + } + /// Returns all padas to use in the derivation. - pub fn padas(&self) -> &Vec { + pub fn padas(&self) -> &Vec { &self.padas } @@ -88,22 +51,41 @@ impl SamasaArgs { self.samasa_type } - /// Returns a new builder for this struct. - pub fn builder() -> SamasaArgsBuilder { - SamasaArgsBuilder::default() + /// Returns the arguments for the `sup`-pratyaya that the samasa will take. If none, derive the + /// samasa as a pratipadika. + pub fn sup(&self) -> Option<(Linga, Vibhakti, Vacana)> { + self.sup + } + + /// Whether or not to derive this with a strI-pratyaya. + pub fn stri(&self) -> bool { + self.stri + } + + /// TODO + pub fn with_sup(mut self, linga: Linga, vibhakti: Vibhakti, vacana: Vacana) -> Self { + self.sup = Some((linga, vibhakti, vacana)); + self + } + + /// TODO + pub fn with_stri(mut self, val: bool) -> Self { + self.stri = val; + self } } /// Convenience struct for building a `SamasaARgs` struct. #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct SamasaArgsBuilder { - padas: Vec, +pub struct SamasaBuilder { + padas: Vec, samasa_type: Option, + sup: Option<(Linga, Vibhakti, Vacana)>, } -impl SamasaArgsBuilder { +impl SamasaBuilder { /// Sets the items to use in the derivation. - pub fn padas(&mut self, padas: Vec) -> &mut Self { + pub fn padas(&mut self, padas: Vec) -> &mut Self { self.padas = padas; self } @@ -114,20 +96,28 @@ impl SamasaArgsBuilder { self } + /// Sets the samasa type to use in the derivation. + pub fn sup(&mut self, tuple: (Linga, Vibhakti, Vacana)) -> &mut Self { + self.sup = Some(tuple); + self + } + /// Converts the arguments in this builder into a `SamasaArgs` struct. /// /// `build()` will fail if any args are missing. - pub fn build(&self) -> Result { - Ok(SamasaArgs { + pub fn build(&self) -> Result { + Ok(Samasa { padas: if !self.padas.is_empty() { self.padas.clone() } else { return Err(Error::missing_required_field("items")); }, + sup: self.sup, samasa_type: match self.samasa_type { Some(x) => x, _ => return Err(Error::missing_required_field("samasa_type")), }, + stri: false, }) } } diff --git a/vidyut-prakriya/src/args/sup.rs b/vidyut-prakriya/src/args/sup.rs index 52e72d8..eda876c 100644 --- a/vidyut-prakriya/src/args/sup.rs +++ b/vidyut-prakriya/src/args/sup.rs @@ -1,4 +1,5 @@ use crate::args::tin::Vacana; +use crate::args::Pratipadika; use crate::core::errors::Error; use crate::core::Tag; use crate::enum_boilerplate; @@ -86,13 +87,55 @@ impl Vibhakti { } /// The information required to derive a subanta in the grammar. -pub struct SubantaArgs { +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Subanta { + pratipadika: Pratipadika, linga: Linga, - vacana: Vacana, vibhakti: Vibhakti, + vacana: Vacana, + is_avyaya: bool, } -impl SubantaArgs { +impl Subanta { + /// Creates a subanta. + pub fn new( + pratipadika: impl Into, + linga: Linga, + vibhakti: Vibhakti, + vacana: Vacana, + ) -> Self { + let pratipadika = pratipadika.into(); + Self { + pratipadika, + linga, + vibhakti, + vacana, + is_avyaya: false, + } + } + + /// Creates a subanta. + pub fn avyaya(pratipadika: impl Into) -> Self { + let pratipadika = pratipadika.into(); + Self { + pratipadika, + linga: Linga::Pum, + vibhakti: Vibhakti::Prathama, + vacana: Vacana::Eka, + is_avyaya: true, + } + } + + /// Returns a new builder for this struct. + pub fn builder() -> SubantaBuilder { + SubantaBuilder::default() + } + + /// The pratipadika to use in the derivation. + pub fn pratipadika(&self) -> &Pratipadika { + &self.pratipadika + } + /// The linga to use in the derivation. pub fn linga(&self) -> Linga { self.linga @@ -108,21 +151,28 @@ impl SubantaArgs { self.vibhakti } - /// Returns a new builder for this struct. - pub fn builder() -> SubantaArgsBuilder { - SubantaArgsBuilder::default() + /// Returns whether or not this subanta is an avyaya. + pub fn is_avyaya(&self) -> bool { + self.is_avyaya } } /// Convenience struct for building a `SubantaArgs` struct. #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct SubantaArgsBuilder { +pub struct SubantaBuilder { + pratipadika: Option, linga: Option, vacana: Option, vibhakti: Option, } -impl SubantaArgsBuilder { +impl SubantaBuilder { + /// Sets the pratipadika to use in the derivation. + pub fn pratipadika(&mut self, val: impl Into) -> &mut Self { + self.pratipadika = Some(val.into()); + self + } + /// Sets the linga to use in the derivation. pub fn linga(&mut self, val: Linga) -> &mut Self { self.linga = Some(val); @@ -144,8 +194,12 @@ impl SubantaArgsBuilder { /// Converts the arguments in this builder into a `SubantaArgs` struct. /// /// `build()` will fail if any args are missing. - pub fn build(&self) -> Result { - Ok(SubantaArgs { + pub fn build(&self) -> Result { + Ok(Subanta { + pratipadika: match &self.pratipadika { + Some(x) => x.clone(), + _ => return Err(Error::missing_required_field("pratipadika")), + }, linga: match self.linga { Some(x) => x, _ => return Err(Error::missing_required_field("linga")), @@ -158,6 +212,7 @@ impl SubantaArgsBuilder { Some(x) => x, _ => return Err(Error::missing_required_field("vibhakti")), }, + is_avyaya: false, }) } } diff --git a/vidyut-prakriya/src/args/taddhita.rs b/vidyut-prakriya/src/args/taddhita.rs index 3320450..0c2a973 100644 --- a/vidyut-prakriya/src/args/taddhita.rs +++ b/vidyut-prakriya/src/args/taddhita.rs @@ -1,3 +1,4 @@ +use crate::args::Pratipadika; use crate::core::errors::*; use crate::enum_boilerplate; use wasm_bindgen::prelude::wasm_bindgen; @@ -27,6 +28,12 @@ pub enum Taddhita { at, /// -atas atasuc, + /// -an + anic, + /// -a + ap, + /// -as + asic, /// -astAt astAti, /// -Akin, @@ -111,10 +118,12 @@ pub enum Taddhita { Ya, /// -ika YiW, + /// -ya + Yya, /// -ya, YyaN, /// -ya - Yya, + Yyaw, /// -a wac, /// -a @@ -123,6 +132,8 @@ pub enum Taddhita { wiWan, /// -wIwa wIwac, + /// -eRya + weRyaR, /// -ya wyaR, /// -ana @@ -141,6 +152,14 @@ pub enum Taddhita { Wan, /// -ika Wap, + /// -a + qaw, + /// -ati + qati, + /// -atara + qatarac, + /// -atama + qatamac, /// -pa qupac, /// -mat @@ -171,6 +190,8 @@ pub enum Taddhita { Rya, /// -tama tamap, + /// -taya + tayap, /// -tara tarap, /// -ta (becomes -tA) @@ -183,6 +204,8 @@ pub enum Taddhita { ti, /// -tika tikan, + /// -tIya + tIya, /// -tya tyak, /// -tyaka @@ -281,6 +304,8 @@ pub enum Taddhita { vatup, /// -vaya vaya, + /// -vala + valac, /// -vin vini, /// -viDu @@ -299,10 +324,12 @@ pub enum Taddhita { Sa, /// -SaNkawa SaNkawac, - /// -Sas - Sas, /// -SAla SAlac, + /// -Sas + Sas, + /// -za + za, /// -ka zkan, /// -tra @@ -315,6 +342,10 @@ pub enum Taddhita { zWal, /// Ayana zPak, + /// -sa + sa, + /// -sna + sna, /// -sAt sAti, /// -s @@ -334,6 +365,9 @@ enum_boilerplate!(Taddhita, { aR => "aR", at => "at", atasuc => "atasu~c", + anic => "ani~c", + ap => "ap", + asic => "asi~c", astAti => "astAti~", Akinic => "Akini~c", Arak => "Arak", @@ -377,11 +411,13 @@ enum_boilerplate!(Taddhita, { Ya => "Ya", YiW => "YiW", Yya => "Yya", - YyaN => "Yyan", + YyaN => "YyaN", + Yyaw => "Yyaw", wac => "wac", waq => "waq", wiWan => "wi~Wan", wIwac => "wIwac", + weRyaR => "weRyaR", wyaR => "wyaR", wyu => "wyu~", wyul => "wyu~l", @@ -391,6 +427,10 @@ enum_boilerplate!(Taddhita, { WaY => "WaY", Wan => "Wan", Wap => "Wap", + qaw => "qaw", + qati => "qati", + qatarac => "qatarac", + qatamac => "qatamac", qupac => "qupac", qmatup => "qmatu~p", qyaR => "qyaR", @@ -406,12 +446,14 @@ enum_boilerplate!(Taddhita, { Rini => "Rini~", Rya => "Rya", tamap => "tamap", + tayap => "tayap", tarap => "tarap", tal => "tal", tasi => "tasi~", tasil => "tasi~l", ti => "ti", tikan => "tikan", + tIya => "tIya", tyak => "tyak", tyakan => "tyakan", tyap => "tyap", @@ -461,6 +503,7 @@ enum_boilerplate!(Taddhita, { rUpap => "rUpap", vatup => "vatu~p", vaya => "vaya", + valac => "valac", viDal => "viDal", vini => "vini~", vuk => "vu~k", @@ -472,12 +515,15 @@ enum_boilerplate!(Taddhita, { SaNkawac => "SaNkawac", SAlac => "SAlac", Sas => "Sas", + za => "za", zkan => "zkan", zwarac => "zwarac", zWac => "zWac", zWan => "zWan", zWal => "zWal", zPak => "zPak", + sa => "sa", + sna => "sna", sAti => "sAti~", suc => "su~c", snaY => "snaY", @@ -508,6 +554,8 @@ pub enum TaddhitaArtha { TasyaSamuha, /// A domain of this. (4.2.52) TasyaVishayoDeshe, + /// What one studies or knows. (4.2.59) + TadAdhiteTadVeda, /// Country, by entities present (4.2.67), creator (4.2.68), dwelling place (4.2.69), or nearby /// features (4.2.70). Caturarthika, @@ -643,6 +691,8 @@ pub enum TaddhitaArtha { Apanna, /// Who goes. (5.1.75) Gacchati, + /// Who deserves approach (5.1.74 vArttika) + AbhigamanamArhati, /// The existence of which. (5.1.119) TasyaBhava, /// A place of growing, when that place is a field. (5.2.1) @@ -671,10 +721,34 @@ pub enum TaddhitaArtha { TasyaMula, /// Celebrated through this. (5.2.26) TenaVitta, + /// Of which this is observed. (5.2.36) + TadAsyaSamjatam, /// Measure. (5.2.37) - Pramana, + TadAsyaPramanam, /// Volume. (5.2.39) Parimana, + /// Parts of which. (5.2.42) + Avasana, + /// Given in exchange. (5.2.47) + Nimana, + /// Making full. (5.2.48) + Purana, + /// Skilled in this. (5.2.63) + TatraKushala, + /// A desire for which. (5.2.65) + TatraKama, + /// Voracious. (5.2.67) + TatraAdyuna, + /// Supplied richly with. (5.2.68) + TatraParijata, + /// Who must take this.. (5.2.69) + Hari, + /// Taken recently. (5.2.70) + AciraApahrta, + /// Going to work in this manner. (5.2.72) + Karin, + /// Who strives to gain by this. (5.2.75) + Anvicchati, /// What one has or is in. (5.2.94) TadAsyaAstiAsmin, /// Words meaning direction, location, or time. (5.3.27) @@ -687,6 +761,10 @@ pub enum TaddhitaArtha { Anukampayam, /// Slenderness. (5.3.91) Tanutve, + /// One of two. (5.3.92) + DvayorEka, + /// One of many. (5.3.93) + BahunamEka, /// Derision. (5.3.95) Avakshepane, /// TODO @@ -695,6 +773,12 @@ pub enum TaddhitaArtha { Hrasve, /// TODO IvePratikrtau, + /// Those who make a living by arms. (5.3.114) + AyudhaJiviSangha, + /// TODO + AnatyantaGati, + /// TODO + Acchadana, /// TODO Svarthe, /// TODO @@ -707,6 +791,8 @@ pub enum TaddhitaArtha { TatPrakrtaVacane, /// For the sake of which. (5.4.24) Tadarthye, + /// Praise of this. (5.3.66, 5.4.41) + Prashamsa, /// Becoming what one was not. (5.4.50) AbhutaTadbhava, } @@ -722,12 +808,25 @@ impl TaddhitaArtha { } /// The information required to derive a taddhitanta in the grammar. -pub struct TaddhitantaArgs { +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Taddhitanta { + pratipadika: Pratipadika, taddhita: Taddhita, artha: Option, + require: Option, } -impl TaddhitantaArgs { +impl Taddhitanta { + /// Returns a new builder for this struct. + pub fn builder() -> TaddhitantaBuilder { + TaddhitantaBuilder::default() + } + + /// The pratipadika to use in the derivation. + pub fn pratipadika(&self) -> &Pratipadika { + &self.pratipadika + } + /// The taddhita-pratyaya to use in the derivation. pub fn taddhita(&self) -> Taddhita { self.taddhita @@ -738,20 +837,34 @@ impl TaddhitantaArgs { self.artha } - /// Returns a new builder for this struct. - pub fn builder() -> TaddhitantaArgsBuilder { - TaddhitantaArgsBuilder::default() + /// The value that the krdanta must match, if defined. + pub fn require(&self) -> &Option { + &self.require + } + + /// Sets the required value for this taddhitanta. + pub fn with_require(mut self, s: impl AsRef) -> Self { + self.require = Some(s.as_ref().to_string()); + self } } /// Convenience struct for building a `TaddhitantaArgs` object. -#[derive(Clone, Default, Hash, Eq, PartialEq)] -pub struct TaddhitantaArgsBuilder { +#[derive(Clone, Default, Eq, Hash, PartialEq)] +pub struct TaddhitantaBuilder { + pratipadika: Option, taddhita: Option, artha: Option, + require: Option, } -impl TaddhitantaArgsBuilder { +impl TaddhitantaBuilder { + /// Sets the pratipadika to use in the derivation. + pub fn pratipadika(&mut self, val: Pratipadika) -> &mut Self { + self.pratipadika = Some(val); + self + } + /// Sets the taddhita-pratyaya to use in the derivation. pub fn taddhita(&mut self, val: Taddhita) -> &mut Self { self.taddhita = Some(val); @@ -764,16 +877,27 @@ impl TaddhitantaArgsBuilder { self } + /// Sets the value that the krdanta must have. + pub fn require(&mut self, text: impl AsRef) -> &mut Self { + self.require = Some(text.as_ref().to_string()); + self + } + /// Converts the arguments in this builder into a `TaddhitantaArgs` struct. /// /// `build()` will fail if any args are missing. - pub fn build(&self) -> Result { - Ok(TaddhitantaArgs { + pub fn build(&self) -> Result { + Ok(Taddhitanta { + pratipadika: match &self.pratipadika { + Some(x) => x.clone(), + _ => return Err(Error::missing_required_field("pratipadika")), + }, taddhita: match self.taddhita { Some(x) => x, _ => return Err(Error::missing_required_field("taddhita")), }, artha: self.artha, + require: self.require.clone(), }) } } diff --git a/vidyut-prakriya/src/args/temp.rs b/vidyut-prakriya/src/args/temp.rs new file mode 100644 index 0000000..139597f --- /dev/null +++ b/vidyut-prakriya/src/args/temp.rs @@ -0,0 +1,2 @@ + + diff --git a/vidyut-prakriya/src/args/tin.rs b/vidyut-prakriya/src/args/tin.rs index d35839d..fc30ce6 100644 --- a/vidyut-prakriya/src/args/tin.rs +++ b/vidyut-prakriya/src/args/tin.rs @@ -1,3 +1,4 @@ +use crate::args::dhatu::Dhatu; use crate::core::errors::Error; use crate::core::Tag; use crate::enum_boilerplate; @@ -188,15 +189,42 @@ impl DhatuPada { /// /// Since we want to keep these args manageable and don't want to repeatedly break our main API, we /// decided to wrap args in this struct and expose its values through accessors. -pub struct TinantaArgs { +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Tinanta { + dhatu: Dhatu, prayoga: Prayoga, - purusha: Purusha, lakara: Lakara, + purusha: Purusha, vacana: Vacana, pada: Option, } -impl TinantaArgs { +impl Tinanta { + /// Creates a new `Tinanta`. + /// + /// For more options, see `Tinanta::build()`. + pub fn new( + dhatu: Dhatu, + prayoga: Prayoga, + lakara: Lakara, + purusha: Purusha, + vacana: Vacana, + ) -> Self { + Self { + dhatu, + prayoga, + lakara, + purusha, + vacana, + pada: None, + } + } + + /// The dhatu to use in the derivation. + pub fn dhatu(&self) -> &Dhatu { + &self.dhatu + } + /// The linga to use in the derivation. pub fn prayoga(&self) -> Prayoga { self.prayoga @@ -225,15 +253,39 @@ impl TinantaArgs { self.pada } + /// Returns an updated version of `self` with the given `dhatu`. + pub fn with_dhatu(mut self, dhatu: Dhatu) -> Self { + self.dhatu = dhatu; + self + } + /// Returns a new builder for this struct. + /// + /// For details, see `TinantaArgsBuilder`. pub fn builder() -> TinantaArgsBuilder { TinantaArgsBuilder::default() } } /// Convenience struct for building a `TinantaArgs` object. +/// +/// +/// ### Example +/// +/// ```` +/// # use vidyut_prakriya::args::*; +/// let args = Tinanta::builder() +/// .dhatu(dhatu) +/// .lakara(Lakara::Lat) +/// .prayoga(Prayoga::Kartari) +/// .purusha(Purusha::Prathama) +/// .vacana(Vacana::Eka) +/// .build()?; +/// # Ok::<(), Error>(()) +/// ```` #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] pub struct TinantaArgsBuilder { + dhatu: Option, prayoga: Option, purusha: Option, lakara: Option, @@ -242,6 +294,12 @@ pub struct TinantaArgsBuilder { } impl TinantaArgsBuilder { + /// Sets the dhatu to use in the derivation. + pub fn dhatu(mut self, val: Dhatu) -> Self { + self.dhatu = Some(val); + self + } + /// Sets the prayoga to use in the derivation. pub fn prayoga(mut self, val: Prayoga) -> Self { self.prayoga = Some(val); @@ -278,8 +336,12 @@ impl TinantaArgsBuilder { /// Converts the arguments in this builder into a `TinantaArgs` struct. /// /// `build()` will fail if any args are missing. - pub fn build(self) -> Result { - Ok(TinantaArgs { + pub fn build(self) -> Result { + Ok(Tinanta { + dhatu: match self.dhatu { + Some(x) => x, + _ => return Err(Error::missing_required_field("dhatu")), + }, prayoga: match self.prayoga { Some(x) => x, _ => return Err(Error::missing_required_field("prayoga")), diff --git a/vidyut-prakriya/src/args/unadi.rs b/vidyut-prakriya/src/args/unadi.rs index 0c600d1..85e53e0 100644 --- a/vidyut-prakriya/src/args/unadi.rs +++ b/vidyut-prakriya/src/args/unadi.rs @@ -644,7 +644,7 @@ enum_boilerplate!(Unadi, { aWa => "aWa", aRqan => "aRqan", atac => "atac", - ati => "ati", + ati => "ati~", atran => "atran", atrin => "atrin", aTa => "aTa", diff --git a/vidyut-prakriya/src/args2.rs b/vidyut-prakriya/src/args2.rs new file mode 100644 index 0000000..6d2ca61 --- /dev/null +++ b/vidyut-prakriya/src/args2.rs @@ -0,0 +1,142 @@ +#![allow(unused)] + +use crate::args::{ + Antargana, DhatuPada, Gana, Krt, Lakara, Linga, Purusha, Sanadi, Taddhita, Vacana, Vibhakti, +}; + +/// Pratyayas +#[derive(Clone)] +pub enum Stri {} + +#[derive(Clone)] +pub struct Muladhatu { + aupadeshika: String, + gana: Gana, + antargana: Option, + sanadi: Vec, +} + +#[derive(Clone)] +pub struct Namadhatu { + pratipadika: Box, + sanadi: Vec, +} + +#[derive(Clone)] +pub enum Dhatu { + Mula(Muladhatu), + Nama(Namadhatu), +} + +#[derive(Clone)] +pub enum Pratipadika { + Basic(String), + Krt(Vec, Dhatu, Krt), + Taddhita(Box, Vec), + Samasa(Samasa), + Stri(Box, Option), +} + +impl Pratipadika { + fn basic(text: impl AsRef) -> Self { + Self::Basic(text.as_ref().to_string()) + } + + fn krt(dhatu: Dhatu, krt: Krt) -> Self { + Self::Krt(vec![], dhatu, krt) + } + + fn taddhita(prati: Pratipadika, taddhita: Taddhita) -> Self { + Self::Taddhita(Box::new(prati), vec![taddhita]) + } +} + +#[derive(Clone)] +pub enum Samasa { + Bahuvrihi(Pada, Pada), + Tatpurusha(Pada, Pada), + Avyayibhava(Pada, Pada), + Dvandva(Vec), +} + +impl Samasa { + pub fn tatpurusha(purva: Pada, uttara: Pada) -> Self { + Self::Tatpurusha(purva, uttara) + } + + pub fn bahuvrihi(purva: Pada, uttara: Pada) -> Self { + Self::Bahuvrihi(purva, uttara) + } + + pub fn avyayibhava(padas: &[Pada]) -> Self { + Self::Dvandva(padas.to_vec()) + } + + pub fn dvandva(padas: &[Pada]) -> Self { + Self::Dvandva(padas.to_vec()) + } +} + +#[derive(Clone)] +pub struct Subanta { + pratipadika: Box, + linga: Linga, + vacana: Vacana, + vibhakti: Vibhakti, +} + +#[derive(Clone)] +pub struct Tinanta { + dhatu: Box, + purusha: Purusha, + vacana: Vacana, + lakara: Lakara, + pada: Option, +} + +#[derive(Clone)] +pub enum Pada { + Subanta(Subanta), + Tinanta(Tinanta), +} + +impl Pada {} + +/* +impl Dhatu { + fn mula(aupadeshika: impl AsRef, gana: Gana) -> Self { + Self { + kind: DhatuKind::Mula(Muladhatu { + aupadeshika: aupadeshika.as_ref().to_string(), + gana, + antargana: None, + }), + sanadi: vec![], + } + } + + fn nama(pratipadika: Pratipadika) -> Self { + Self { + kind: DhatuKind::Nama(pratipadika), + sanadi: vec![], + } + } +} + +fn foo() { + use Gana::*; + + let bhu = Dhatu::mula("BU", Bhvadi); + + let putra = Pratipadika::from("putra"); + let putriya = Dhatu::nama(putra); + + let bubhush = Dhatu::builder() + .aupadeshika("BU") + .gana(Gana::Bhvadi) + .antargana(Antargana::Akusmiya) + .sanadi(&[Sanadi::san]) + .build(); +} +*/ + diff --git a/vidyut-prakriya/src/ashtadhyayi.rs b/vidyut-prakriya/src/ashtadhyayi.rs index 669fb2f..85b2c22 100644 --- a/vidyut-prakriya/src/ashtadhyayi.rs +++ b/vidyut-prakriya/src/ashtadhyayi.rs @@ -4,9 +4,7 @@ A high-level interface to `vidyut-prakriya`. The main struct here is `Ashtadhyayi`. This struct accepts various config options that control how words are derived in the system. For details, see `AshtadhyayiBuilder`. */ -use crate::args::{ - Dhatu, KrdantaArgs, Pada, Pratipadika, SamasaArgs, SubantaArgs, TaddhitantaArgs, TinantaArgs, -}; +use crate::args::{Krdanta, Pada, Pratipadika, Samasa, Subanta, Taddhitanta, Tinanta}; use crate::core::prakriya_stack::PrakriyaStack; use crate::core::Prakriya; use crate::core::Tag; @@ -33,7 +31,7 @@ use crate::sutrapatha; /// ```no_run /// use vidyut_prakriya::Ashtadhyayi; /// -/// let a = Ashtadhyayi::builder().log_steps(false).build(); +/// let a = Ashtadhyayi::builder().log_steps(false).is_chandasi(true).use_svaras(true).build(); /// ``` #[derive(Debug, Default)] pub struct Ashtadhyayi { @@ -48,6 +46,8 @@ pub struct Ashtadhyayi { log_steps: bool, // If set, also generate chaandasa forms. is_chandasi: bool, + // If set, use svara rules. If unset, output will have no svaras. + use_svaras: bool, } // TODO: better error handling. @@ -57,6 +57,7 @@ impl Ashtadhyayi { Ashtadhyayi { log_steps: true, is_chandasi: false, + use_svaras: false, } } @@ -77,20 +78,21 @@ impl Ashtadhyayi { /// # use vidyut_prakriya::Error; /// # use vidyut_prakriya::args::*; /// let a = Ashtadhyayi::new(); - /// let dhatu = Dhatu::new("BU", Gana::Bhvadi); - /// let args = TinantaArgs::builder() + /// let dhatu = Dhatu::mula("BU", Gana::Bhvadi); + /// let args = Tinanta::builder() + /// .dhatu(dhatu) /// .lakara(Lakara::Lat) /// .prayoga(Prayoga::Kartari) /// .purusha(Purusha::Prathama) /// .vacana(Vacana::Eka) /// .build()?; - /// let prakriyas = a.derive_tinantas(&dhatu, &args); + /// let prakriyas = a.derive_tinantas(&args); /// # Ok::<(), Error>(()) /// ``` - pub fn derive_tinantas(&self, dhatu: &Dhatu, args: &TinantaArgs) -> Vec { + pub fn derive_tinantas(&self, args: &Tinanta) -> Vec { let mut stack = self.create_prakriya_stack(); // TODO: handle error properly. - stack.find_all(|p| sutrapatha::derive_tinanta(p, dhatu, args)); + stack.find_all(|p| sutrapatha::derive_tinanta(p, args)); let mut prakriyas = stack.prakriyas(); // If the caller specified an explicit pada, keep only the results that match that pada. @@ -119,18 +121,18 @@ impl Ashtadhyayi { /// # use vidyut_prakriya::Error; /// # use vidyut_prakriya::args::*; /// let a = Ashtadhyayi::new(); - /// let pratipadika = Pratipadika::new("nara"); - /// let args = SubantaArgs::builder() + /// let args = Subanta::builder() + /// .pratipadika(Pratipadika::basic("nara")) /// .linga(Linga::Pum) /// .vibhakti(Vibhakti::Trtiya) /// .vacana(Vacana::Eka) /// .build()?; - /// let prakriyas = a.derive_subantas(&pratipadika, &args); + /// let prakriyas = a.derive_subantas(&args); /// # Ok::<(), Error>(()) /// ``` - pub fn derive_subantas(&self, pratipadika: &Pratipadika, args: &SubantaArgs) -> Vec { + pub fn derive_subantas(&self, subanta: &Subanta) -> Vec { let mut stack = self.create_prakriya_stack(); - stack.find_all(|p| sutrapatha::derive_subanta(p, pratipadika, args)); + stack.find_all(|p| sutrapatha::derive_subanta(p, subanta)); stack.prakriyas() } @@ -140,21 +142,34 @@ impl Ashtadhyayi { /// /// ### Example /// + /// Using a basic krt-pratyaya. + /// /// ``` /// # use vidyut_prakriya::Ashtadhyayi; /// # use vidyut_prakriya::Error; /// # use vidyut_prakriya::args::*; /// let a = Ashtadhyayi::new(); - /// let dhatu = Dhatu::new("BU", Gana::Bhvadi); - /// let args = KrdantaArgs::builder() - /// .krt(BaseKrt::ktvA) - /// .build()?; - /// let prakriyas = a.derive_krdantas(&dhatu, &args); + /// let dhatu = Dhatu::mula("BU", Gana::Bhvadi); + /// let args = Krdanta::new(dhatu, BaseKrt::ktvA); + /// let prakriyas = a.derive_krdantas(&args); /// # Ok::<(), Error>(()) /// ``` - pub fn derive_krdantas(&self, dhatu: &Dhatu, args: &KrdantaArgs) -> Vec { + /// + /// Using an unadi-pratyaya: + /// + /// ``` + /// # use vidyut_prakriya::Ashtadhyayi; + /// # use vidyut_prakriya::Error; + /// # use vidyut_prakriya::args::*; + /// let a = Ashtadhyayi::new(); + /// let dhatu = Dhatu::mula("dF", Gana::Kryadi); + /// let args = Krdanta::new(dhatu, Unadi::YuR); + /// let prakriyas = a.derive_krdantas(&args); + /// # Ok::<(), Error>(()) + /// ``` + pub fn derive_krdantas(&self, krdanta: &Krdanta) -> Vec { let mut stack = self.create_prakriya_stack(); - stack.find_all(|p| sutrapatha::derive_krdanta(p, dhatu, args)); + stack.find_all(|p| sutrapatha::derive_krdanta(p, krdanta)); stack.prakriyas() } @@ -169,20 +184,16 @@ impl Ashtadhyayi { /// # use vidyut_prakriya::Error; /// # use vidyut_prakriya::args::*; /// let a = Ashtadhyayi::new(); - /// let pratipadika = Pratipadika::new("nara"); - /// let args = TaddhitantaArgs::builder() + /// let args = Taddhitanta::builder() + /// .pratipadika(Pratipadika::basic("nara")) /// .taddhita(Taddhita::matup) /// .build()?; - /// let prakriyas = a.derive_taddhitantas(&pratipadika, &args); + /// let prakriyas = a.derive_taddhitantas(&args); /// # Ok::<(), Error>(()) /// ``` - pub fn derive_taddhitantas( - &self, - pratipadika: &Pratipadika, - args: &TaddhitantaArgs, - ) -> Vec { + pub fn derive_taddhitantas(&self, spec: &Taddhitanta) -> Vec { let mut stack = self.create_prakriya_stack(); - stack.find_all(|p| sutrapatha::derive_taddhitanta(p, pratipadika, args)); + stack.find_all(|p| sutrapatha::derive_taddhitanta(p, spec)); stack.prakriyas() } @@ -197,7 +208,7 @@ impl Ashtadhyayi { /// # use vidyut_prakriya::Error; /// # use vidyut_prakriya::args::*; /// let a = Ashtadhyayi::new(); - /// let pratipadika = Pratipadika::new("nara"); + /// let pratipadika = Pratipadika::basic("nara"); /// let prakriyas = a.derive_stryantas(&pratipadika); /// # Ok::<(), Error>(()) /// ``` @@ -218,7 +229,7 @@ impl Ashtadhyayi { /// # use vidyut_prakriya::args::*; /// let a = Ashtadhyayi::new(); /// # Ok::<(), Error>(()) - pub fn derive_samasas(&self, args: &SamasaArgs) -> Vec { + pub fn derive_samasas(&self, args: &Samasa) -> Vec { let mut stack = self.create_prakriya_stack(); stack.find_all(|p| sutrapatha::derive_samasa(p, &args)); stack.prakriyas() @@ -233,17 +244,18 @@ impl Ashtadhyayi { /// # use vidyut_prakriya::Ashtadhyayi; /// # use vidyut_prakriya::Error; /// # use vidyut_prakriya::args::*; + /// /// let a = Ashtadhyayi::new(); /// # Ok::<(), Error>(()) pub fn derive_vakyas(&self, padas: &[Pada]) -> Vec { let mut stack = self.create_prakriya_stack(); - stack.find_all(|p| sutrapatha::derive_vakya(p, &padas)); + stack.find_all(|p| sutrapatha::derive_vakya(p, padas)); stack.prakriyas() } /// Creates a prakriya stack that generates prakriyas according to our derivation options. fn create_prakriya_stack(&self) -> PrakriyaStack { - PrakriyaStack::new(self.log_steps, self.is_chandasi) + PrakriyaStack::new(self.log_steps, self.is_chandasi, self.use_svaras) } } @@ -278,11 +290,21 @@ impl AshtadhyayiBuilder { /// - If `true`, each `Prakriya` will have access to chAndasa rules. /// /// - If `false`, each `Prakriya` will use a standard ruleset. - pub fn is_chandasa(mut self, value: bool) -> Self { + pub fn is_chandasi(mut self, value: bool) -> Self { self.ashtadhyayi.is_chandasi = value; self } + /// *(default: folse)* Controls whether or not to run svara rules. + /// + /// - If `true`, each `Prakriya` will have its svaras marked. + /// + /// - If `false`, each `Prakriya` will leave svaras unset. + pub fn use_svaras(mut self, value: bool) -> Self { + self.ashtadhyayi.use_svaras = value; + self + } + /// Creates an `Ashtadhyayi` struct. pub fn build(self) -> Ashtadhyayi { self.ashtadhyayi diff --git a/vidyut-prakriya/src/atmanepada.rs b/vidyut-prakriya/src/atmanepada.rs index 57a5561..afa32c5 100644 --- a/vidyut-prakriya/src/atmanepada.rs +++ b/vidyut-prakriya/src/atmanepada.rs @@ -283,6 +283,9 @@ pub fn run(p: &mut Prakriya) -> Option<()> { } else if pp.is(&["upa"], &["ra\\ma~\\"]) { // 1.3.84 sets anuvrtti for 1.3.85 pp.optional_para("1.3.85"); + } else if dhatu.has_u("kyaz") { + // lohitAyati, lohitAyate, ... + pp.optional_atma("1.3.90"); } else if dhatu.has_u_in(DYUT_ADI) && dhatu.has_gana(Gana::Bhvadi) && la.has_u("lu~N") { pp.optional_para("1.3.91"); } else if dhatu.has_u_in(VRT_ADI) && dhatu.has_gana(Gana::Bhvadi) && sya_san() { diff --git a/vidyut-prakriya/src/bin/create_krdantas.rs b/vidyut-prakriya/src/bin/create_krdantas.rs index d694f43..0c910cf 100644 --- a/vidyut-prakriya/src/bin/create_krdantas.rs +++ b/vidyut-prakriya/src/bin/create_krdantas.rs @@ -6,7 +6,7 @@ use clap::Parser; use serde::Serialize; use std::error::Error; use std::io; -use vidyut_prakriya::args::{BaseKrt, KrdantaArgs}; +use vidyut_prakriya::args::{BaseKrt, Krdanta}; use vidyut_prakriya::{Ashtadhyayi, Dhatupatha}; #[derive(Parser)] @@ -32,11 +32,11 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { for entry in d { let dhatu = entry.dhatu(); let krt = args.krt; - let krdanta_args = KrdantaArgs::builder().krt(krt).build()?; + let krdanta = Krdanta::builder().dhatu(dhatu.clone()).krt(krt).build()?; - let prakriyas = a.derive_krdantas(dhatu, &krdanta_args); + let prakriyas = a.derive_krdantas(&krdanta); - let dhatu_text = &dhatu.upadesha(); + let dhatu_text = &dhatu.upadesha().expect("ok"); let mut pratipadikas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); pratipadikas.sort(); pratipadikas.dedup(); @@ -45,7 +45,7 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { let row = Row { pratipadikas, dhatu: dhatu_text, - gana: dhatu.gana().as_str(), + gana: dhatu.gana().expect("ok").as_str(), number: entry.number(), krt: krt.as_str(), }; diff --git a/vidyut-prakriya/src/bin/create_subantas.rs b/vidyut-prakriya/src/bin/create_subantas.rs deleted file mode 100644 index 495b0a3..0000000 --- a/vidyut-prakriya/src/bin/create_subantas.rs +++ /dev/null @@ -1,292 +0,0 @@ -/*! -Creates a test file containing the inputs to `Ashtadhyayi`'s derivation functions and all of the -padas produced by those inputs. -*/ -use serde::Serialize; -use std::error::Error; -use std::io; -use vidyut_prakriya::args::{Linga, Pratipadika, SubantaArgs, Vacana, Vibhakti}; -use vidyut_prakriya::Ashtadhyayi; - -struct TestCase { - pratipadika: Pratipadika, - linga: Linga, -} - -fn dhatu_pratipadika(s: &str) -> Pratipadika { - Pratipadika::builder() - .text(s) - .is_dhatu(true) - .build() - .unwrap() -} - -fn pum(s: &str) -> TestCase { - TestCase { - pratipadika: Pratipadika::from(s), - linga: Linga::Pum, - } -} - -fn pum_dhatu(s: &str) -> TestCase { - TestCase { - pratipadika: dhatu_pratipadika(s), - linga: Linga::Pum, - } -} - -fn stri(s: &str) -> TestCase { - TestCase { - pratipadika: Pratipadika::builder() - .text(s) - .is_nyap(s.ends_with('A') || s.ends_with('I')) - .build() - .unwrap(), - linga: Linga::Stri, - } -} - -#[allow(unused)] -fn stri_dhatu(s: &str) -> TestCase { - TestCase { - pratipadika: Pratipadika::builder() - .text(s) - .is_dhatu(true) - .build() - .unwrap(), - linga: Linga::Stri, - } -} - -fn stri_no_nyap(s: &str) -> TestCase { - TestCase { - pratipadika: Pratipadika::from(s), - linga: Linga::Stri, - } -} - -fn na(s: &str) -> TestCase { - TestCase { - pratipadika: Pratipadika::from(s), - linga: Linga::Napumsaka, - } -} - -/// Sourced from . -fn create_test_cases() -> Vec { - vec![ - // ------------------------------ - // Ajantas (pum, stri, napumsaka) - // ------------------------------ - pum("a"), - pum("deva"), - pum("rAma"), - pum("sarva"), - pum("viSva"), - // TODO: viSva when not a sarvanama - pum("katara"), - pum("yatara"), - pum("tatara"), - pum("ekatara"), - pum("katama"), - pum("yatama"), - pum("tatama"), - pum("ekatama"), - pum("anya"), - pum("anyatara"), - pum("anyatama"), - pum("itara"), - pum("sima"), - pum("eka"), - pum("pUrva"), - pum("para"), - pum("avara"), - pum("dakziRa"), - pum("uttara"), - pum("apara"), - pum("aDara"), - pum("praTama"), - pum("carama"), - pum("alpa"), - pum("arDa"), - pum("katipaya"), - pum_dhatu("viSvapA"), - pum("hAhA"), - pum("i"), - pum("kavi"), - pum("hari"), - pum("BUpati"), - pum_dhatu("nI"), - pum_dhatu("SuzkI"), - pum_dhatu("pakvI"), - pum("u"), - pum("SamBu"), - pum("guru"), - pum_dhatu("KalapU"), - pum("hUhU"), - pum("pitf"), - pum("jAmAtf"), - pum("BrAtf"), - pum("nf"), - pum("se"), - pum("smfte"), - pum("go"), - pum("sudyo"), - pum("smfto"), - pum("rE"), - pum("glO"), - pum("janO"), - stri("mAlA"), - stri("ramA"), - stri("ambA"), - stri("mati"), - stri("rAtri"), - stri("nadI"), - stri("gOrI"), - stri_no_nyap("avI"), - stri_no_nyap("tantrI"), - stri_no_nyap("tarI"), - stri_no_nyap("starI"), - stri_no_nyap("lakzmI"), - stri("Denu"), - stri("Karu"), - stri("vaDU"), - stri("SvaSrU"), - stri("svasf"), - stri("mAtf"), - stri("nAnAndf"), - stri("duhitf"), - stri("duhitf"), - stri("yAtf"), - stri("go"), - stri("dyo"), - stri("rE"), - stri("nO"), - na("Pala"), - na("puzpa"), - na("sarva"), - na("pUrva"), - na("para"), - na("avara"), - na("dakziRa"), - na("uttara"), - na("apara"), - na("aDara"), - na("praTama"), - na("carama"), - na("vAri"), - na("Suci"), - na("maDu"), - na("vasu"), - na("ambu"), - na("aSru"), - na("vastu"), - na("pIlu"), - na("susmfte"), - na("prarE"), - na("pradyo"), - na("sunO"), - // ------------------------------- - // Halantas (pum, stri, napumsaka) - // ------------------------------- - // Ordered alphabetically by last consonant (in shiva sutra order) - pum("lih"), - pum("kamal"), - pum("rAjan"), - pum("yajvan"), - pum("aryaman"), - pum("brahman"), - pum("SArNgin"), - pum("Atman"), - pum("guRin"), - pum("Svan"), - pum("yaSasvin"), - pum("pUzan"), - pum("yuvan"), - pum("gup"), - pum("veDas"), - pum("uSanas"), - pum("anehas"), - pum_dhatu("suvas"), - pum("adas"), - stri("vAc"), - stri("yozit"), - stri("Apad"), - stri("kzuD"), - stri("sIman"), - stri("kakuB"), - na("brahman"), - na("nAman"), - na("daRqin"), - na("sragvin"), - na("manohArin"), - na("varman"), - na("jagat"), - na("payas"), - ] -} - -#[derive(Debug, Serialize)] -struct Row<'a> { - padas: String, - linga: &'static str, - vibhakti: &'static str, - vacana: &'static str, - pratipadika: &'a str, - is_nyap: bool, - is_dhatu: bool, -} - -fn run() -> Result<(), Box> { - let mut wtr = csv::Writer::from_writer(io::stdout()); - let a = Ashtadhyayi::builder().log_steps(false).build(); - - for test_case in create_test_cases() { - let pratipadika = test_case.pratipadika; - let linga = test_case.linga; - - for vibhakti in Vibhakti::iter() { - for vacana in Vacana::iter() { - let subanta_args = SubantaArgs::builder() - .linga(linga) - .vibhakti(*vibhakti) - .vacana(*vacana) - .build()?; - - let prakriyas = a.derive_subantas(&pratipadika, &subanta_args); - let mut padas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - padas.sort(); - padas.dedup(); - let padas = padas.join("|"); - if padas.is_empty() { - continue; - } - - let row = Row { - padas, - linga: linga.as_str(), - vibhakti: vibhakti.as_str(), - vacana: vacana.as_str(), - pratipadika: &pratipadika.text(), - is_nyap: pratipadika.needs_nyap(), - is_dhatu: pratipadika.is_dhatu(), - }; - - wtr.serialize(row)?; - } - } - } - - wtr.flush()?; - Ok(()) -} - -fn main() { - match run() { - Ok(()) => (), - Err(err) => { - eprintln!("{}", err); - std::process::exit(1); - } - } -} diff --git a/vidyut-prakriya/src/bin/create_test_file.rs b/vidyut-prakriya/src/bin/create_test_file.rs index 06d268c..ae83994 100644 --- a/vidyut-prakriya/src/bin/create_test_file.rs +++ b/vidyut-prakriya/src/bin/create_test_file.rs @@ -5,7 +5,7 @@ padas produced by those inputs. use serde::Serialize; use std::error::Error; use std::io; -use vidyut_prakriya::args::{Lakara, Prayoga, Purusha, TinantaArgs, Vacana}; +use vidyut_prakriya::args::{Lakara, Prayoga, Purusha, Tinanta, Vacana}; use vidyut_prakriya::{Ashtadhyayi, Dhatupatha}; const TIN_SEMANTICS: &[(Purusha, Vacana)] = &[ @@ -41,16 +41,17 @@ fn run(d: Dhatupatha) -> Result<(), Box> { for lakara in Lakara::iter() { for (purusha, vacana) in TIN_SEMANTICS { let prayoga = Prayoga::Kartari; - let tinanta_args = TinantaArgs::builder() + let tinanta = Tinanta::builder() + .dhatu(dhatu.clone()) .prayoga(prayoga) .purusha(*purusha) .vacana(*vacana) .lakara(*lakara) .build()?; - let prakriyas = a.derive_tinantas(dhatu, &tinanta_args); + let prakriyas = a.derive_tinantas(&tinanta); - let dhatu_text = &dhatu.upadesha(); + let dhatu_text = &dhatu.upadesha().expect("ok"); let mut padas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); padas.sort(); let padas = padas.join("|"); @@ -58,7 +59,7 @@ fn run(d: Dhatupatha) -> Result<(), Box> { let row = Row { padas, dhatu: dhatu_text, - gana: dhatu.gana().as_str(), + gana: dhatu.gana().expect("ok").as_str(), number: entry.number(), lakara: lakara.as_str(), purusha: purusha.as_str(), diff --git a/vidyut-prakriya/src/bin/create_tinantas.rs b/vidyut-prakriya/src/bin/create_tinantas.rs index 4f22d5e..88417cf 100644 --- a/vidyut-prakriya/src/bin/create_tinantas.rs +++ b/vidyut-prakriya/src/bin/create_tinantas.rs @@ -6,7 +6,7 @@ use clap::Parser; use serde::Serialize; use std::error::Error; use std::io; -use vidyut_prakriya::args::{Dhatu, Lakara, Prayoga, Purusha, Sanadi, TinantaArgs, Vacana}; +use vidyut_prakriya::args::{Dhatu, Lakara, Muladhatu, Prayoga, Purusha, Sanadi, Tinanta, Vacana}; use vidyut_prakriya::{Ashtadhyayi, Dhatupatha}; #[derive(Parser)] @@ -59,6 +59,13 @@ struct Row<'a> { vacana: &'static str, } +fn to_mula(dhatu: &Dhatu) -> &Muladhatu { + match dhatu { + Dhatu::Mula(m) => m, + _ => panic!("unknown dhatu"), + } +} + fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { let mut wtr = csv::Writer::from_writer(io::stdout()); let a = Ashtadhyayi::builder().log_steps(false).build(); @@ -69,7 +76,7 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { }; for entry in d { - let dhatu = entry.dhatu(); + let dhatu = to_mula(entry.dhatu()); // Add sanadi to the dhatu. let mut builder = Dhatu::builder() @@ -81,6 +88,7 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { builder = builder.antargana(x); } let dhatu = builder.build()?; + let mula = to_mula(&dhatu); for prayoga in PRAYOGAS { // Filter prayoga based on args @@ -92,14 +100,15 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { for lakara in LAKARA { for (purusha, vacana) in TIN_SEMANTICS { - let tinanta_args = TinantaArgs::builder() + let tinanta = Tinanta::builder() + .dhatu(dhatu.clone()) .prayoga(*prayoga) .purusha(*purusha) .vacana(*vacana) .lakara(*lakara) .build()?; - let prakriyas = a.derive_tinantas(&dhatu, &tinanta_args); + let prakriyas = a.derive_tinantas(&tinanta); let mut padas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); padas.sort(); padas.dedup(); @@ -115,11 +124,11 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { .fold(String::new(), |b, x| b + x + "+"); let sanadi_str = sanadi_str.trim_end_matches('+'); - let dhatu_text = &dhatu.upadesha(); + let dhatu_text = mula.upadesha(); let row = Row { padas, dhatu: dhatu_text, - gana: dhatu.gana().as_str(), + gana: mula.gana().as_str(), number: entry.number(), sanadi: sanadi_str.to_string(), lakara: lakara.as_str(), diff --git a/vidyut-prakriya/src/bin/explain_subanta.rs b/vidyut-prakriya/src/bin/explain_subanta.rs deleted file mode 100644 index cc408a2..0000000 --- a/vidyut-prakriya/src/bin/explain_subanta.rs +++ /dev/null @@ -1,85 +0,0 @@ -//! Debugging tool that displays all prakriyas available for the given pada and code. -//! -//! Usage: -//! -//! ```ignore -//! $ cargo run --bin explain -- --code 01.0001 --pada BavAmi -//! ``` -use clap::Parser; -use std::error::Error; -use vidyut_prakriya::args::{Linga, Pratipadika, SubantaArgs, Vacana, Vibhakti}; -use vidyut_prakriya::Ashtadhyayi; -use vidyut_prakriya::Prakriya; - -#[derive(Parser)] -#[command(author, version, about)] -struct Args { - #[arg(long)] - pratipadika: String, - #[arg(long)] - linga: Linga, - #[arg(long)] - pada: String, - #[arg(long)] - is_dhatu: Option, - #[arg(long)] - is_pratyaya: Option, -} - -fn pretty_print_prakriya(p: &Prakriya, args: &SubantaArgs) { - println!("------------------------------"); - println!( - "{:?} {:?} {:?}", - args.linga(), - args.vacana(), - args.vibhakti() - ); - println!("------------------------------"); - for step in p.history() { - println!("{:<10?} | {}", step.rule(), step.result()); - } - println!("------------------------------"); - for choice in p.rule_choices() { - println!("{choice:?}"); - } - println!("------------------------------"); -} - -fn run(args: Args) -> Result<(), Box> { - let mut padas = vec![]; - let a = Ashtadhyayi::new(); - - let pratipadika = Pratipadika::builder() - .text(&args.pratipadika) - .is_dhatu(args.is_dhatu.unwrap_or(false)) - .is_pratyaya(args.is_pratyaya.unwrap_or(false)) - .build()?; - - for vibhakti in Vibhakti::iter() { - for vacana in Vacana::iter() { - let subanta_args = SubantaArgs::builder() - .linga(args.linga) - .vibhakti(*vibhakti) - .vacana(*vacana) - .build()?; - let prakriyas = a.derive_subantas(&pratipadika, &subanta_args); - for p in prakriyas { - let text = p.text(); - if text == args.pada { - pretty_print_prakriya(&p, &subanta_args); - } - padas.push(text); - } - } - } - - let data = padas.join(", "); - println!("{}", data); - - Ok(()) -} - -fn main() { - let args = Args::parse(); - run(args).ok(); -} diff --git a/vidyut-prakriya/src/bin/test_krdantas.rs b/vidyut-prakriya/src/bin/test_krdantas.rs index c7529a9..97c433e 100644 --- a/vidyut-prakriya/src/bin/test_krdantas.rs +++ b/vidyut-prakriya/src/bin/test_krdantas.rs @@ -2,7 +2,7 @@ use clap::Parser; use std::error::Error; use std::path::PathBuf; -use vidyut_prakriya::args::{BaseKrt, KrdantaArgs}; +use vidyut_prakriya::args::{BaseKrt, Krdanta}; use vidyut_prakriya::dhatupatha; use vidyut_prakriya::private::check_file_hash; use vidyut_prakriya::Ashtadhyayi; @@ -37,9 +37,9 @@ fn run(args: Args) -> Result<(), Box> { let krt: BaseKrt = r[4].parse()?; - let krdanta_args = KrdantaArgs::builder().krt(krt).build()?; + let krdanta = Krdanta::builder().dhatu(dhatu.clone()).krt(krt).build()?; - let prakriyas = a.derive_krdantas(&dhatu, &krdanta_args); + let prakriyas = a.derive_krdantas(&krdanta); let mut actual: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); actual.sort(); actual.dedup(); @@ -50,7 +50,7 @@ fn run(args: Args) -> Result<(), Box> { } else { let krt = &r[4]; let code = format!("{:0>2}.{:0>4}", gana, number); - let upadesha = dhatu.upadesha(); + let upadesha = dhatu.upadesha().expect("ok"); println!("[ FAIL ] {code:<10} {upadesha:<10} {krt:<10}"); println!(" Expected: {:?}", expected); println!(" Actual : {:?}", actual); diff --git a/vidyut-prakriya/src/bin/test_subantas.rs b/vidyut-prakriya/src/bin/test_subantas.rs deleted file mode 100644 index dbab4dd..0000000 --- a/vidyut-prakriya/src/bin/test_subantas.rs +++ /dev/null @@ -1,96 +0,0 @@ -use clap::Parser; -use std::error::Error; -use std::path::PathBuf; -use vidyut_prakriya::args::{Pratipadika, SubantaArgs}; -use vidyut_prakriya::private::check_file_hash; -use vidyut_prakriya::Ashtadhyayi; - -#[derive(Parser)] -#[command(author, version, about)] -struct Args { - #[arg(long)] - test_cases: PathBuf, - - #[arg(long)] - hash: Option, -} - -#[derive(Debug, Clone)] -struct ArgumentError { - message: &'static str, -} - -use std::fmt; -impl fmt::Display for ArgumentError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.message) - } -} - -fn run(args: Args) -> Result<(), Box> { - if let Some(hash) = args.hash { - check_file_hash(&args.test_cases, &hash); - } - - let a = Ashtadhyayi::builder().log_steps(false).build(); - let mut num_matches = 0; - let mut n = 0; - - let mut rdr = csv::Reader::from_path(args.test_cases)?; - for maybe_row in rdr.records() { - let r = maybe_row?; - let padas = &r[0]; - let linga = &r[1].parse()?; - let vibhakti = &r[2].parse()?; - let vacana = &r[3].parse()?; - - let pratipadika = Pratipadika::builder() - .text(&r[4]) - .is_nyap(r[5].parse()?) - .is_dhatu(r[6].parse()?) - .build()?; - - let args = SubantaArgs::builder() - .linga(*linga) - .vibhakti(*vibhakti) - .vacana(*vacana) - .build()?; - let prakriyas = a.derive_subantas(&pratipadika, &args); - - let mut expected: Vec<_> = padas.split('|').collect(); - expected.sort(); - expected.dedup(); - - let mut actual: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - actual.sort(); - actual.dedup(); - - n += 1; - if expected == actual { - num_matches += 1; - } else { - println!( - "[ FAIL ] {:<10} {linga:?} {vibhakti:?} {vacana:?}", - pratipadika.text() - ); - println!(" Expected: {:?}", expected); - println!(" Actual : {:?}", actual); - } - } - - let pct = 100_f32 * (num_matches as f32) / (n as f32); - println!("{num_matches} / {n} tests pass ({pct:.2}%)"); - Ok(()) -} - -fn main() { - let args = Args::parse(); - - match run(args) { - Ok(()) => (), - Err(err) => { - println!("{}", err); - std::process::exit(1); - } - } -} diff --git a/vidyut-prakriya/src/bin/test_tinantas.rs b/vidyut-prakriya/src/bin/test_tinantas.rs index 095a220..96dd66d 100644 --- a/vidyut-prakriya/src/bin/test_tinantas.rs +++ b/vidyut-prakriya/src/bin/test_tinantas.rs @@ -2,7 +2,7 @@ use clap::Parser; use std::error::Error; use std::path::PathBuf; -use vidyut_prakriya::args::{Dhatu, Sanadi, TinantaArgs}; +use vidyut_prakriya::args::{Dhatu, Sanadi, Tinanta}; use vidyut_prakriya::dhatupatha; use vidyut_prakriya::private::check_file_hash; use vidyut_prakriya::Ashtadhyayi; @@ -54,8 +54,8 @@ fn run(args: Args) -> Result<(), Box> { // TODO: this is very clumsy! let mut builder = Dhatu::builder() - .upadesha(dhatu.upadesha()) - .gana(dhatu.gana()) + .upadesha(dhatu.upadesha().expect("ok")) + .gana(dhatu.gana().expect("ok")) .prefixes(dhatu.prefixes()) .sanadi(&sanadi); @@ -65,14 +65,15 @@ fn run(args: Args) -> Result<(), Box> { let dhatu = builder.build()?; - let tinanta_args = TinantaArgs::builder() + let tinanta_args = Tinanta::builder() + .dhatu(dhatu.clone()) .prayoga(prayoga) .purusha(purusha) .vacana(vacana) .lakara(lakara) .build()?; - let prakriyas = a.derive_tinantas(&dhatu, &tinanta_args); + let prakriyas = a.derive_tinantas(&tinanta_args); let mut actual: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); actual.sort(); actual.dedup(); @@ -85,7 +86,7 @@ fn run(args: Args) -> Result<(), Box> { let purusha = &r[6]; let vacana = &r[7]; let code = format!("{:0>2}.{:0>4}", gana, number); - let upadesha = dhatu.upadesha(); + let upadesha = dhatu.upadesha().expect("ok"); println!("[ FAIL ] {code:<10} {upadesha:<10} {lakara:<10} {purusha:<10} {vacana:<10}"); println!(" Expected: {:?}", expected); println!(" Actual : {:?}", actual); diff --git a/vidyut-prakriya/src/core.rs b/vidyut-prakriya/src/core.rs index be341a2..68f74a3 100644 --- a/vidyut-prakriya/src/core.rs +++ b/vidyut-prakriya/src/core.rs @@ -11,10 +11,10 @@ pub mod iterators; pub mod operators; pub mod prakriya_stack; -mod prakriya; -mod tag; -mod term; -mod term_view; +pub(crate) mod prakriya; +pub(crate) mod tag; +pub(crate) mod term; +pub(crate) mod term_view; pub use prakriya::*; pub use tag::*; diff --git a/vidyut-prakriya/src/core/char_view.rs b/vidyut-prakriya/src/core/char_view.rs index 029892c..4b3ea23 100644 --- a/vidyut-prakriya/src/core/char_view.rs +++ b/vidyut-prakriya/src/core/char_view.rs @@ -137,7 +137,7 @@ impl<'a> CharPrakriya<'a> { /// /// - `filter` receives two consecutive terms and returns whether the rule should apply. /// - `op` receives the prakriya and the indices of the two terms. - pub fn for_terms( + pub fn for_non_empty_terms( &mut self, filter: impl Fn(&Term, &Term) -> bool, op: impl Fn(&mut Prakriya, usize, usize), @@ -155,6 +155,13 @@ impl<'a> CharPrakriya<'a> { Some(()) } + + pub fn for_terms(&mut self, func: impl Fn(&mut Prakriya, usize) -> Option<()>) { + for i in 0..self.p.terms().len() { + func(self.p, i); + } + self.is_stale = true; + } } /// Gets the indices corresponding to the character at absolute index `i`. diff --git a/vidyut-prakriya/src/core/errors.rs b/vidyut-prakriya/src/core/errors.rs index f3d8d72..e737ecc 100644 --- a/vidyut-prakriya/src/core/errors.rs +++ b/vidyut-prakriya/src/core/errors.rs @@ -10,8 +10,6 @@ pub type Result = std::result::Result; pub enum Error { /// An IO error Io(io::Error), - /// A CSV format error. - Csv(csv::Error), /// An input vile is invalid in some way. InvalidFile, @@ -37,7 +35,7 @@ pub enum Error { Generic(&'static str), /// The caller's arguments are incompatible with the prakriya, so we aborted early. - Abort(Prakriya), + Abort(Box), } impl From for Error { @@ -47,13 +45,6 @@ impl From for Error { } } -impl From for Error { - #[inline] - fn from(err: csv::Error) -> Error { - Error::Csv(err) - } -} - impl From for Error { #[inline] fn from(err: num::ParseIntError) -> Error { @@ -83,7 +74,6 @@ impl fmt::Display for Error { match self { Io(_) => write!(f, "I/O error"), - Csv(_) => write!(f, "CSV error"), InvalidFile => write!(f, "The input file is invalid."), ParseInt(_) => write!(f, "Parse int error"), UnknownIt(c) => write!(f, "`{c}` could not be parsed as an it-samjna."), diff --git a/vidyut-prakriya/src/core/operators.rs b/vidyut-prakriya/src/core/operators.rs index 0b27f39..53f2f0f 100644 --- a/vidyut-prakriya/src/core/operators.rs +++ b/vidyut-prakriya/src/core/operators.rs @@ -86,7 +86,7 @@ pub fn ti(sub: &'static str) -> impl Fn(&mut Term) { /// Replaces all of the text in the given term. pub fn text(sub: &'static str) -> impl Fn(&mut Term) { - move |t| t.text.replace_range(.., sub) + move |t| t.set_text(sub) } // Insertion of new terms @@ -142,13 +142,12 @@ pub fn append_agama(rule: impl Into, p: &mut Prakriya, i: usize, sub: &str /// Complex op pub fn adesha(rule: impl Into, p: &mut Prakriya, i: usize, sub: &str) { - if let Some(t) = p.get_mut(i) { + p.run_at(rule, i, |t| { t.save_lakshana(); t.set_u(sub); t.set_text(sub); - p.step(rule); - it_samjna::run(p, i).expect("should always succeed"); - } + }); + it_samjna::run(p, i).expect("should always succeed"); } pub fn optional_adesha( diff --git a/vidyut-prakriya/src/core/prakriya.rs b/vidyut-prakriya/src/core/prakriya.rs index 4a66dae..fe666a8 100644 --- a/vidyut-prakriya/src/core/prakriya.rs +++ b/vidyut-prakriya/src/core/prakriya.rs @@ -4,7 +4,7 @@ Manages the derivation state. Users interested in understanding this module should start by reading the comments on the `Prakriya` struct, which manages a derivation from start to finish. */ -use crate::args::{Artha, Lakara, Pada, Pratipadika}; +use crate::args::{Artha, Lakara}; use crate::core::Tag; use crate::core::{Term, TermView}; use compact_str::CompactString; @@ -22,9 +22,10 @@ pub enum Rule { /// A sutra from the Ashtadhyayi. The string data here is an adhyaya-pada-sutra string, e.g. /// "3.1.68". Ashtadhyayi(&'static str), - /// A comment in the Kashika-vrtti on a specific sutra. The string data here is an - /// adhyaya-pada-sutra string that describes the sutra being commented on. - Kashika(&'static str), + /// A varttika on the Ashtadhyayi. The first string is an adhyaya-pada-sutra string, e.g. + /// "3.1.68",a nd the second string is an integer corresponding to the vArttika's position on + /// the sutra, e.g. "2" for the second vArttika on some sUtra. + Varttika(&'static str, &'static str), /// A sutra from the Dhatupatha. The string data here is a gana-sutra string, e.g. "10.0493". Dhatupatha(&'static str), /// A sutra from the Unadipatha. The string here is a gana-sutra string, e.g. "1.1". @@ -32,6 +33,11 @@ pub enum Rule { /// A sutra from the Paniniya-Linganushasanam. The string here is the sutra's position in the /// text, e.g. "40". Linganushasana(&'static str), + /// A sutra from the Phit Sutras. The string here is a gana-sutra string, e.g. "1.1". + Phit(&'static str), + /// A comment in the Kashika-vrtti on a specific sutra. The string data here is an + /// adhyaya-pada-sutra string that describes the sutra being commented on. + Kashika(&'static str), /// A quotation from the Vaiyakarana-siddhanta-kaumudi. The string here is the position of the /// sutra being commented on in Kaumudi order, e.g. "446". Kaumudi(&'static str), @@ -42,10 +48,12 @@ impl Rule { pub fn code(&self) -> &'static str { match self { Self::Ashtadhyayi(x) => x, - Self::Kashika(x) => x, + Self::Varttika(x, _) => x, Self::Dhatupatha(x) => x, Self::Unadipatha(x) => x, Self::Linganushasana(x) => x, + Self::Phit(x) => x, + Self::Kashika(x) => x, Self::Kaumudi(x) => x, } } @@ -69,7 +77,8 @@ impl From<&'static str> for Rule { #[derive(Clone, Debug, Hash, Eq, PartialEq)] pub struct Step { rule: Rule, - result: String, + result: Vec, + active: Option, } impl Step { @@ -79,9 +88,15 @@ impl Step { } /// The result of applying `rule`. - pub fn result(&self) -> &String { + pub fn result(&self) -> &Vec { &self.result } + + /// Returns the index of the item in `result` that was modified, or `None` if the rule modified + /// either more than one term or no terms. + pub fn active(&self) -> Option { + self.active + } } /// Records whether an optional rule was accepted or declined. @@ -94,11 +109,12 @@ pub enum RuleChoice { } /// Configuration options that affect how a `Prakriya` behaves during the derivation. -#[derive(Default, Debug)] +#[derive(Clone, Default, Debug)] pub(crate) struct Config { pub rule_choices: Vec, pub log_steps: bool, pub is_chandasi: bool, + pub use_svaras: bool, } impl Config { @@ -154,8 +170,14 @@ impl Prakriya { /// complete, `text()` will thus represent the derivation's final output. pub fn text(&self) -> String { let mut ret = String::from(""); - for t in &self.terms { - ret.push_str(&t.text); + if self.config.use_svaras { + for t in &self.terms { + ret.push_str(&t.text_with_svaras().replace('\\', "")); + } + } else { + for t in &self.terms { + ret.push_str(&t.text); + } } ret } @@ -205,8 +227,11 @@ impl Prakriya { /// }) /// ``` /// -/// But for convenience, we have also defined `run_optional` and `run_optional_at`. +/// For convenience, we have also defined `optional_run` and `optional_run_at`. impl Prakriya { + // Constructors + // ------------ + /// Creates an empty prakriya. pub(crate) fn new() -> Self { Prakriya { @@ -220,6 +245,16 @@ impl Prakriya { } } + /// Creates an empty prakriya with the given config options. + pub(crate) fn with_config(config: Config) -> Self { + let mut p = Prakriya::new(); + p.config = config; + p + } + + // Accessors + // --------- + /// Like `text` but creates a `CompactString`. /// /// `CompactString` is an implementation detail that we don't wish to expose in the public API. @@ -231,15 +266,6 @@ impl Prakriya { ret } - /// Creates an empty prakriya with the given config options. - pub(crate) fn with_config(config: Config) -> Self { - let mut p = Prakriya::new(); - p.config = config; - p - } - - // Term accessors - /// Returns all terms. pub(crate) fn terms(&self) -> &Vec { &self.terms @@ -273,6 +299,51 @@ impl Prakriya { None } + // Views + // ----- + + pub(crate) fn custom_view(&self, start: usize, end: usize) -> Option { + TermView::new(self.terms(), start, end) + } + + /// Creates a pada view whose last index is `i_end`. + pub(crate) fn pada(&self, i_end: usize) -> Option { + let t = self.get(i_end)?; + if t.is_pada() { + TermView::new(self.terms(), 0, i_end) + } else { + None + } + } + + /// Creates a nyApu/pratipadika view whose last index is `i_end`. + /// + /// The pratipadika-samjna technically does not include the nyApu-pratyayas. But, most rules + /// that deal with pratipadikas also want access to terms ending in nyAp-pratyayas per rule + /// 4.1.2 (NyAp-prAtipadikAt). So, this method returns both pratipadikas and nyApu-antas. + pub(crate) fn nyapu_pratipadika(&self, i_end: usize) -> Option { + let t = self.get(i_end)?; + if t.is_pratipadika_or_nyapu() { + TermView::new(self.terms(), 0, i_end) + } else { + None + } + } + + /// Creates a pratyaya view whose first index is `i_start`. + /// + /// (This is a legacy API.) + pub(crate) fn pratyaya(&self, i_start: usize) -> Option { + TermView::with_start(self.terms(), i_start) + } + + // Properties + // ---------- + + pub(crate) fn is_karmadharaya(&self) -> bool { + self.has_tag(Tag::Karmadharaya) + } + /// Returns whether the given prakriya express bhAve/karmani prayoga. pub(crate) fn is_bhave_or_karmani(&self) -> bool { self.any(&[Tag::Bhave, Tag::Karmani]) @@ -305,9 +376,8 @@ impl Prakriya { } } - pub(crate) fn custom_view(&self, start: usize, end: usize) -> Option { - TermView::new(self.terms(), start, end) - } + // Index lookup + // ------------ /// Returns the index of the first `Term` that matches the predicate function `f` or `None` if /// no such term exists. @@ -430,6 +500,7 @@ impl Prakriya { } // Filters + // ------- /// Returns whether a term exists at `index` and matches the condition in `filter`. pub(crate) fn has(&self, index: usize, filter: impl Fn(&Term) -> bool) -> bool { @@ -454,37 +525,6 @@ impl Prakriya { tags.iter().any(|t| self.tags.contains(*t)) } - /// Creates a pada view whose last index is `i_end`. - pub(crate) fn pada(&self, i_end: usize) -> Option { - let t = self.get(i_end)?; - if t.is_sup() || t.is_tin() { - TermView::new(&self.terms(), 0, i_end) - } else { - None - } - } - - /// Creates a nyAp/pratipadika view whose last index is `i_end`. - /// - /// The pratipadika-samjna technically does not include the nyAp-pratyayas. But, most rules - /// that deal with pratipadikas also want access to terms ending in nyAp-pratyayas per rule - /// 4.1.2 (NyAp-prAtipadikAt). So, this method returns both pratipadikas and nyAp-antas. - pub(crate) fn nyap_pratipadika(&self, i_end: usize) -> Option { - let t = self.get(i_end)?; - if t.is_pratipadika_or_nyap() { - TermView::new(&self.terms(), 0, i_end) - } else { - None - } - } - - /// Creates a pratyaya view whose first index is `i_start`. - /// - /// (This is a legacy API.) - pub(crate) fn pratyaya(&self, i_start: usize) -> Option { - TermView::with_start(self.terms(), i_start) - } - /// Returns whether the prakriya contains a pratipadika with value `text` that ends at index `i`. /// /// A simple pratipadika exists in exactly one term, but a more complex pratipadika (krdanta, @@ -512,7 +552,22 @@ impl Prakriya { false } + pub(crate) fn has_prev_non_empty(&self, index: usize, func: impl Fn(&Term) -> bool) -> bool { + match self.find_prev_where(index, |t| !t.is_empty()) { + Some(i) => func(self.get(i).expect("ok")), + None => false, + } + } + + pub(crate) fn has_next_non_empty(&self, index: usize, func: impl Fn(&Term) -> bool) -> bool { + match self.find_next_where(index, |t| !t.is_empty()) { + Some(i) => func(self.get(i).expect("ok")), + None => false, + } + } + // Basic mutators + // -------------- /// Adds a tag to the prakriya. pub(crate) fn add_tag(&mut self, tag: Tag) { @@ -584,6 +639,7 @@ impl Prakriya { } // Rule application + // ---------------- /// Runs `func` on the `Prakriya` then records `rule` in the derivation history. /// @@ -606,7 +662,7 @@ impl Prakriya { ) -> bool { if let Some(term) = self.get_mut(index) { func(term); - self.step(rule.into()); + self.step_at(rule.into(), index); true } else { false @@ -668,57 +724,58 @@ impl Prakriya { }) } + /// OPtionally adds `tag` to the term at `index` then records `rule` in the derivation history. + /// + /// Returns: whether `tag` was added. + pub(crate) fn optional_add_tag_at( + &mut self, + rule: impl Into, + index: usize, + tag: Tag, + ) -> bool { + let rule = rule.into(); + self.optionally(rule, |rule, p| { + p.add_tag_at(rule, index, tag); + }) + } + /// Adds `rule` and the current derivation state to the derivation history. pub(crate) fn step(&mut self, rule: impl Into) { if self.config.log_steps { - let state = self.terms.iter().fold(String::new(), |a, b| { - if a.is_empty() { - a + &b.text - } else { - a + " + " + &b.text - } - }); + let result = self.terms.iter().map(|t| t.text_with_svaras()).collect(); self.history.push(Step { rule: rule.into(), - result: state, + result, + active: None, }) } } - /// (debug) Writes the given string to the history. - #[allow(unused)] - #[cfg(debug_assertions)] - pub(crate) fn debug(&mut self, text: impl AsRef) { - self.history.push(Step { - rule: Rule::Ashtadhyayi("debug"), - result: text.as_ref().to_string(), - }); - } - - #[allow(unused)] - #[cfg(not(debug_assertions))] - pub(crate) fn debug(&mut self, _text: impl AsRef) {} - - /// (debug) Writes the current Prakriya state to the history. - #[allow(unused)] - #[cfg(debug_assertions)] - pub(crate) fn dump(&mut self) { - let n = self.terms().len(); - self.debug(format!("tags: {:?}", self.tags)); - self.debug(format!("{:#?}", self.terms())); + /// Adds `rule` and the current derivation state to the derivation history. + pub(crate) fn step_at(&mut self, rule: impl Into, index: usize) { + if self.config.log_steps { + let result = self.terms.iter().map(|t| t.text_with_svaras()).collect(); + self.history.push(Step { + rule: rule.into(), + result, + active: Some(index), + }) + } } - #[allow(unused)] - #[cfg(not(debug_assertions))] - pub(crate) fn dump(&mut self) {} - // Optional rules + // -------------- /// Returns whether the prakriya allows chAndasa rules. pub(crate) fn is_chandasi(&self) -> bool { self.config.is_chandasi } + /// Returns whether the prakriya allows chAndasa rules. + pub(crate) fn use_svaras(&self) -> bool { + self.config.use_svaras + } + pub(crate) fn is_allowed(&mut self, r: impl Into) -> bool { let r = r.into(); for option in &self.config.rule_choices { @@ -749,32 +806,35 @@ impl Prakriya { pub(crate) fn decline(&mut self, rule: impl Into) { self.rule_choices.push(RuleChoice::Decline(rule.into())); } -} -impl From for Option { - /// (experimental) Converts this prakriya to a `Pratipadika`. - fn from(p: Prakriya) -> Self { - Pratipadika::from_terms(p.terms) - } -} + // Debugging code + // -------------- -impl From<&Prakriya> for Option { - /// (experimental) Converts this prakriya to a `Pratipadika`. - fn from(p: &Prakriya) -> Self { - Pratipadika::from_terms(p.terms.clone()) + /// (debug) Writes the given string to the history. + #[allow(unused)] + #[cfg(debug_assertions)] + pub(crate) fn debug(&mut self, text: impl AsRef) { + self.history.push(Step { + rule: Rule::Ashtadhyayi(" "), + result: vec![text.as_ref().to_string()], + active: None, + }); } -} -impl From for Option { - /// (experimental) Converts this prakriya to a `Pratipadika`. - fn from(p: Prakriya) -> Self { - Pada::from_terms(p.terms) - } -} + #[allow(unused)] + #[cfg(not(debug_assertions))] + pub(crate) fn debug(&mut self, _text: impl AsRef) {} -impl From<&Prakriya> for Option { - /// (experimental) Converts this prakriya to a `Pratipadika`. - fn from(p: &Prakriya) -> Self { - Pada::from_terms(p.terms.clone()) + /// (debug) Writes the current Prakriya state to the history. + #[allow(unused)] + #[cfg(debug_assertions)] + pub(crate) fn dump(&mut self) { + let n = self.terms().len(); + self.debug(format!("tags: {:?}", self.tags)); + self.debug(format!("{:#?}", self.terms())); } + + #[allow(unused)] + #[cfg(not(debug_assertions))] + pub(crate) fn dump(&mut self) {} } diff --git a/vidyut-prakriya/src/core/prakriya_stack.rs b/vidyut-prakriya/src/core/prakriya_stack.rs index 6427b96..809ee12 100644 --- a/vidyut-prakriya/src/core/prakriya_stack.rs +++ b/vidyut-prakriya/src/core/prakriya_stack.rs @@ -12,6 +12,8 @@ pub(crate) struct PrakriyaStack { log_steps: bool, /// Whether a prakriya should use chAndasa rules. is_chandasi: bool, + /// Whether svara rules are enabled. + use_svaras: bool, /// Completed prakriyas. prakriyas: Vec, @@ -21,12 +23,13 @@ pub(crate) struct PrakriyaStack { impl PrakriyaStack { /// Creates an empty `PrakriyaStack`. - pub fn new(log_steps: bool, is_chandasi: bool) -> Self { + pub fn new(log_steps: bool, is_chandasi: bool, use_svaras: bool) -> Self { Self { prakriyas: Vec::new(), paths: Vec::new(), log_steps, is_chandasi, + use_svaras, } } @@ -36,6 +39,7 @@ impl PrakriyaStack { rule_choices, log_steps: self.log_steps, is_chandasi: self.is_chandasi, + use_svaras: self.use_svaras, }) } diff --git a/vidyut-prakriya/src/core/tag.rs b/vidyut-prakriya/src/core/tag.rs index abe70ee..b4bcfb6 100644 --- a/vidyut-prakriya/src/core/tag.rs +++ b/vidyut-prakriya/src/core/tag.rs @@ -150,6 +150,8 @@ pub enum Tag { /// (pratyaya) indicates lopa that causes dvitva (hu -> juhoti) Slu, Lup, + /// Indicates that luk is blocked. + Aluk, /// (dhatu) various functions: /// - blocks it-agama per 7.2.10. @@ -173,9 +175,6 @@ pub enum Tag { Sanartha, Yanartha, - // Dialect conditions - Chandasi, - // Prayoga Kartari, Bhave, @@ -285,10 +284,8 @@ pub enum Tag { Samahara, StriNyap, - TrnTrc, Pada, Bha, - YanLuk, Dvitva, Gha, diff --git a/vidyut-prakriya/src/core/term.rs b/vidyut-prakriya/src/core/term.rs index e2e6bcf..5716fe9 100644 --- a/vidyut-prakriya/src/core/term.rs +++ b/vidyut-prakriya/src/core/term.rs @@ -12,6 +12,19 @@ lazy_static! { static ref AC: Set = s("ac"); } +/// Models the svaras on a particular `Term`. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub(crate) enum Svara { + /// Indicates that the entire `Term` has the *anudAtta* accent. + Anudatta, + /// Indicates that the `Term` has the *udAtta* accent on the specified vowel. If the first + /// vowel receives the accent, we store `0`; if the second vowel, `1`; and so on. + Udatta(usize), + /// Indicates that the `Term` has the *svarita* accent on the specified vowel. If the first + /// vowel receives the accent, we store `0`; if the second vowel, `1`; and so on. + Svarita(usize), +} + /// A string with additional metadata. /// /// A typical prakriya uses various kinds of terms. For example, the prakriya for *cakAra* contains @@ -42,6 +55,8 @@ pub struct Term { pub(crate) u: Option, /// The text of this term. This string contains sound changes such as guna, vrddhi, lopa, etc. pub(crate) text: CompactString, + /// The svara that applies to this term. + pub(crate) svara: Option, /// The form of the term to use for sthAnivad-bhAva substitutions, e.g. for dvitva on the /// dhatu. For example, when applying dvitva for BAvi, the abhyasa should be BO, not BAv. /// @@ -72,6 +87,7 @@ impl Term { gana: None, antargana: None, lakshanas: Vec::new(), + svara: None, } } @@ -85,6 +101,7 @@ impl Term { gana: None, antargana: None, lakshanas: Vec::new(), + svara: None, } } @@ -103,6 +120,48 @@ impl Term { t } + // Attributes + // ---------- + + /// Returns this term's text with svaras rendered. + pub fn text_with_svaras(&self) -> String { + let mut ret = String::new(); + let mut vowels_seen = 0; + for c in self.text.chars() { + ret.push(c); + if sounds::is_ac(c) { + let sub = match self.svara { + Some(Svara::Udatta(i)) if i == vowels_seen => "/", + Some(Svara::Svarita(i)) if i == vowels_seen => "^", + Some(Svara::Anudatta) => "\\", + _ => "", + }; + ret.push_str(sub); + vowels_seen += 1; + } + } + ret + } + + pub fn sthanivat(&self) -> &CompactString { + &self.sthanivat + } + + /// Returns the number of vowels contained in this term's text. + pub fn num_vowels(&self) -> usize { + self.text.chars().filter(|c| AC.contains(*c)).count() + } + + /// Wrapper over `CompactString::len`. + pub fn len(&self) -> usize { + self.text.len() + } + + /// Wrapper over `CompactString::chars`. + pub fn chars(&self) -> std::str::Chars<'_> { + self.text.chars() + } + // Sound selectors // --------------- @@ -158,7 +217,95 @@ impl Term { self.matches_sound_pattern(self.get_at(i), pattern) } - /// Returns whether the term has a specific upadesha. + /// Returns whether the term has exactly one vowel. + pub fn is_ekac(&self) -> bool { + // TODO: find a way to de-dupe with `is_anekac` in the asiddhavat section. + self.num_vowels() == 1 + } + + /// Returns whether the term has at least one vowel. + pub fn has_ac(&self) -> bool { + self.text.chars().any(|c| AC.contains(c)) + } + + /// Returns whether the term begins with a conjunct consonant. + pub fn is_samyogadi(&self) -> bool { + sounds::is_samyogadi(&self.text) + } + + /// Returns whether the term ends in a conjunct consonant. + pub fn is_samyoganta(&self) -> bool { + sounds::is_samyoganta(&self.text) + } + + /// Returns whether the last sound of the term is a short vowel. + pub fn is_hrasva(&self) -> bool { + match self.antya() { + Some(c) => sounds::is_hrasva(c), + None => false, + } + } + + /// Returns whether the last sound of the term is a long vowel. + pub fn is_dirgha(&self) -> bool { + match self.antya() { + Some(c) => sounds::is_dirgha(c), + None => false, + } + } + + /// Returns whether the first syllable of the term is or could be laghu. + #[allow(dead_code)] + pub fn is_laghu_adi(&self) -> bool { + let mut had_ac = false; + let mut num_consonants = 0; + for c in self.text.chars() { + if sounds::is_ac(c) { + if sounds::is_dirgha(c) { + return false; + } + had_ac = true; + } else if had_ac { + num_consonants += 1; + if num_consonants > 1 { + return false; + } + } + } + true + } + + /// Returns whether the last syllable of the term is or could be laghu. + pub fn is_laghu(&self) -> bool { + // 1.4.10 hrasvaM laghu + // 1.4.11 saMyoge guru + // 1.4.12 dIrghaM ca + if let Some(c) = self.antya() { + if sounds::is_ac(c) { + sounds::is_hrasva(c) + } else { + // upadha is hrasva --> laghu + // upadha is dirgha --> guru + // upadha is hal --> guru (samyoga) + // upadha is missing --> laghu + self.upadha().map(sounds::is_hrasva).unwrap_or(false) + // HACK for C, which will always become cC (= guru). + && c != 'C' + } + } else { + false + } + } + + /// Returns whether the last syllable of the term is guru. + pub fn is_guru(&self) -> bool { + !self.is_laghu() + } + + // Text properties + // --------------- + + /// Returns whether the term has a specific aupadeshika form. pub fn has_u(&self, s: &str) -> bool { match &self.u { Some(u) => u == &s, @@ -166,7 +313,7 @@ impl Term { } } - /// Returns whether the term has an upadesha in the specified list. + /// Returns whether the term has an aupadeshika in the specified list. pub fn has_u_in(&self, items: &[&str]) -> bool { match &self.u { Some(u) => items.contains(&u.as_str()), @@ -206,6 +353,11 @@ impl Term { suffixes.iter().any(|t| self.text.ends_with(t)) } + /// Returns whether the term's text starts with the given `prefix`. + pub fn starts_with(&self, prefix: &str) -> bool { + self.text.starts_with(prefix) + } + /// Returns whether the term's text ends with the given `suffix`. pub fn ends_with(&self, suffix: &str) -> bool { self.text.ends_with(suffix) @@ -218,19 +370,11 @@ impl Term { /// Returns whether the term has the given antargana. pub fn has_antargana(&self, antargana: Antargana) -> bool { - match self.antargana { - Some(x) => x == antargana, - _ => false, - } - } - - /// Returns the number of vowels contained in this term's text. - pub fn num_vowels(&self) -> usize { - self.text.chars().filter(|c| AC.contains(*c)).count() + self.antargana == Some(antargana) } - // Tags - // ---- + // Tag properties + // -------------- /// Returns whether the term has the given tag. pub fn has_tag(&self, tag: Tag) -> bool { @@ -252,14 +396,9 @@ impl Term { self.text.is_empty() } - /// Returns whether the term has exactly one vowel. - pub fn is_ekac(&self) -> bool { - // TODO: find a way to de-dupe with `is_anekac` in the asiddhavat section. - self.num_vowels() == 1 - } - // Samjna properties // ----------------- + // These simple wrappers over `has_tag` improve readability in our rule code. /// Returns whether the term has the `abhyAsa` samjna. pub fn is_abhyasa(&self) -> bool { @@ -276,7 +415,7 @@ impl Term { self.has_tag(Tag::Agama) } - /// Returns whether the term is an ardhadhatuka pratyaya. + /// Returns whether the term has the `Ardhadhatuka` samjna. pub fn is_ardhadhatuka(&self) -> bool { self.has_tag(Tag::Ardhadhatuka) } @@ -308,7 +447,15 @@ impl Term { self.has_tag(Tag::Ekavacana) } - /// Returns whether the term has the `dhatu` samjna. + /// Returns whether the term has the `Anga` samjna. + /// + /// (experimental) + pub fn is_anga(&self) -> bool { + // `is_pratyaya` is for Snu (sunoti). + self.is_dhatu() || self.is_pratipadika_or_nyapu() || self.is_pratyaya() + } + + /// Returns whether the term has the `Dhatu` samjna. pub fn is_dhatu(&self) -> bool { self.has_tag(Tag::Dhatu) } @@ -318,7 +465,7 @@ impl Term { self.has_tag(Tag::Gati) } - /// Returns whether the term is kit or Nit. + /// Returns whether the term has the `kit` or `Nit` samjnas. pub fn is_knit(&self) -> bool { self.has_tag_in(&[Tag::kit, Tag::Nit]) } @@ -333,6 +480,10 @@ impl Term { self.has_tag(Tag::Krtya) } + pub fn is_kya(&self) -> bool { + self.has_u_in(&["kyaN", "kyac", "kyaz"]) + } + /// Returns whether the term has undergone lopa (1.1.60) pub fn is_lupta(&self) -> bool { self.has_tag_in(&[Tag::Luk, Tag::Slu, Tag::Lup]) @@ -348,16 +499,14 @@ impl Term { self.has_tag(Tag::Nipata) } - /// Returns whether the term is a nistha. + /// Returns whether the term has the `Nistha` samjna. pub fn is_nistha(&self) -> bool { self.has_tag(Tag::Nistha) } /// Returns whether the term could be called a `pada`. pub fn is_pada(&self) -> bool { - // TODO: create and use `T::Pada` instead. - // TODO: avoid `Upasarga` hack. - self.has_tag_in(&[Tag::Pada, Tag::Tin, Tag::Sup, Tag::Upasarga]) + self.has_tag(Tag::Pada) } /// Returns whether the term has the `Atmanepada` samjna. @@ -370,9 +519,12 @@ impl Term { self.has_tag(Tag::Pratipadika) } - /// Returns whether the term has the `Pratipadika` samjna or is a nyAp-pratyaya. - pub fn is_pratipadika_or_nyap(&self) -> bool { - self.has_tag(Tag::Pratipadika) || self.is_nyap_pratyaya() + /// Returns whether the term meets one of the following conditions: + /// 1. The term has the `Pratipadika` samjna. + /// 2. The term is a nyAp-pratyaya. + /// 3. The term is the strI-pratyaya UN. + pub fn is_pratipadika_or_nyapu(&self) -> bool { + self.has_tag(Tag::Pratipadika) || self.is_nyap_pratyaya() || self.has_u("UN") } /// Returns whether the term has the `Pratyaya` samjna. @@ -396,11 +548,11 @@ impl Term { } pub fn is_aap_pratyaya(&self) -> bool { - self.has_tag(Tag::Pratyaya) && self.has_u_in(&["dAp", "wAp", "cAp"]) + self.has_tag(Tag::Pratyaya) && self.has_u_in(&["cAp", "wAp", "qAp"]) } pub fn is_nyap_pratyaya(&self) -> bool { - self.has_tag(Tag::Pratyaya) && self.has_u_in(&["wAp", "cAp", "dAp", "NIp", "NIz"]) + self.has_tag(Tag::Pratyaya) && self.has_u_in(&["cAp", "wAp", "qAp", "NIn", "NIp", "NIz"]) } /// Returns whether the term has the `Taddhita` samjna. @@ -408,6 +560,11 @@ impl Term { self.has_tag(Tag::Samasa) } + /// Returns whether the term has the `Taddhita` samjna. + pub fn is_sambuddhi(&self) -> bool { + self.has_tag(Tag::Sambuddhi) + } + /// Returns whether the term has the `Sarvanama` samjna. pub fn is_sarvadhatuka(&self) -> bool { self.has_tag(Tag::Sarvadhatuka) @@ -438,7 +595,7 @@ impl Term { self.has_tag(Tag::Tin) } - /// Returns whether the term is an upasarga. + /// Returns whether the term has the `Upasarga` samjna. pub fn is_upasarga(&self) -> bool { self.has_tag(Tag::Upasarga) } @@ -448,7 +605,7 @@ impl Term { self.has_tag(Tag::Vibhakti) } - /// Returns whether the term is vrddha. + /// Returns whether the term has the `Vrddha` samjna. pub fn is_vrddha(&self) -> bool { self.has_tag(Tag::Vrddha) } @@ -466,87 +623,6 @@ impl Term { self.is_agama() && self.has_u("iw") } - // Other properties - // ---------------- - - /// Returns whether the term begins with a conjunct consonant. - pub fn is_samyogadi(&self) -> bool { - sounds::is_samyogadi(&self.text) - } - - /// Returns whether the term ends in a conjunct consonant. - pub fn is_samyoganta(&self) -> bool { - sounds::is_samyoganta(&self.text) - } - - /// Returns whether the last sound of the term is a short vowel. - pub fn is_hrasva(&self) -> bool { - match self.antya() { - Some(c) => sounds::is_hrasva(c), - None => false, - } - } - - /// Returns whether the last sound of the term is a long vowel. - pub fn is_dirgha(&self) -> bool { - match self.antya() { - Some(c) => sounds::is_dirgha(c), - None => false, - } - } - - /// Returns whether the first syllable of the term is or could be laghu. - #[allow(dead_code)] - pub fn is_laghu_adi(&self) -> bool { - let mut had_ac = false; - let mut num_consonants = 0; - for c in self.text.chars() { - if sounds::is_ac(c) { - if sounds::is_dirgha(c) { - return false; - } - had_ac = true; - } else if had_ac { - num_consonants += 1; - if num_consonants > 1 { - return false; - } - } - } - true - } - - /// Returns whether the last syllable of the term is or could be laghu. - pub fn is_laghu(&self) -> bool { - // 1.4.10 hrasvaM laghu - // 1.4.11 saMyoge guru - // 1.4.12 dIrghaM ca - if let Some(c) = self.antya() { - if sounds::is_ac(c) { - sounds::is_hrasva(c) - } else { - // upadha is hrasva --> laghu - // upadha is dirgha --> guru - // upadha is hal --> guru (samyoga) - // upadha is missing --> laghu - self.upadha().map(sounds::is_hrasva).unwrap_or(false) - // HACK for C, which will always become cC (= guru). - && c != 'C' - } - } else { - false - } - } - - /// Returns whether the last syllable of the term is guru. - pub fn is_guru(&self) -> bool { - !self.is_laghu() - } - - pub fn sthanivat(&self) -> &CompactString { - &self.sthanivat - } - // Mutators // -------- @@ -579,7 +655,7 @@ impl Term { /// Replaces the character at index `i` with the given value. pub fn set_at(&mut self, i: usize, s: &str) { - self.text.replace_range(i..i + 1, s); + self.text.replace_range(i..=i, s); } /// Sets the term's upadesha to the given value. @@ -592,15 +668,20 @@ impl Term { self.text.replace_range(.., s); } - /// Sets the dhatu's gana. + /// Sets the term's gana. pub fn set_gana(&mut self, gana: Gana) { self.gana = Some(gana); } + /// Sets the term's svara. + pub(crate) fn set_svara(&mut self, s: Svara) { + self.svara = Some(s); + } + pub fn find_and_replace_text(&mut self, needle: &str, sub: &str) { - // Ugly, but it works - let alloc = self.text.replace(needle, sub); - self.text = CompactString::from(&alloc); + if let Some(i) = self.text.find(needle) { + self.text.replace_range(i..i + needle.len(), sub) + } } pub fn maybe_save_sthanivat(&mut self) { diff --git a/vidyut-prakriya/src/core/term_view.rs b/vidyut-prakriya/src/core/term_view.rs index 2360de8..2bfc216 100644 --- a/vidyut-prakriya/src/core/term_view.rs +++ b/vidyut-prakriya/src/core/term_view.rs @@ -36,7 +36,7 @@ pub struct TermView<'a> { impl<'a> TermView<'a> { /// Creates a new term view over the interval `[start, end]`` pub fn new(terms: &'a Vec, start: usize, end: usize) -> Option { - if end + 1 <= terms.len() { + if end < terms.len() { Some(TermView { terms, start, end }) } else { None @@ -104,7 +104,7 @@ impl<'a> TermView<'a> { // Accessors pub fn terms(&self) -> &[Term] { - &self.terms + self.terms } pub fn slice(&self) -> &[Term] { @@ -153,7 +153,7 @@ impl<'a> TermView<'a> { /// Returns whether the view's text is empty. #[allow(unused)] pub fn is_empty(&self) -> bool { - self.slice().iter().all(|t| t.text.is_empty()) + self.slice().iter().all(|t| t.is_empty()) } /// Returns whether this view is at the very end of the given word. diff --git a/vidyut-prakriya/src/dhatu_gana.rs b/vidyut-prakriya/src/dhatu_gana.rs index 4a5b0f5..0d3247f 100644 --- a/vidyut-prakriya/src/dhatu_gana.rs +++ b/vidyut-prakriya/src/dhatu_gana.rs @@ -330,11 +330,3 @@ pub const LU_ADI: &[&str] = &[ "lUY", "stFY", "kFY", "vFY", "DUY", "SF", "pF", "vF", "BF", "mF", "dF", "jF", "JF", "DF", "nF", "kF", "F", "gF", "jyA\\", ]; - -/// Dhatus for 3.1.27. These dhatus were copied from the S. C. Vasu commentary on that rule. -pub const KANDU_ADI: &[&str] = &[ - "kaRqUY", "mantu", "hraRIY", "valgu", "astra", "manas", "mahIN", "lew", "low", "iras", "iraj", - "iraY", "dravas", "meDA", "kuzuBa", "magaDa", "tantas", "pampas", "suKa", "duHKa", "sapara", - "ara", "Bizaj", "BizRaj", "izuDa", "caraRa", "curaRa", "BuraRa", "turaRa", "gadgada", "elA", - "kelA", "KelA", "liw", "low", -]; diff --git a/vidyut-prakriya/src/dhatu_karya.rs b/vidyut-prakriya/src/dhatu_karya.rs index 70817cf..1da0e8a 100644 --- a/vidyut-prakriya/src/dhatu_karya.rs +++ b/vidyut-prakriya/src/dhatu_karya.rs @@ -8,8 +8,8 @@ Operations here include: - inserting upasargas - applying gana sutras */ +use crate::args::dhatu::Muladhatu; use crate::args::Antargana; -use crate::args::Dhatu; use crate::args::Gana; use crate::core::errors::*; use crate::core::operators as op; @@ -17,11 +17,11 @@ use crate::core::Tag as T; use crate::core::Term; use crate::core::{Prakriya, Rule}; use crate::dhatu_gana as gana; -use crate::ganapatha::PRA_ADI; use crate::it_samjna; +use crate::samjna; /// Adds the mula-dhatu to the prakriya. -fn add_mula_dhatu(p: &mut Prakriya, dhatu: &Dhatu) { +fn add_mula_dhatu(p: &mut Prakriya, dhatu: &Muladhatu) { p.run("1.3.1", |p| { let mut dhatu = Term::make_dhatu(dhatu.upadesha(), dhatu.gana(), dhatu.antargana()); dhatu.add_tag(T::Dhatu); @@ -139,7 +139,7 @@ fn try_satva_and_natva(p: &mut Prakriya, i: usize) -> Option<()> { // Also undo retroflexion of `R`. This occurs only in two roots, as far as I can // tell: zaRa~ and zaRu~. So, just check for `zaR`: if t.text == "zaR" { - t.text.replace_range(.., "san"); + t.set_text("san"); } t.add_tag(T::FlagSaAdeshadi); }); @@ -179,34 +179,35 @@ fn try_add_num_agama(p: &mut Prakriya, i: usize) { } /// Adds prefixes from `dhatu` into the prakriya. -fn try_add_prefixes(p: &mut Prakriya, dhatu: &Dhatu) -> Option<()> { - let i_offset = p.find_first(T::Dhatu)?; +pub fn try_add_prefixes(p: &mut Prakriya, prefixes: &[String]) -> Option<()> { + let mut i_offset = p.find_first(T::Dhatu).unwrap_or(0); // TODO: prefixes that aren't upasargas? - for (i, prefix) in dhatu.prefixes().iter().enumerate() { - let i_upasarga = i + i_offset; - let mut t = Term::make_upadesha(prefix); - - if PRA_ADI.contains(&prefix.as_str()) { - t.add_tag(T::Upasarga); - p.insert_before(i_upasarga, t); - p.step("1.4.80"); - } else { - p.insert_before(i_upasarga, t); - } + for prefix in prefixes { + let t = Term::make_upadesha(&prefix); + p.insert_before(i_offset, t); + samjna::try_nipata_rules(p, i_offset); + + let mut su = Term::make_upadesha("su~"); + su.add_tags(&[T::Pada, T::V1, T::Sup, T::Ekavacana, T::Luk, T::Pratyaya]); + su.set_text(""); + p.insert_before(i_offset + 1, su); // Don't run it-samjna-prakarana for other upasargas (e.g. sam, ud) // TODO: why run only for AN? if prefix == "AN" { - it_samjna::run(p, i_upasarga).ok()?; + it_samjna::run(p, i_offset).ok()?; } + + // Add 1 for prefix and 1 for su~. + i_offset += 2; } Some(()) } /// Adds a dhatu to the prakriya and runs various follow-up rules on it. -pub fn run(p: &mut Prakriya, dhatu: &Dhatu) -> Result<()> { +pub fn run(p: &mut Prakriya, dhatu: &Muladhatu) -> Result<()> { add_mula_dhatu(p, dhatu); let i_dhatu = p.terms().len() - 1; @@ -231,7 +232,8 @@ pub fn run(p: &mut Prakriya, dhatu: &Dhatu) -> Result<()> { } p.maybe_save_sthanivat(); - try_add_prefixes(p, dhatu); + // Add upasargas now because certain gana-sUtras check for them. + try_add_prefixes(p, dhatu.prefixes()); // Update `i_dhatu` because we added upasargas above. let i_dhatu = p.terms().len() - 1; @@ -249,12 +251,7 @@ mod tests { fn check(text: &str, code: &str) -> Term { let (gana, _number) = code.split_once('.').expect("valid"); let gana: u8 = gana.parse().expect("ok"); - let dhatu = Dhatu::builder() - .upadesha(text) - .gana(gana.to_string().parse().expect("ok")) - .build() - .expect("ok"); - + let dhatu = Muladhatu::new(text, gana.to_string().parse().unwrap()); let mut p = Prakriya::new(); run(&mut p, &dhatu).expect("ok"); p.get(0).expect("ok").clone() diff --git a/vidyut-prakriya/src/dhatupatha.rs b/vidyut-prakriya/src/dhatupatha.rs index f34d94a..4cb62e7 100644 --- a/vidyut-prakriya/src/dhatupatha.rs +++ b/vidyut-prakriya/src/dhatupatha.rs @@ -15,6 +15,23 @@ pub struct Entry { } impl Entry { + fn parse(code: &str, upadesha: &str, artha: &str) -> Result { + let (gana, number) = code.split_once('.').ok_or(Error::InvalidFile)?; + let gana = if let Some(stripped) = gana.strip_prefix('0') { + stripped.parse()? + } else { + gana.parse()? + }; + let number = number.parse()?; + let dhatu = create_dhatu(upadesha, gana, number)?; + + Ok(Self { + code: code.to_string(), + dhatu, + artha: artha.to_string(), + }) + } + /// The numeric code for this entry. pub fn code(&self) -> &String { &self.code @@ -78,23 +95,6 @@ pub fn create_dhatu(upadesha: impl AsRef, gana: Gana, number: u16) -> Resul builder.build() } -fn create_entry(code: &str, upadesha: &str, artha: &str) -> Result { - let (gana, number) = code.split_once('.').ok_or(Error::InvalidFile)?; - let gana = if let Some(stripped) = gana.strip_prefix('0') { - stripped.parse()? - } else { - gana.parse()? - }; - let number = number.parse()?; - let dhatu = create_dhatu(upadesha, gana, number)?; - - Ok(Entry { - code: code.to_string(), - dhatu, - artha: artha.to_string(), - }) -} - impl Dhatupatha { /// Loads a dhatupatha from the provided TSV. /// @@ -112,25 +112,8 @@ impl Dhatupatha { /// # Ok::<(), Error>(()) /// ``` pub fn from_path(path: impl AsRef) -> Result { - let mut dhatus = Vec::new(); - let mut rdr = csv::ReaderBuilder::new().delimiter(b'\t').from_path(path)?; - for maybe_row in rdr.records() { - let r = maybe_row?; - let code = &r[0]; - let upadesha = &r[1]; - let artha = &r[2]; - - // If the upadesha is missing, this is a ganasutra -- skip. - if upadesha == "-" { - continue; - } - - let entry = create_entry(code, upadesha, artha)?; - dhatus.push(entry); - } - - dhatus.sort_by(|x, y| x.code.cmp(&y.code)); - Ok(Self(dhatus)) + let content = std::fs::read_to_string(path)?; + Self::from_text(&content) } /// Loads a dhatupatha from the input text string. @@ -169,7 +152,12 @@ impl Dhatupatha { None => return Err(Error::InvalidFile), }; - let entry = create_entry(code, upadesha, artha)?; + // If the upadesha is missing, this is a ganasutra -- skip. + if upadesha == "-" { + continue; + } + + let entry = Entry::parse(code, upadesha, artha)?; dhatus.push(entry); } @@ -217,8 +205,8 @@ mod tests { #[test] fn create_dhatu_basic() { let dhatu = create_dhatu("BU", Gana::Bhvadi, 1).unwrap(); - assert_eq!(dhatu.upadesha(), "BU"); - assert_eq!(dhatu.gana(), Gana::Bhvadi); + assert_eq!(dhatu.upadesha().unwrap(), "BU"); + assert_eq!(dhatu.gana().expect("ok"), Gana::Bhvadi); assert!(dhatu.prefixes().is_empty()); assert!(dhatu.sanadi().is_empty()); } @@ -226,8 +214,8 @@ mod tests { #[test] fn create_dhatu_with_ashas() { let dhatu = create_dhatu("SAsu~\\", Gana::Adadi, 23).unwrap(); - assert_eq!(dhatu.upadesha(), "SAsu~\\"); - assert_eq!(dhatu.gana(), Gana::Adadi); + assert_eq!(dhatu.upadesha().unwrap(), "SAsu~\\"); + assert_eq!(dhatu.gana().expect("ok"), Gana::Adadi); assert_eq!(dhatu.prefixes(), &vec!["AN"]); assert!(dhatu.sanadi().is_empty()); } diff --git a/vidyut-prakriya/src/dvitva.rs b/vidyut-prakriya/src/dvitva.rs index 17f7191..95559c1 100644 --- a/vidyut-prakriya/src/dvitva.rs +++ b/vidyut-prakriya/src/dvitva.rs @@ -45,7 +45,7 @@ fn try_dvitva_for_ajadi_dhatu(rule: Code, p: &mut Prakriya, i: usize) -> Option< third.add_tags(&[T::Dhatu]); let abhyasa = Term::make_text(&third.text); - p.set(i, |t| t.text.truncate(t.text.len() - abhyasa.text.len())); + p.set(i, |t| t.text.truncate(t.len() - abhyasa.len())); if p.has(i, |t| t.has_u("UrRuY")) { third.set_adi("n"); } @@ -101,11 +101,11 @@ fn find_abhyasa_span(text: &CompactString) -> Option<(usize, usize)> { fn try_dvitva_for_sanadi_ajadi(rule: Code, p: &mut Prakriya, i_dhatu: usize) -> Option<()> { let mut p_text = CompactString::from(""); for t in p.terms() { - if t.is_upasarga() { + if t.is_upasarga() || t.is_lupta() { continue; } if !t.sthanivat().is_empty() { - p_text.push_str(&t.sthanivat()); + p_text.push_str(t.sthanivat()); } else { p_text.push_str(&t.text); } @@ -115,7 +115,18 @@ fn try_dvitva_for_sanadi_ajadi(rule: Code, p: &mut Prakriya, i_dhatu: usize) -> // debug_assert!(start == 1); let ac = Term::make_text(&p_text[0..start]); - let abhyasa = Term::make_text(&p_text[start..=end]); + let mut abhyasa = Term::make_text(&p_text[start..=end]); + + // For OcicCat, etc. + // + // > hrasva eva atra āgamī, na tu tadantaḥ. tena cicchadatuḥ, cicchiduḥ ityatra + // > tukabhyāsasya grahaṇena na gṛhyate iti halādiḥśeṣeṇa na nivartyate, nāvayavāvayavaḥ + // > samudāyāvayavo bhavatīti. + // + // -- KV on 6.1.73. + if abhyasa.starts_with("tC") { + abhyasa.set_adi(""); + } let i_ac = i_dhatu; p.insert_before(i_ac, ac); @@ -165,10 +176,10 @@ fn try_dvitva(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { try_dvitva_for_sanadi_ajadi(rule, p, i); } else if dhatu.is_ekac() || al::is_hal(dhatu.adi()?) { let mut abhyasa = Term::make_text(""); - abhyasa.set_text(&dhatu.sthanivat()); + abhyasa.set_text(dhatu.sthanivat()); - // TODO: correctly double jAgR - if dhatu.text.starts_with("tC") { + // See comment above on 6.1.73 and removal of tuk-Agama. + if dhatu.starts_with("tC") { abhyasa.set_adi(""); } p.insert_before(i, abhyasa); diff --git a/vidyut-prakriya/src/ganapatha.rs b/vidyut-prakriya/src/ganapatha.rs index 37ecdf4..0d89057 100644 --- a/vidyut-prakriya/src/ganapatha.rs +++ b/vidyut-prakriya/src/ganapatha.rs @@ -13,9 +13,170 @@ pub const SARVA_ADI: &[&str] = &[ "Bavatu~", "kim", ]; +/// 1.1.38 svarAdi-nipAtam avyayam (2) +pub const SVAR_ADI: &[&str] = &[ + "svar", + "antar", + "prAtar", + "punar", + "sanutar", + "uccEs", + "nIcEs", + "SanEs", + "fDak", + "fte", + "yugapat", + "ArAt", + "antikAt", + "pfTak", + "hyas", + "Svas", + "divA", + "rAtrO", + "sAyam", + "ciram", + "manAk", + "Izat", + "SaSvat", + "jozam", + "tUzRIm", + "bahis", + "aDas", + "avas", + "samayA", + "nikazA", + "svayam", + "mfzA", + "naktam", + "naY", + "hetO", + "he", + "hE", + "idDA", + "adDA", + "sAmi", + "sanA", + "sanat", + "sanAt", + "upaDA", + "tiras", + "antarA", + "antareRa", + "mak", + "jyok", + "yok", + "nak", + "kam", + "Sam", + "sanA", + "sahasA", + "SradDA", + "alam", + "svaDA", + "vazaw", + "vinA", + "nAnA", + "svasti", + "anyat", + "asti", + "upAMSu", + "kzamA", + "vihAyasA", + "dozA", + "mfzA", + "muDA", + "dizwyA", + "vfTA", + "miTyA", + "purA", + "miTo", + "miTas", + "prAyas", + "muhus", + "pravAhukam", + "pravAhikA", + "Aryahalam", + "aBIkzRam", + "sAyam", + "sAkam", + "sArDam", + "sArTam", + "satram", + "samam", + "namas", + "hiruk", + "aTa", + "am", + "Am", + "pratAm", + "pratAn", + "praSAn", + "taTAhi", + "mA", + "mAN", + "Sram", + "kAmam", + "prakAmam", + "BUyas", + "param", + "sAkzAt", + "sAci", + "sAvi", + "satyam", + "maMkzu", + "saMvat", + "avaSyam", + "sapadi", + "prAdus", + "Avis", + "aniSam", + "nityam", + "nityadA", + "sadA", + "ajasram", + "santatam", + "uzA", + "om", + "BUr", + "Buvar", + "Jawiti", + "tarasA", + "suzWu", + "ku", + "aYjasA", + "a", + "miTu", + "amiTu", + "viTak", + "BAjak", + "anvak", + "cirAya", + "ciram", + "cirarAtrAya", + "cirasya", + "cireRa", + "cirAt", + "astam", + "Anuzak", + "anuzak", + "anuzaw", + "amnas", + "amBas", + "amnar", + "amBar", + "sTAne", + "varam", + "duzWu", + "balAt", + "Su", + "arvAk", + "Sudi", + "vadi", + "ityAdi", +]; + /// 1.4.57 cAdayo sattve (3) /// TODO: no cet, na cet -#[allow(dead_code)] pub const CA_ADI: &[&str] = &[ "ca", "vA", "ha", "aha", "eva", "evam", "nUnam", "SaSvat", "yugapat", "sUpat", "kUpat", "kuvit", "net", "cet", "caR", "kaccit", "yatra", "naha", "hanta", "mAkim", "nakim", "mAN", @@ -37,6 +198,80 @@ pub const PRA_ADI: &[&str] = &[ "api", "ati", "su", "ud", "aBi", "prati", "pari", "upa", ]; +/// 1.4.61 UryAdi-cvi-qAcaS ca (5) +pub const URI_ADI: &[&str] = &[ + "UrI", + "urarI", + "tanTI", + "tAlI", + "AttAlI", + "vetAlI", + "DUlI", + "DUsa", + "SakalA", + "saMSakalA", + "DvaMsakalA", + "BraMsakalA", + "guluguDA", + "sajUs", + "Pala", + "PalI", + "viklI", + "AklI", + "AlozWI", + "kevAlI", + "kevAsI", + "sevAsI", + "paryAlI", + "SevAlI", + "varzAlI", + "atyUmaSA", + "maSmaSA", + "masmasA", + "masamasA", + "Ozaw", + "SrOzaw", + "vOzaw", + "vazaw", + "svAhA", + "svaDA", + "vanDA", + "prAdus", + "Srat", + "Avis", +]; + +/// 1.4.64 sAkzAt-praBftIni ca (6) +pub const SAKSHAT_PRABHRTI: &[&str] = &[ + "sAkzAt", + "miTyA", + "cintA", + "BadrA", + "rocanA", + "AsTA", + "amA", + "SradDA", + "prAjaryA", + "prAjaruhA", + "bIjaryA", + "bIjaruhA", + "saMsaryA", + "arTe", + "lavaRam", + "uzRam", + "SItam", + "udakam", + "Ardram", + "agnO", + "vaSe", + "vihasane", + "prasahane", + "pratapane", + "prAdus", + "namas", + "Avis", +]; + /// 2.1.40 saptamI SORqEH (8) pub const SHAUNDA_ADI: &[&str] = &[ "SORqa", "DUrta", "kitava", "vyAqa", "pravIRa", "saMvIta", "antar", "aDi", "pawu", "paRqita", @@ -79,6 +314,54 @@ pub const YAJAKA_ADI: &[&str] = &[ "pattigaRaka", ]; +/// 3.1.11 BrzAdiByo Buvyacver lopaSca halaH (32) +pub const BHRSHA_ADI: &[&str] = &[ + "BfSa", + "SIGra", + "capala", + "manda", + "paRqita", + "utsuka", + "sumanas", + "durmanas", + "aBimanas", + "unmanas", + "rahas", + "rohat", + "rehat", + "saMScat", + "tfpat", + "SaSvat", + "Bramat", + "vehat", + "Sucis", + "Sucivarcas", + "aRqara", + "varcas", + "ojas", + "surajas", + "arajas", +]; + +/// 3.1.13 lohitAdi-qAj-ByaH kyaz (33) +pub const LOHITA_ADI: &[&str] = &[ + "lohita", "carita", "nIla", "Pena", "madra", "hari", "dAsa", "man", +]; + +/// 3.1.17 suKAdiByaH kartf-vedanAyAm (34) +pub const SUKHA_ADI: &[&str] = &[ + "suKa", "duHKa", "tfpta", "kfcCra", "asra", "Asra", "aloka", "pratIpa", "karuRa", "kfpaRa", + "so", +]; + +/// 3.1.27 kaRqvAdiByo yak (35) +pub const KANDU_ADI: &[&str] = &[ + "kaRqUY", "mantu", "hraRIY", "valgu", "astra", "manas", "mahIN", "lew", "low", "iras", "iraj", + "iraY", "dravas", "meDA", "kuzuBa", "magaDa", "tantas", "pampas", "suKa", "duHKa", "sapara", + "ara", "Bizaj", "BizRaj", "izuDa", "caraRa", "curaRa", "BuraRa", "turaRa", "gadgada", "elA", + "kelA", "KelA", "liw", "low", +]; + /// 4.1.4 ajAdyataz wAp (54) pub const AJA_ADI: &[&str] = &[ // jAti @@ -865,12 +1148,92 @@ pub const KHANDIKA_ADI: &[&str] = &[ "halabanDa", ]; -/// For 4.2.49. +/// 4.2.49 pASAdiByo yaH (74) pub const PASHA_ADI: &[&str] = &[ "pASa", "tfRa", "DUma", "vAta", "aNgAra", "pota", "bAlaka", "piwaka", "piwAka", "Sakawa", "hala", "naqa", "vana", ]; +/// 4.2.53 rAjyanAdiByo vuY (76) +pub const RAJANYA_ADI: &[&str] = &[ + "rAjanya", + "Anfta", + "bABravya", + "SAlaNkAyana", + "dEvayAtava", + "dEvayAta", + "vrIqa", + "varatra", + "jAlaMDarAyaRa", + "rAjAyana", + "telu", + "AtmakAmeya", + "ambarIzaputra", + "vasAti", + "bElvavana", + "SElUza", + "udumbara", + "tIvra", + "bElvala", + "ArjunAyana", + "saMpriya", + "dakzi", + "UrRanABa", +]; + +/// 4.2.54 BorikyAdyEzukAryAdiByo viDal-BaktalO (77) +pub const BHAURIKI_ADI: &[&str] = &[ + "BOriki", + "vEpeya", + "BOliki", + "cEpayata", + "cEwayata", + "kAReya", + "vARijaka", + "vARikAjya", + "vAlikAjya", + "sEkayata", + "vEkayata", +]; + +/// 4.2.54 BorikyAdyEzukAryAdiByo viDal-BaktalO (78) +pub const AISHUKARI_ADI: &[&str] = &[ + "EzukAri", + "sArasyAyana", + "sArasAyana", + "cAndrAyaRa", + "dvyAkzAyaRa", + "tryAkzAyaRa", + "OqAyana", + "jOlAyana", + "KAqAyana", + "dAsamitri", + "dAsamitrAyaRa", + "SOdrAyaRa", + "dAkzAyaRa", + "SayaRqAyana", + "SAyaRqAyana", + "tArkzyAyaRa", + "SOBrAyaRa", + "sOvIra", + "sOvIrAyaRa", + "SapaRqa", + "SayaRqa", + "SORqa", + "SayARqi", + "SayARqa", + "vESvamAnava", + "vESvaDyenava", + "vESvaDenava", + "naqa", + "tuRqadeva", + "viSvadeva", + "sApiRqi", +]; + +/// 4.2.61 kramAdiByo vun (78) +pub const KRAMA_ADI: &[&str] = &["krama", "pada", "SikzA", "mImAMsA", "sAman"]; + /// For 4.2.75. pub const SANKALA_ADI: &[&str] = &[ "saNkala", @@ -1294,6 +1657,43 @@ pub const GUDA_ADI: &[&str] = &[ "upavAsa", ]; +/// 5.1.2 u-gavAdiByo yat (146) +pub const GAVADI: &[&str] = &[ + "go", "havis", "akzara", "viza", "barhis", "azwakA", "svadA", "yuga", "meDA", "srac", "nABi", + "naBa", "kUpa", "Kada", "dara", "asura", "aDvan", "aDvana", "kzara", "veda", "bIja", "dIsa", + "dIpta", +]; + +/// 5.1.4 viBAzA havirapUpAdiByaH (147) +pub const APUPA_ADI: &[&str] = &[ + "apUpa", + "taRqula", + "aByuza", + "aByUza", + "aByoza", + "avoza", + "aByeza", + "pfTuka", + "odana", + "sUpa", + "pUpa", + "kiRva", + "pradIpa", + "musala", + "kawaka", + "karRavezwaka", + "irgala", + "argala", + "yUpa", + "sTURA", + "dIpa", + "aSva", + "patra", +]; + +/// 5.1.20 asamAse nizkAdiByaH (148) +pub const NISHKA_ADI: &[&str] = &["nizka", "paRa", "pAda", "mAza", "vAha", "droRa", "zazwi"]; + /// 5.1.66 daRqAdiByaH (152) pub const DANDA_ADI: &[&str] = &[ "daRqa", @@ -1413,6 +1813,108 @@ pub const TARAKA_ADI: &[&str] = &[ "garja", ]; +/// 5.2.61 vimuktAdiByo 'R (173) +pub const VIMUKTA_ADI: &[&str] = &[ + "vimukta", + "devAsura", + "rakzosura", + "upasad", + "suvarRa", + "parisAraka", + "sadasat", + "vasu", + "marut", + "patnIvat", + "vasumat", + "mahIyas", + "satvat", + "barhavat", + "daSArRa", + "daSArha", + "vayas", + "havirDAna", + "patatrin", + "mahitrI", + "asyahatya", + "somApUzan", + "iqA", + "agnAvizRU", + "urvaSI", + "vftrahan", +]; + +/// 5.2.62 gozadAdiByo vun (174) +pub const GOSHADA_ADI: &[&str] = &[ + "gozada", + "gozad", + "izetvA", + "mAtariSvan", + "devasyatvA", + "devIrApaH", + "kfzRa", + "devIMDiyA", + "devIMDiya", + "rakzohaRa", + "yuYjAna", + "aYjana", + "prasUta", + "praBUta", + "pratUrta", + "kfSAnu", + "kfSAku", +]; + +/// 5.2.64 AkarzAdiByaH kan (175) +pub const AKARSHA_ADI: &[&str] = &[ + "Akarza", + "Akaza", + "tsaru", + "piSAca", + "picaRqa", + "aSani", + "aSman", + "nicaya", + "caya", + "vijaya", + "jaya", + "Acaya", + "naya", + "pAda", + "dIpahrada", + "hrAda", + "hlAda", + "gadgada", + "Sakuni", +]; + +/// 5.2.95 rasAdiByaS ca (177) +pub const RASA_ADI: &[&str] = &[ + "rasa", "rUpa", "ganDa", "sparSa", "Sabda", "sneha", "guRAt", "ekAcaH", +]; + +// 5.2.97 siDmAdiByaS ca (178) +pub const SIDHMA_ADI: &[&str] = &[ + "siDma", "gaqu", "maRi", "nABi", "jIva", "nizpAva", "pAMsu", "saktu", "hanu", "mAMsa", "paraSu", +]; + +// 5.2.100 lomAdi-pAmAdi-picCAdiByaH SanelacaH (179) +pub const LOMA_ADI: &[&str] = &[ + "loman", "roman", "valgu", "baBrO", "hari", "kapi", "Suni", "taru", +]; + +// 5.2.100 lomAdi-pAmAdi-picCAdiByaH SanelacaH (180) +pub const PAMA_ADI: &[&str] = &[ + "pAman", "vAman", "heman", "Slezman", "kadru", "bali", "SrezWa", "palala", "sAman", +]; + +// 5.2.100 lomAdi-pAmAdi-picCAdiByaH SanelacaH (181) +pub const PICCHA_ADI: &[&str] = &[ + "picCa", "uras", "GruvakA", "kzuvakA", "varRa", "udaka", "paNka", "prajYA", +]; + +/// 5.2.117 tundAdiBya ilac ca (174) +pub const TUNDA_ADI: &[&str] = &["tunda", "udara", "picaRqa", "yava", "vrIhi"]; + /// 5.3.101 SAKAdiByo yat (191) pub const SHAKHA_ADI: &[&str] = &[ "SAKA", "muKa", "jaGana", "SfNga", "meGa", "caraRa", "skanDa", "Siras", "uras", "agra", @@ -1533,3 +2035,11 @@ pub const VINAYA_ADI: &[&str] = &[ "viSeza", "atyaya", ]; + +// 6.1.203 vfzAdInAM ca (210) +// TODO: SamaraRa +pub const VRSHA_ADI: &[&str] = &[ + "vfza", "jana", "jvara", "graha", "haya", "maya", "gaya", "tAya", "taya", "caya", "ama", + "veda", "sUda", "aMSa", "guhA", "mantra", "SAnti", "kAma", "yAma", "ArA", "DArA", "kArA", + "vaha", "kalpa", "pAda", +]; diff --git a/vidyut-prakriya/src/it_agama.rs b/vidyut-prakriya/src/it_agama.rs index 05cc11a..607b92f 100644 --- a/vidyut-prakriya/src/it_agama.rs +++ b/vidyut-prakriya/src/it_agama.rs @@ -102,13 +102,8 @@ impl<'a> ItPrakriya<'a> { /// Returns whether the term before the anga has an upasarga with one of the given values. fn has_upasarga_in(&self, values: &[&str]) -> bool { - if self.i_anga == 0 { - false - } else { - self.p.has(self.i_anga - 1, |t| { - t.has_text_in(values) && t.is_upasarga() - }) - } + self.p + .has_prev_non_empty(self.i_anga, |t| t.is_upasarga() && t.has_text_in(values)) } /// Inserts it-Agama and prevents further rules. @@ -301,11 +296,12 @@ fn run_valadau_ardhadhatuke_before_attva_for_term(ip: &mut ItPrakriya) -> Option } if !ip.done { - // The effect of 7.2.13 is that all other roots are considerd `sew` by + // The effect of 7.2.13 is that all other anudatta roots are considerd `sew` by // default. ip.p.step("7.2.13"); + let anga = ip.anga(); let n = ip.next(); - if n.has_adi(&*VAL) { + if n.has_adi(&*VAL) && anga.has_tag(T::Anudatta) { ip.try_add("7.2.35"); } } @@ -331,9 +327,7 @@ fn run_valadau_ardhadhatuke_before_attva_for_term(ip: &mut ItPrakriya) -> Option let rdhu_adi = &[ "fD", "Brasj", "danB", "Sri", "svf", "yu", "UrRu", "Bar", "jYap", ]; - if anga.text.ends_with("iv") - || anga.has_text_in(rdhu_adi) - || anga.has_u_in(&["zaRu~^", "zaRa~"]) + if anga.ends_with("iv") || anga.has_text_in(rdhu_adi) || anga.has_u_in(&["zaRu~^", "zaRa~"]) { // didevizati, dudyUzati; // ardiDizati, Irtsati; @@ -452,7 +446,7 @@ fn run_valadau_ardhadhatuke_before_attva_for_term(ip: &mut ItPrakriya) -> Option let has_parasmaipada = ip.p.has_tag(T::Parasmaipada); let se = n.has_adi('s'); - let krta_crta = &["kft", "cft", "Cfd", "tfd", "nft"]; + let krta_crta = &["kftI~", "cftI~", "u~Cfdi~^r", "u~tfdi~^r", "nftI~"]; let ishu_saha = &["izu~", "zaha~\\", "luBa~", "ruza~", "riza~"]; if ip.done { @@ -469,7 +463,8 @@ fn run_valadau_ardhadhatuke_before_attva_for_term(ip: &mut ItPrakriya) -> Option } } else if anga.has_u_in(ishu_saha) && n.has_adi('t') { ip.optional_try_block("7.2.48"); - } else if anga.has_text_in(krta_crta) && se && !n.has_u("si~c") { + } else if anga.has_u_in(krta_crta) && se && !n.has_u("si~c") { + // kartsyati, kartizyati, ... ip.optional_try_block("7.2.57"); } else if anga.has_text("gam") && has_parasmaipada && se { // gamizyati @@ -552,7 +547,7 @@ fn run_sarvadhatuke_for_term(ip: &mut ItPrakriya) -> Option<()> { let tin = n.last(); let rudh_adi = &["rudi~r", "Yizva\\pa~", "Svasa~", "ana~", "jakza~"]; - let is_aprkta = n.slice().iter().map(|t| t.text.len()).sum::() == 1; + let is_aprkta = n.slice().iter().map(|t| t.len()).sum::() == 1; if anga.has_u("a\\da~") && is_aprkta { op::insert_agama_at("7.3.100", ip.p, i_n, "aw"); } else if anga.has_u_in(rudh_adi) { diff --git a/vidyut-prakriya/src/it_samjna.rs b/vidyut-prakriya/src/it_samjna.rs index b2febe8..dca78b3 100644 --- a/vidyut-prakriya/src/it_samjna.rs +++ b/vidyut-prakriya/src/it_samjna.rs @@ -26,7 +26,11 @@ fn get_adi(s: &CompactString) -> Option { } fn is_cutu_exempt_taddhita(t: &Term) -> bool { - t.is_taddhita() && t.has_u_in(&["jAtIyar", "caraw", "cuYcup", "caRap"]) + t.is_taddhita() && t.has_u_in(&["jAtIyar", "caraw", "cuYcup", "caRap", "jAhac", "wIwac"]) +} + +fn is_lashaku_exempt(t: &Term) -> bool { + t.has_u_in(&["kAmyac"]) } /// Runs rule 1.3.2 ("upadeśe janunāsika iṭ"). @@ -90,7 +94,7 @@ fn run_1_3_2(p: &mut Prakriya, i_term: usize, before: &mut CompactString) -> Opt if before != &after { before.replace_range(.., &after); if should_mark_rule { - p.step("1.3.2"); + p.run_at("1.3.2", i_term, |_| {}); } } @@ -163,9 +167,8 @@ pub fn run(p: &mut Prakriya, i: usize) -> Result<()> { if vibhaktau_tusmah && !is_vibhakti_exception { p.step("1.3.4"); } else { - t.add_tag(T::parse_it(antya)?); + p.add_tag_at("1.3.3", i, T::parse_it(antya)?); temp.truncate(temp.len() - 1); - p.step("1.3.3"); } } } @@ -183,7 +186,7 @@ pub fn run(p: &mut Prakriya, i: usize) -> Result<()> { } } if matched { - p.step("1.3.5"); + p.run_at("1.3.5", i, |_| {}); } } } @@ -198,9 +201,8 @@ pub fn run(p: &mut Prakriya, i: usize) -> Result<()> { if t.is_unadi() && t.has_u_in(&["kan"]) { // Do nothing. } else if adi == 'z' { - t.add_tag(T::parse_it(adi)?); temp_slice = &temp_slice[1..]; - p.step("1.3.6") + p.add_tag_at("1.3.6", i, T::parse_it(adi)?); } else if CUTU.contains(adi) && !is_cutu_exempt_taddhita(t) { // The sounds C, J, W, and Q are replaced later in the grammar. // If we substitute them now, those rules will become vyartha. @@ -209,16 +211,15 @@ pub fn run(p: &mut Prakriya, i: usize) -> Result<()> { temp_slice = &temp_slice[1..]; } p.step("1.3.7"); - } else if !t.has_tag(T::Taddhita) && t.has_adi(&*LASHAKU) { + } else if !t.has_tag(T::Taddhita) && t.has_adi(&*LASHAKU) && !is_lashaku_exempt(t) { // Keep the first "l" of the lakAras. // Otherwise, rule 3.4.77 will become vyartha. const LAKARAS: &[&str] = &[ "la~w", "li~w", "lu~w", "lf~w", "le~w", "lo~w", "la~N", "li~N", "lu~N", "lf~N", ]; if !t.has_u_in(&LAKARAS) { - t.add_tag(T::parse_it(adi)?); temp_slice = &temp_slice[1..]; - p.step("1.3.8"); + p.add_tag_at("1.3.8", i, T::parse_it(adi)?); } } } @@ -226,11 +227,12 @@ pub fn run(p: &mut Prakriya, i: usize) -> Result<()> { if let Some(t) = p.get_mut(i) { if temp_slice != t.text { - t.text.replace_range(.., temp_slice); - if t.has_tag(T::zit) && t.text.starts_with('w') { - t.text.replace_range(..1, "t"); - } - p.step("1.3.9") + p.run_at("1.3.9", i, |t| { + t.set_text(temp_slice); + if t.has_tag(T::zit) && t.has_adi('w') { + t.set_adi("t"); + } + }); } } diff --git a/vidyut-prakriya/src/krt.rs b/vidyut-prakriya/src/krt.rs index 88a87a2..c24cfbc 100644 --- a/vidyut-prakriya/src/krt.rs +++ b/vidyut-prakriya/src/krt.rs @@ -1,11 +1,11 @@ -use crate::args::KrdantaArgs; +use crate::args::Krdanta; use crate::core::Prakriya; mod basic; mod unadi_sutras; mod utils; -pub fn run(p: &mut Prakriya, args: &KrdantaArgs) -> bool { +pub fn run(p: &mut Prakriya, args: &Krdanta) -> bool { // First, check if the pratyaya is an unAdi-pratyaya. let mut added = unadi_sutras::run(p, args.krt()); if !added { diff --git a/vidyut-prakriya/src/krt/basic.rs b/vidyut-prakriya/src/krt/basic.rs index d291b36..e9f9184 100644 --- a/vidyut-prakriya/src/krt/basic.rs +++ b/vidyut-prakriya/src/krt/basic.rs @@ -62,14 +62,13 @@ use crate::args::KrtArtha::*; use crate::args::Taddhita; use crate::args::{BaseKrt, Krt}; use crate::core::operators as op; -use crate::core::Tag as T; -use crate::core::Term; -use crate::core::{Prakriya, Rule}; +use crate::core::{Prakriya, Rule, Tag as T, Term}; use crate::dhatu_gana as gana; use crate::it_samjna; use crate::krt::utils::KrtPrakriya; use crate::sounds::{s, Set}; use crate::stem_gana::TYAD_ADI; +use crate::Rule::Varttika; use lazy_static::lazy_static; lazy_static! { @@ -200,10 +199,13 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { // Per commentaries, allow only this specific `vid`. kp.try_add("3.2.162", kurac); } else if dhatu.has_u("i\\R") || dhatu.has_text_in(&["naS", "ji", "sf"]) { + // naSvara, ... kp.try_add("3.2.163", kvarap); } else if dhatu.has_text("jAgf") { + // jAgarUka kp.try_add("3.2.165", Uka); } else if dhatu.has_text_in(&["yaj", "jap", "daS"]) && has_yan { + // yAyajUka, ... kp.try_add("3.2.166", Uka); } else if dhatu.has_text_in(&["nam", "kanp", "smi", "jas", "kam", "hins", "dIp"]) { kp.try_add("3.2.167", ra); @@ -211,11 +213,12 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { kp.try_add("3.2.168", u); } else if dhatu.has_text_in(&["svap", "tfz"]) { kp.try_add("3.2.172", najiN); - } else if dhatu.has_text_in(&["Sf", "vand"]) { + } else if dhatu.has_text_in(&["SF", "vand"]) { + // SarAru, vandAru kp.try_add("3.2.173", Aru); } else if dhatu.has_text("BI") { if kp.expects_krt(kruka) { - kp.try_add("3.2.174.v1", kruka); + kp.try_add(Varttika("3.2.174", "1"), kruka); } else if kp.expects_krt(kru) { kp.try_add("3.2.174", kru); } else { @@ -458,6 +461,10 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { kp.try_add("3.3.120", GaY); } else if dhatu.has_u("Kanu~^") { kp.optional_try_add("3.3.125", Ga); + kp.optional_try_add(Varttika("3.3.125", "1"), qa); + kp.optional_try_add(Varttika("3.3.125", "2"), qara); + kp.optional_try_add(Varttika("3.3.125", "3"), ika); + kp.optional_try_add(Varttika("3.3.125", "4"), ikavaka); } // Base case @@ -528,7 +535,7 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { }; let nau = kp.p.has(i_dhatu + 1, |t| t.has_u("Ric")); - let upasarge = i_dhatu > 0 && kp.p.has(i_dhatu - 1, |t| t.is_upasarga()); + let upasarge = kp.p.has_prev_non_empty(i_dhatu, |t| t.is_upasarga()); match krt { aR | ka | ac | wa | wak => { @@ -551,7 +558,7 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { && dhatu.has_u("pA\\") && dhatu.has_gana(Gana::Bhvadi) { - kp.try_add("3.2.8.v1", wak); + kp.try_add(Varttika("3.2.8", "1"), wak); } else if dhatu.has_u("hf\\Y") { if kp.has_upapada("AN") { // tAcCIlye @@ -564,10 +571,10 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { if upapada.has_text_in(&[ "Sakti", "lANgala", "aNkuSa", "yazwi", "tomara", "Gawa", "GaWI", "Danus", ]) { - kp.try_add("3.2.9.v1", ac); + kp.try_add(Varttika("3.2.9", "1"), ac); } else if upapada.has_text("sUtra") { // dhAri-arthe - kp.optional_try_add("3.2.9.v2", ac); + kp.optional_try_add(Varttika("3.2.9", "2"), ac); } } else if !upasarge && dhatu.has_antya('A') { kp.try_add("3.2.3", ka); @@ -777,6 +784,8 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { kvin | kaY => { if upapada.has_text_in(TYAD_ADI) && dhatu.has_u("df\\Si~r") { kp.try_add("3.2.60", krt); + } else if upapada.has_text_in(&["samAna", "anya"]) && dhatu.has_u("df\\Si~r") { + kp.try_add(Varttika("3.2.60", "1"), krt); } else if krt == kvin { if !upapada.has_text("udaka") && dhatu.has_text("spfS") { kp.try_add("3.2.58", kvin); @@ -795,13 +804,7 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { } else if kp.has_upapada("ud") && dhatu.has_u("zRi\\ha~") { kp.do_nipatana(code, "uzRih"); } else if dhatu.has_u("ancu~") { - kp.p.run_at(code, i_dhatu, |t| { - t.set_text("aYc"); - t.add_tag(T::Krt); - }); - // HACK: update bookkeeping here. - kp.has_krt = true; - kp.had_match = true; + kp.try_add(code, kvin); } else if dhatu.has_u("yu\\ji~^r") { kp.do_nipatana(code, "yuj"); } else if dhatu.has_u("krunca~") { @@ -812,7 +815,10 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { } viw => { - if dhatu.has_u("a\\da~") { + if dhatu.has_u_in(&["janI~\\", "zaRu~^", "Kanu~^", "kramu~", "ga\\mx~"]) { + // abjAH, ... + kp.try_add("3.2.67", krt); + } else if dhatu.has_u("a\\da~") { if upapada.has_text("kravya") { kp.try_add("3.2.69", krt); } else if !upapada.has_text("anna") { @@ -874,7 +880,7 @@ fn try_add_upapada_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { if dhatu.has_text("Sri") { // SrI // TODO: others - kp.p.run_at("3.2.178.v1", i_dhatu, |t| t.set_antya("I")); + kp.p.run_at(Varttika("3.2.178", "1"), i_dhatu, |t| t.set_antya("I")); } } @@ -913,11 +919,10 @@ fn try_add_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { use BaseKrt as K; let i = p.find_last(T::Dhatu)?; - let prev = if i > 0 { p.get(i - 1) } else { None }; // Pre-calculate some common properties. - let upasarge = prev.map_or(false, |t| t.is_upasarga()); - let supi = prev.map_or(false, |t| t.has_tag(T::Sup)); + let upasarge = i > 1 && p.has(i - 2, |t| t.is_upasarga()); + let supi = i > 0 && p.has(i - 1, |t| t.is_sup()); // For convenience below, wrap `Prakriya` in a new `KrtPrakriya` type that contains `krt` and // records whether or not any of these rules were applied. @@ -933,7 +938,7 @@ fn try_add_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { let added = kp.try_add("3.1.96", krt); if added && krt == K::tavyat && kp.dhatu().has_u("va\\sa~") { // vAstavya - kp.p.optional_run_at("3.1.96.v1", i + 1, |t| t.add_tag(T::Rit)); + kp.p.optional_run_at(Varttika("3.1.96", "1"), i + 1, |t| t.add_tag(T::Rit)); } } @@ -980,7 +985,7 @@ fn try_add_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { } else if dhatu.has_u_in(&["gada~", "madI~", "cara~", "ya\\ma~"]) && !upasarge { kp.try_add("3.1.100", K::yat); } else if dhatu.has_u("cara~") && kp.has_upapada("AN") { - kp.optional_try_add("3.1.100.v1", K::yat); + kp.optional_try_add(Varttika("3.1.100", "1"), K::yat); } else if !upasarge && dhatu.has_text("vad") && supi { kp.try_add("3.1.106", K::yat); kp.try_add("3.1.106", K::kyap); @@ -1024,7 +1029,7 @@ fn try_add_krt(p: &mut Prakriya, krt: BaseKrt) -> Option { // Sapya, laBya, japya kp.try_add("3.1.98", K::yat); } else if dhatu.has_u_in(&["taka~", "Sasu~\\", "cate~^", "yatI~\\", "janI~\\"]) { - kp.try_add("3.1.97.v1", K::yat); + kp.try_add(Varttika("3.1.97", "1"), K::yat); } else if dhatu.has_antya('f') || dhatu.has_antya('F') || dhatu.has_antya(&*HAL) { kp.try_add("3.1.124", K::Ryat); } else if dhatu.has_antya(&*AC) { @@ -1390,92 +1395,3 @@ pub fn run(p: &mut Prakriya, krt: Krt) -> bool { false } } - -#[cfg(test)] -#[allow(clippy::unwrap_used)] -mod tests { - use super::*; - use crate::args::{Dhatu, Gana}; - use crate::dhatu_karya; - - fn make_prakriya(dhatu: &str) -> Prakriya { - let dhatu = Dhatu::new(dhatu, Gana::Bhvadi); - let mut p = Prakriya::new(); - dhatu_karya::run(&mut p, &dhatu).unwrap(); - - p - } - - fn allows(dhatu: &str, krt: impl Into) -> bool { - let krt = krt.into(); - let mut p = make_prakriya(dhatu); - run(&mut p, krt); - p.terms().last().unwrap().has_u(krt.as_str()) - } - - #[test] - fn test_common_pratyayas() { - use BaseKrt::*; - - assert!(allows("BU", tavyat)); - assert!(allows("BU", tavya)); - assert!(allows("BU", anIyar)); - assert!(allows("BU", Rvul)); - assert!(allows("BU", tfc)); - assert!(allows("BU", kta)); - assert!(allows("BU", ktavatu)); - assert!(allows("BU", ktvA)); - assert!(allows("BU", lyuw)); - assert!(allows("BU", tumun)); - - assert!(allows("BU", ktin)); - - assert!(allows("BU", GaY)); - } - - #[test] - fn test_ya_pratyaya() { - use BaseKrt::*; - - assert!(allows("BU", yat)); - // Allowed by "or AvAzyake" - assert!(allows("BU", Ryat)); - - assert!(allows("gada~", yat)); - assert!(!allows("gada~", Ryat)); - - assert!(allows("Sa\\kx~", yat)); - assert!(!allows("Sa\\kx~", Ryat)); - - assert!(allows("a\\da~", Ryat)); - assert!(!allows("a\\da~", yat)); - } - - #[test] - fn test_tacchila() { - use BaseKrt::*; - - // 3.2.161 - assert!(allows("sf\\", kmarac)); - assert!(allows("Gasx~", kmarac)); - assert!(allows("a\\da~", kmarac)); - assert!(!allows("sf\\", tfn)); - - // 3.2.162 - assert!(allows("Ba\\njo~", Gurac)); - assert!(allows("BAsf~\\", Gurac)); - assert!(allows("YimidA~\\", Gurac)); - assert!(!allows("Ba\\njo~", tfn)); - - // 3.2.173 - assert!(allows("Sf", Aru)); - assert!(allows("vadi~\\", Aru)); - assert!(!allows("Sf", tfn)); - - // 3.2.174 - assert!(allows("YiBI\\", kru)); - assert!(allows("YiBI\\", kruka)); - assert!(allows("YiBI\\", klukan)); - assert!(!allows("YiBI\\", tfn)); - } -} diff --git a/vidyut-prakriya/src/krt/unadi_sutras.rs b/vidyut-prakriya/src/krt/unadi_sutras.rs index cf1a718..ebdf47c 100644 --- a/vidyut-prakriya/src/krt/unadi_sutras.rs +++ b/vidyut-prakriya/src/krt/unadi_sutras.rs @@ -244,6 +244,13 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Unadi) -> Option { kp.try_add(UP("2.25"), krt); } } + U::ati => { + if dhatu.has_text_in(&["mah"]) { + kp.try_add_with(UP("2.84"), krt, |p| { + p.set(i_dhatu + 1, |t| t.add_tags(&[T::Sit, T::fdit])); + }); + } + } U::isi => { if dhatu.has_u_in(&["arca~", "I~Suci~^r", "hu\\", "sf\\px~", "Cada~", "Carda~"]) { kp.try_add(UP("2.108"), krt); @@ -310,7 +317,7 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Unadi) -> Option { kp.try_add_with(UP("3.127"), krt, mark_as(T::zit)); // rohanta, nadanta ... } else if dhatu - .has_text_in(&["tF", "BU", "vah", "vas", "BAs", "sAD", "gaRq", "maRq", "ji"]) + .has_text_in(&["tF", "BU", "vah", "vas", "BAs", "sAD", "ganq", "manq", "ji"]) { // taranta, Bavanta, ... // TODO: nandayanta @@ -437,6 +444,15 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Unadi) -> Option { kp.try_add_with(UP("4.12"), krt, set_antya("T")); } } + U::ni => { + if dhatu.has_u_in(&["anga"]) { + // agni + kp.try_add_with(UP("4.50"), krt, |p| { + let i_last = p.terms().len() - 1; + p.set(i_last, |t| t.find_and_replace_text("n", "")) + }); + } + } U::kvin => { if dhatu.has_u_in(&["jF", "SFY", "stFY", "jAgf"]) { kp.try_add(UP("4.54"), krt); diff --git a/vidyut-prakriya/src/krt/utils.rs b/vidyut-prakriya/src/krt/utils.rs index eb0d2a3..eb15246 100644 --- a/vidyut-prakriya/src/krt/utils.rs +++ b/vidyut-prakriya/src/krt/utils.rs @@ -75,23 +75,31 @@ impl<'a> KrtPrakriya<'a> { self.p.get(i).expect("present") } + fn i_upapada(&self) -> Option { + self.p.find_prev_where(self.i_dhatu, |t| !t.is_empty()) + } + /// Returns a reference to the underlying upapada, if present. pub fn upapada(&self) -> Option<&Term> { - if self.i_dhatu > 0 { - self.p.get(self.i_dhatu - 1) - } else { - None - } + self.p.get(self.i_upapada()?) } /// Returns whether the term before the dhatu has the given upapada. pub fn has_upapada(&self, upadesha: &str) -> bool { - self.i_dhatu > 0 && self.p.has(self.i_dhatu - 1, |t| t.has_u(upadesha)) + if let Some(i_upapada) = self.i_upapada() { + self.p.has(i_upapada, |t| t.has_u(upadesha)) + } else { + false + } } /// Returns whether the term before the dhatu has one of the given upapada values. pub fn has_upapada_in(&self, upadeshas: &[&str]) -> bool { - self.i_dhatu > 0 && self.p.has(self.i_dhatu - 1, |t| t.has_u_in(upadeshas)) + if let Some(i_upapada) = self.i_upapada() { + self.p.has(i_upapada, |t| t.has_u_in(upadeshas)) + } else { + false + } } pub fn expects_krt(&self, krt: impl Into) -> bool { @@ -128,20 +136,22 @@ impl<'a> KrtPrakriya<'a> { } pub fn has_upasarga_dhatu(&self, i_dhatu: usize, upa: &str, dhatu: &str) -> bool { - i_dhatu > 0 - && self.p.has(i_dhatu - 1, |t| t.has_u(upa)) - && self.p.has(i_dhatu, |t| t.has_u(dhatu)) + if let Some(i_upapada) = self.i_upapada() { + self.p.has(i_upapada, |t| t.has_u(upa)) && self.p.has(i_dhatu, |t| t.has_u(dhatu)) + } else { + false + } } pub fn has_prefixes(&self, values: &[&str; 2]) -> bool { - match self.p.find_last_where(|t| !t.is_dhatu()) { - Some(i) => { - i > 0 - && self.p.has(i - 1, |t| t.has_text(values[0])) - && self.p.has(i, |t| t.has_text(values[1])) + if let Some(i_upapada) = self.i_upapada() { + let i_before = self.p.find_prev_where(i_upapada, |t| !t.is_empty()); + if let Some(i_before) = i_before { + return self.p.has(i_before, |t| t.has_text(values[0])) + && self.p.has(i_upapada, |t| t.has_text(values[1])); } - None => false, } + false } /// If there's a match, adds the given `krt` pratyaya. @@ -214,6 +224,8 @@ impl<'a> KrtPrakriya<'a> { let rule = rule.into(); let krt = krt.into(); + self.p.debug(format!("try_add: {:?} --> {krt:?}", rule)); + self.had_match = true; if self.krt == krt && !self.has_krt { // Insert term with it-samjna-prakarana. diff --git a/vidyut-prakriya/src/lib.rs b/vidyut-prakriya/src/lib.rs index 784603b..5255f1f 100644 --- a/vidyut-prakriya/src/lib.rs +++ b/vidyut-prakriya/src/lib.rs @@ -26,7 +26,13 @@ pub mod private { mod core; mod sounds; -// Rules +/// Other texts. +mod ganapatha; +mod linganushasanam; +mod phit_sutraani; +mod sutrapatha; + +// Components of the sutrapatha. mod ac_sandhi; mod angasya; mod ardhadhatuka; @@ -36,12 +42,10 @@ mod atmanepada; mod dhatu_gana; mod dhatu_karya; mod dvitva; -mod ganapatha; mod it_agama; mod it_samjna; mod krt; mod la_karya; -mod linganushasanam; mod misc; mod pratipadika_karya; mod samasa; @@ -51,7 +55,7 @@ mod sanadi; mod stem_gana; mod stritva; mod sup_karya; -mod sutrapatha; +mod svara; mod taddhita; mod tin_pratyaya; mod tripadi; diff --git a/vidyut-prakriya/src/misc.rs b/vidyut-prakriya/src/misc.rs index 06cfe8c..c3156bd 100644 --- a/vidyut-prakriya/src/misc.rs +++ b/vidyut-prakriya/src/misc.rs @@ -21,7 +21,7 @@ pub fn run_pad_adi(p: &mut Prakriya) -> Option<()> { t.is_vibhakti() && !t.is_lupta() && !t.has_u_in(&["su~", "O", "jas", "am", "Ow"]) - && t.u != None + && t.u.is_some() }); if is_shas_prabhrti { diff --git a/vidyut-prakriya/src/phit_sutraani.rs b/vidyut-prakriya/src/phit_sutraani.rs new file mode 100644 index 0000000..f2f4401 --- /dev/null +++ b/vidyut-prakriya/src/phit_sutraani.rs @@ -0,0 +1,24 @@ +use crate::core::term::Svara; +use crate::core::{Prakriya, Rule}; + +fn run_at(p: &mut Prakriya, i: usize) -> Option<()> { + use Rule::Phit as P; + use Svara::*; + + let num_vowels = p.get(i)?.num_vowels(); + + p.run_at(P("1.1"), i, |t| t.set_svara(Udatta(num_vowels - 1))); + + Some(()) +} + +/// Runs the rules of the Phit-sutras. +pub fn run(p: &mut Prakriya) { + for i in 0..p.terms().len() { + if p.has(i, |t| t.is_pratipadika() && !t.is_pratyaya()) + && !p.has(i + 1, |t| t.is_taddhita()) + { + run_at(p, i); + } + } +} diff --git a/vidyut-prakriya/src/pratipadika_karya.rs b/vidyut-prakriya/src/pratipadika_karya.rs index ac4c5d2..d7910dc 100644 --- a/vidyut-prakriya/src/pratipadika_karya.rs +++ b/vidyut-prakriya/src/pratipadika_karya.rs @@ -1,74 +1,37 @@ -use crate::args::Pratipadika; -use crate::args::SamasaArgs; -use crate::args::Vibhakti; use crate::core::operators as op; use crate::core::Prakriya; use crate::core::Tag as T; use crate::core::Term; use crate::sounds as al; -/// Appends a pratipadika to the prakriya. -/// -/// Scope: subantas, taddhitas -pub fn add_one(p: &mut Prakriya, pratipadika: &Pratipadika) { - p.extend(pratipadika.terms()); +/// FOO +pub fn add_string(p: &mut Prakriya, text: &str, nyap: bool) { + let mut base = Term::make_upadesha(text); + // HACK: old implemenation of `Pratipadika` has these tags, so keep them here for consistency + // for now. + if nyap { + base.add_tags(&[T::Stri, T::StriNyap]); + } + p.push(base); // HACK: Add a dummy pratyaya so rules pass. // TODO: see if we can delete `is_nyap`. - if pratipadika.needs_nyap() { - let sub = if pratipadika - .terms() - .last() - .map_or(false, |t| t.has_antya('I')) - { - "NIp" + if nyap { + let last = p.terms().last(); + let u = if let Some(t) = last { + match t.antya() { + Some('I') => "NIp", + Some('U') => "UN", + _ => "wAp", + } } else { "wAp" }; - let mut nyap = Term::make_upadesha(sub); - nyap.add_tags(&[T::Pratyaya, T::StriNyap]); + let mut nyap = Term::make_upadesha(u); + nyap.add_tags(&[T::Pratyaya, T::StriNyap, T::Stri]); nyap.set_text(""); p.push(nyap); } - - add_samjnas(p); -} - -/// Appends multiple pratipadikas to the prakriya. -/// -/// Scope: samasas -pub fn add_all(p: &mut Prakriya, args: &SamasaArgs) { - // Initialize the prakriya by adding all items with dummy sup-pratyayas in between. - for pada in args.padas() { - for t in pada.pratipadika().terms() { - p.push(t.clone()); - } - if pada.is_avyaya() { - p.terms_mut().last_mut().expect("ok").add_tag(T::Avyaya); - } - p.push(make_sup_pratyaya(pada.vibhakti())); - } - // Remove the trailing sup-pratyaya. - p.terms_mut().pop(); - - add_samjnas(p); -} - -/// Assigns the pratipadika-samjna to all matching terms in the prakriya. -fn add_samjnas(p: &mut Prakriya) -> Option<()> { - for i in 0..p.terms().len() { - let t = p.get(i)?; - - if t.is_krt() || t.is_taddhita() || t.is_samasa() { - p.add_tag_at("1.2.46", i, T::Pratipadika); - } else if !t.is_dhatu() && !t.is_pratyaya() && !t.is_agama() && !t.is_abhyasa() { - // 1.2.45 specifies "arthavat", so exclude meaningless terms (agamas and abhyasas). - // TODO: is there anything else that's not arthavat? - p.add_tag_at("1.2.45", i, T::Pratipadika); - } - } - - Some(()) } /// Runs rurles specific to napumsaka-pratipadikas. @@ -83,24 +46,3 @@ pub fn run_napumsaka_rules(p: &mut Prakriya) -> Option<()> { } None } - -/// Creates a dummy sup-pratyaya. -/// -/// Scope: samasas -fn make_sup_pratyaya(vibhakti: Vibhakti) -> Term { - use Vibhakti::*; - let (u, vibhakti) = match vibhakti { - Prathama | Sambodhana => ("su~", T::V1), - Dvitiya => ("am", T::V2), - Trtiya => ("wA", T::V3), - Caturthi => ("Ne", T::V4), - Panchami => ("Nasi", T::V5), - Sasthi => ("Nas", T::V6), - Saptami => ("Ni", T::V7), - }; - - let mut su = Term::make_upadesha(u); - su.set_text(""); - su.add_tags(&[T::Pratyaya, T::Sup, T::Vibhakti, T::Pada, vibhakti]); - su -} diff --git a/vidyut-prakriya/src/samasa.rs b/vidyut-prakriya/src/samasa.rs index 4f1ed64..e5d79c8 100644 --- a/vidyut-prakriya/src/samasa.rs +++ b/vidyut-prakriya/src/samasa.rs @@ -1,10 +1,11 @@ -use crate::args::SamasaArgs; +use crate::args::Samasa; use crate::args::SamasaType; use crate::core::operators as op; use crate::core::Tag as T; use crate::core::{Prakriya, Rule}; use crate::core::{Term, TermView}; use crate::ganapatha as gana; +use crate::it_samjna; // 2.1.3 samAsaH // 2.1.4 saha supA @@ -41,7 +42,7 @@ impl<'a> SamasaPrakriya<'a> { self.mark_as_type(rule.into(), T::Bahuvrihi); } - fn mark_dvandva(&mut self, rule: impl Into, args: &SamasaArgs) { + fn mark_dvandva(&mut self, rule: impl Into, args: &Samasa) { let is_samahara = args.is_samahara_dvandva(); self.p.run(rule, |p| { p.add_tag(T::Dvandva); @@ -54,7 +55,7 @@ impl<'a> SamasaPrakriya<'a> { } } -impl SamasaArgs { +impl Samasa { fn is_avyayibhava(&self) -> bool { self.samasa_type() == SamasaType::Avyayibhava } @@ -147,6 +148,24 @@ impl<'a> TermView<'a> { } } +impl Prakriya { + pub(crate) fn is_trtiya_tatpurusha(&self) -> bool { + self.has_tag(T::Tatpurusha) && self.find_first(T::V3).is_some() + } + + pub(crate) fn is_caturthi_tatpurusha(&self) -> bool { + self.has_tag(T::Tatpurusha) && self.find_first(T::V4).is_some() + } + + pub(crate) fn is_panchami_tatpurusha(&self) -> bool { + self.has_tag(T::Tatpurusha) && self.find_first(T::V5).is_some() + } + + pub(crate) fn is_saptami_tatpurusha(&self) -> bool { + self.has_tag(T::Tatpurusha) && self.find_first(T::V7).is_some() + } +} + fn make_su_pratyaya() -> Term { let mut su = Term::make_upadesha("su~"); su.set_text(""); @@ -157,7 +176,7 @@ fn make_su_pratyaya() -> Term { /// Decides on the samasa type that best applies to `p`. /// /// Returns: whether or not `p` contains a samasa. -fn decide_samasa_type(p: &mut Prakriya, args: &SamasaArgs) -> Option { +fn decide_samasa_type(p: &mut Prakriya, args: &Samasa) -> Option { let mut sp = SamasaPrakriya::new(p); let purva = TermView::pratipadika_view(sp.p, 0)?; @@ -242,7 +261,18 @@ fn decide_samasa_type(p: &mut Prakriya, args: &SamasaArgs) -> Option { } else if uttara.has_text_in(&["apeta", "apoQa", "mukta", "patita", "apatrasta"]) { // suKApeta, ... sp.mark_tatpurusha("2.1.38"); - } else if purva.has_text_in(&["stoka", "antika", "dUra", "kfcCra"]) && uttara.is_kta() { + } else if purva.has_text_in(&[ + // From the rule + "stoka", + "antika", + "dUra", + "kfcCra", + // From commentaries + "alpa", + "aByASa", + "viprakfzwa", + ]) && uttara.is_kta() + { // stokAnmukta, ... sp.mark_tatpurusha("2.1.39"); } @@ -261,6 +291,9 @@ fn decide_samasa_type(p: &mut Prakriya, args: &SamasaArgs) -> Option { } else { sp.mark_tatpurusha("2.1.45"); } + } else { + // TODO: mark samjna + sp.mark_tatpurusha("2.1.44"); } } else if args.is_karmadharaya() { if purva.has_text_in(&["eka", "sarva", "jarat", "purARa", "nava", "kevala"]) { @@ -312,7 +345,10 @@ fn decide_samasa_type(p: &mut Prakriya, args: &SamasaArgs) -> Option { } else { sp.mark_tatpurusha("2.1.57"); } - } else if purva.has_text("naY") { + } else if uttara.has_text("ahan") { + // sAyAhna, ... + sp.mark_tatpurusha("2.2.1"); + } else if purva.has_u("naY") { // abrAhmaRa, ... sp.mark_tatpurusha("2.2.6"); } else if purva.has_text("Izat") && !uttara.is_krt() { @@ -337,35 +373,48 @@ fn decide_samasa_type(p: &mut Prakriya, args: &SamasaArgs) -> Option { Some(sp.done) } -pub fn run(p: &mut Prakriya, args: &SamasaArgs) -> bool { - let res = decide_samasa_type(p, args); - match res { - Some(true) => (), - _ => return false, - } - - if p.has_tag(T::Tatpurusha) && args.is_karmadharaya() { - p.run("1.2.42", |p| p.add_tag(T::Karmadharaya)); - } - - let i_last = p.terms().len() - 1; - for i in 0..=i_last { - if p.has(i, |t| t.is_sup()) { - p.run_at("2.4.71", i, op::luk); +pub fn try_sup_luk(p: &mut Prakriya) -> Option<()> { + let i_end = p.find_last_where(|t| t.is_samasa())?; + for i in 0..i_end { + let t = p.get(i)?; + if t.is_sup() { + if t.has_tag(T::Aluk) { + it_samjna::run(p, i).expect("ok"); + } else { + p.run_at("2.4.71", i, op::luk); + } } } + Some(()) +} + +pub fn run_rules_for_avyayibhava(p: &mut Prakriya) { if p.has_tag(T::Avyayibhava) { p.run("2.4.17", |p| p.add_tag(T::Napumsaka)); let i_last = p.terms().len() - 1; - p.run("4.1.2", |p| p.push(make_su_pratyaya())); - if p.has(i_last, |t| t.has_antya('a')) { - p.run_at("2.4.83", i_last + 1, |t| t.set_text("am")); - } else { - p.run_at("2.4.82", i_last + 1, op::luk); + if p.has(i_last, |t| !t.is_sup()) { + p.run("4.1.2", |p| p.push(make_su_pratyaya())); + if p.has(i_last, |t| t.has_antya('a')) { + p.run_at("2.4.83", i_last + 1, |t| t.set_text("am")); + } else { + p.run_at("2.4.82", i_last + 1, op::luk); + } } } +} + +pub fn run(p: &mut Prakriya, args: &Samasa) -> bool { + let res = decide_samasa_type(p, args); + match res { + Some(true) => (), + _ => return false, + } + + if p.has_tag(T::Tatpurusha) && args.is_karmadharaya() { + p.run("1.2.42", |p| p.add_tag(T::Karmadharaya)); + } true } diff --git a/vidyut-prakriya/src/samjna.rs b/vidyut-prakriya/src/samjna.rs index ae3c5cc..e20033a 100644 --- a/vidyut-prakriya/src/samjna.rs +++ b/vidyut-prakriya/src/samjna.rs @@ -1,8 +1,9 @@ +//! Rules that add various samjnas (labels) to the terms in the grammar. use crate::core::operators as op; use crate::core::Prakriya; use crate::core::Tag as T; use crate::core::Term; -use crate::ganapatha::SARVA_ADI; +use crate::ganapatha as gana; use crate::sounds as al; use crate::sounds::{s, Set}; use crate::stem_gana::{LAUKIKA_SANKHYA, PRATHAMA_ADI, PURVA_ADI, USES_DATARA_DATAMA}; @@ -10,6 +11,7 @@ use lazy_static::lazy_static; lazy_static! { static ref AC: Set = s("ac"); + static ref M_EC: Set = s("m ec"); } /// Returns whether this term ends in tIya-pratyaya. @@ -28,6 +30,89 @@ fn is_dati(t: &Term) -> bool { t.has_u_in(&["kati"]) } +/// Runs rules that define pragrhya. +pub fn try_pragrhya_rules(p: &mut Prakriya) -> Option<()> { + for i in 0..p.terms().len() { + let pada = p.pada(i); + if let Some(pada) = pada { + // Add the tag to the specific vowel sound (non-empty) so that it's more accessible + // during ac-sandhi. + let i_last = pada.end_non_empty()?; + if (pada.has_antya('I') || pada.has_antya('U') || pada.has_antya('e')) + && pada.last().has_tag(T::Dvivacana) + { + // harI etO, ... + p.add_tag_at("1.1.11", i_last, T::Pragrhya); + } else if pada.has_text_in(&["amI", "amU"]) { + // amI atra, ... + p.add_tag_at("1.1.12", i_last, T::Pragrhya); + } else if pada.last().has_u("Se") { + p.add_tag_at("1.1.13", i_last, T::Pragrhya); + } else if pada.first().is_nipata() { + if pada.last_non_empty()?.has_u("uY") { + // U~ iti + let done = p.optional_run_at("1.1.18", i_last, |t| t.set_text("U~")); + if !done { + // u iti, viti + p.optional_add_tag_at("1.1.17", i_last, T::Pragrhya); + } + } else if pada.text().len() == 1 + && pada.num_vowels() == 1 + && !pada.first().has_u("AN") + { + p.add_tag_at("1.1.14", i_last, T::Pragrhya); + } else if pada.has_antya('o') { + // Aho iti + p.add_tag_at("1.1.15", i_last, T::Pragrhya); + } + } + } + } + + Some(()) +} + +#[allow(unused)] +pub fn try_avyaya_rules(p: &mut Prakriya, i: usize) -> Option<()> { + let t = p.get(i)?; + + let is_svaradi = |t: &Term| { + if t.is_dhatu() || t.is_pratyaya() || t.is_agama() { + // svarAdi contains more than 150 items, so short-circuit the check however we can. + false + } else { + t.has_text_in(gana::SVAR_ADI) + } + }; + + if t.is_nipata() || is_svaradi(t) { + p.add_tag_at("1.1.37", i, T::Avyaya); + } else if t.is_taddhita() + // TODO: others. Is there a full list? + && t.has_u_in(&[ + "tasi~", + "vati~", + "naY", + "tasi~l", + "Am", + "kftvasu~c", + "su~c", + "DA", + "Sas", + ]) + { + p.add_tag_at("1.1.38", i, T::Avyaya); + } else if t.is_krt() && t.has_antya(&*M_EC) { + p.add_tag_at("1.1.39", i, T::Avyaya); + } else if t.is_krt() && t.has_u_in(&["ktvA", "tosu~n", "kasu~n"]) { + p.add_tag_at("1.1.40", i, T::Avyaya); + } else if p.is_avyayibhava() { + p.add_tag_at("1.1.41", i, T::Avyaya); + } + + Some(()) +} + fn try_run_for_pratipadika(p: &mut Prakriya) { for i in 0..p.terms().len() { if p.has(i, |t| t.is_pratipadika()) { @@ -80,7 +165,7 @@ fn try_run_for_pratipadika_at_index(p: &mut Prakriya, i: usize) -> Option<()> { } else if is_tiya(prati) && p.has(i + 1, |t| t.has_tag(T::Nit)) { // dvitIyAya, dvitIyasmE, ... p.optional_run_at("1.1.33.v1", i, add_tag(T::Sarvanama)); - } else if prati.has_u_in(SARVA_ADI) || prati.has_u_in(USES_DATARA_DATAMA) { + } else if prati.has_u_in(gana::SARVA_ADI) || prati.has_u_in(USES_DATARA_DATAMA) { let mut sarvanama = true; if prati.has_u_in(PURVA_ADI) && jasi { sarvanama = !p.optional_run("1.1.34", |_| {}); @@ -105,9 +190,7 @@ fn try_run_for_pratipadika_at_index(p: &mut Prakriya, i: usize) -> Option<()> { let mut decided = false; if stri_linga && (iyan_uvan_astri || i_u) && sup.has_tag(T::Nit) { - decided = p.optionally("1.4.6", |code, p| { - p.add_tag_at(code, i_sup - 1, T::Nadi); - }); + decided = p.optional_add_tag_at("1.4.6", i_sup - 1, T::Nadi); } let prati = p.get(i)?; @@ -123,9 +206,7 @@ fn try_run_for_pratipadika_at_index(p: &mut Prakriya, i: usize) -> Option<()> { } else if ii_uu && !decided { if iyan_uvan_astri { if sup.has_u("Am") { - p.optionally("1.4.5", |code, p| { - p.add_tag_at(code, i_sup - 1, T::Nadi); - }); + p.optional_add_tag_at("1.4.5", i_sup - 1, T::Nadi); } else { // "he SrIH", "he BrUH", but "he stri" p.step("1.4.4"); @@ -141,7 +222,7 @@ fn try_run_for_pratipadika_at_index(p: &mut Prakriya, i: usize) -> Option<()> { } fn is_matvartha(t: &Term) -> bool { - t.has_u_in(&["matu~p", "vini~"]) + t.has_u_in(&["matu~p", "vini~", "valac"]) } /// Runs rules that add the "pada" or "bha" samjnas to various terms. @@ -157,10 +238,23 @@ pub fn try_run_for_pada_or_bha(p: &mut Prakriya) -> Option<()> { } if term.has_tag_in(&[T::Sup, T::Tin]) { - // do nothing - // TODO: why? + if term.is_sup() && p.has(i + 1, |t| t.is_kya()) { + let ends_with_n = i > 0 && p.has(i - 1, |t| t.has_antya('n')); + p.run_at("1.4.15", i, |t| { + if ends_with_n { + t.add_tag(T::Pada); + } else { + t.remove_tag(T::Pada); + } + }); + } else { + p.add_tag_at("1.4.14", i, T::Pada); + } } else { - let next = p.pratyaya(i + 1)?; + let next = match p.pratyaya(i + 1) { + Some(v) => v, + None => continue, + }; // "svAdi" refers to any pratyaya introduced in adhyayas 4 and 5. These include: // - sup pratyayas (4.1.2) // - NI and Ap pratyayas (4.1.3 - 4.1.75) @@ -185,43 +279,97 @@ pub fn try_run_for_pada_or_bha(p: &mut Prakriya) -> Option<()> { Some(()) } -pub fn run_for_pragrhya(p: &mut Prakriya) -> Option<()> { - for i in 0..p.terms().len() { - let pada = p.pada(i); - if let Some(pada) = pada { - // Add the tag to the specific vowel sound (non-empty) so that it's more accessible - // during ac-sandhi. - let i_last = pada.end_non_empty()?; - if pada.has_antya('I') - || pada.has_antya('U') - || pada.has_antya('e') && pada.last().has_tag(T::Dvivacana) - { - // harI etO, ... - p.add_tag_at("1.1.11", i_last, T::Pragrhya); - } else if pada.has_text_in(&["amI", "amU"]) { - // amI atra, ... - p.add_tag_at("1.1.12", i_last, T::Pragrhya); - } else if pada.last().has_u("Se") { - p.add_tag_at("1.1.13", i_last, T::Pragrhya); - } else if pada.first().is_nipata() { - if pada.has_u("uY") { - // U~ iti - let done = p.optional_run_at("1.1.18", i_last, |t| t.set_text("U~")); - if !done { - // u iti, viti - p.optionally("1.1.17", |rule, p| p.add_tag_at(rule, i_last, T::Pragrhya)); - } - } else if pada.text().len() == 1 - && pada.num_vowels() == 1 - && !pada.first().has_u("AN") - { - p.add_tag_at("1.1.14", i_last, T::Pragrhya); - } else if pada.has_antya('o') { - // Aho iti - p.add_tag_at("1.1.15", i_last, T::Pragrhya); - } +/// Runs rules that define nipAta, upasarga, and gati. +pub fn try_nipata_rules(p: &mut Prakriya, i: usize) -> Option<()> { + let i_dhatu = p.find_next_where(i, |t| t.is_dhatu()); + let is_kriyayoga = i_dhatu.is_some(); + + // Marks the term as both `Gati` and `Nipata`. + let set_gati = |t: &mut Term| { + t.add_tags(&[T::Gati, T::Nipata]); + }; + + let t = p.get(i)?; + if t.has_text_in(gana::PRA_ADI) { + // pra, parA, ... + // (check prAdi first because some items are in both prAdi and cAdi). + p.add_tag_at("1.4.58", i, T::Nipata); + if is_kriyayoga { + // pra-Rayati, ... + p.add_tag_at("1.4.59", i, T::Upasarga); + // prakftya, ... + p.add_tag_at("1.4.60", i, T::Gati); + } + } else if is_kriyayoga { + let dhatu = p.get(i_dhatu?)?; + let is_kr = dhatu.has_u("qukf\\Y"); + + if t.has_text_in(gana::URI_ADI) || t.has_u_in(&["cvi~", "qAc"]) { + // urIkftya, ... + p.run_at("1.4.61", i, set_gati); + } else if t.has_text_in(&["sad", "asad"]) { + // satkftya, sat kftvA, ... + p.optional_run_at("1.4.63", i, set_gati); + } else if t.has_text("alam") { + // alaNkftya, alaN kftvA, ... + p.optional_run_at("1.4.64", i, set_gati); + } else if t.has_text("antar") { + // antarhatya, antarhatvA, ... + p.optional_run_at("1.4.65", i, set_gati); + } else if t.has_text_in(&["kaRe", "manas"]) { + // kaRehatya, kaRe hatvA, ... + p.optional_run_at("1.4.66", i, set_gati); + } else if t.has_text("puras") && t.is_avyaya() { + // puraskftya, ... + p.run_at("1.4.67", i, set_gati); + } else if t.has_text("astam") && t.is_avyaya() { + // astaNgatya, ... + p.run_at("1.4.68", i, set_gati); + } else if t.has_text("acCa") && t.is_avyaya() { + // acCagatya, ... + p.run_at("1.4.69", i, set_gati); + } else if t.has_text("adas") { + // adaHkftya, ... + p.run_at("1.4.70", i, set_gati); + } else if t.has_text("tiras") && !is_kr { + // tiroBUya, ... + p.run_at("1.4.71", i, set_gati); + } else if is_kr { + if t.has_text("tiras") { + // tiraskftya, tiras kftvA + p.optional_run_at("1.4.72", i, set_gati); + } else if t.has_text_in(&["upAje", "anvAje"]) { + // upAjekftya, upAje kftvA, ... + p.optional_run_at("1.4.73", i, set_gati); + } else if t.has_text_in(gana::SAKSHAT_PRABHRTI) { + // sAkzAtkftya, sAkzAt kftvA, ... + p.optional_run_at("1.4.74", i, set_gati); + } else if t.has_text_in(&["urasi", "manasi"]) { + // urasikftya, urasi kftvA, ... + p.optional_run_at("1.4.75", i, set_gati); + } else if t.has_text_in(&["maDye", "pade", "nivacane"]) { + // maDyekftya, maDye kftvA, ... + p.optional_run_at("1.4.76", i, set_gati); + } else if t.has_text_in(&["haste", "pARO"]) { + // hastekftya, haste kftvA, ... + p.optional_run_at("1.4.77", i, set_gati); + } else if t.has_text("prADvam") { + // prADvaNkftya, prADvaN kftvA + p.optional_run_at("1.4.78", i, set_gati); + } else if t.has_text_in(&["jIvikA", "upanizad"]) { + // jIvikAkftya, ... + p.optional_run_at("1.4.79", i, set_gati); } } + } else if t.has_text_in(gana::CA_ADI) { + // ca, vA, ... + p.add_tag_at("1.4.57", i, T::Nipata); + } + + let x = p.get(i)?; + if x.has_tag_in(&[T::Upasarga, T::Gati]) { + // "te prAg DAtoH" + p.step("1.4.80"); } Some(()) @@ -284,6 +432,28 @@ fn try_run_for_dhatu_pratyaya(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } +/// Assigns the pratipadika-samjna to all matching terms in the prakriya. +pub fn try_decide_pratipadika(p: &mut Prakriya) -> Option<()> { + for i in 0..p.terms().len() { + let t = p.get(i)?; + + if t.is_krt() || t.is_taddhita() || t.is_samasa() { + p.add_tag_at("1.2.46", i, T::Pratipadika); + } else if !t.is_dhatu() + && !t.is_pratyaya() + && !t.is_agama() + && !t.is_abhyasa() + && !t.is_pada() + { + // 1.2.45 specifies "arthavat", so exclude meaningless terms (agamas and abhyasas). + // TODO: is there anything else that's not arthavat? + p.add_tag_at("1.2.45", i, T::Pratipadika); + } + } + + Some(()) +} + fn try_run_for_dhatu(p: &mut Prakriya) -> Option<()> { p.find_first_where(|t| t.is_dhatu())?; @@ -295,6 +465,7 @@ fn try_run_for_dhatu(p: &mut Prakriya) -> Option<()> { } pub fn run(p: &mut Prakriya) { + try_decide_pratipadika(p); try_run_for_dhatu(p); try_run_for_pratipadika(p); try_run_for_sup(p); diff --git a/vidyut-prakriya/src/samprasarana.rs b/vidyut-prakriya/src/samprasarana.rs index b53c37a..e57f4ba 100644 --- a/vidyut-prakriya/src/samprasarana.rs +++ b/vidyut-prakriya/src/samprasarana.rs @@ -150,8 +150,7 @@ pub fn run_for_dhatu(p: &mut Prakriya) -> Option<()> { set_text("6.1.22", p, "sPI"); } else if dhatu.has_text("styE") && n.has_tag(T::Nistha) - && i > 0 - && p.has(i - 1, |t| t.has_u("pra")) + && p.has_prev_non_empty(i, |t| t.has_u("pra")) { // prastIta set_text("6.1.23", p, "sti"); @@ -175,7 +174,7 @@ pub fn run_for_dhatu(p: &mut Prakriya) -> Option<()> { } else if dhatu.has_u("jyA\\") && n.has_u("lyap") { p.step("6.1.42"); } else if dhatu.has_u("vye\\Y") && n.has_u("lyap") { - if i > 0 && p.has(i - 1, |t| t.has_u("pari")) { + if p.has_prev_non_empty(i, |t| t.has_u("pari")) { optional_set_text("6.1.44", p, "vi"); } else { p.step("6.1.43"); @@ -207,7 +206,7 @@ pub fn run_for_abhyasa(p: &mut Prakriya) -> Option<()> { if last.has_lakshana("li~w") { // yadā ca dhātorna bhavati tadā "liṭyabhyāsasya ubhayeṣām" // ityabhyāsasya api na bhavati -- kāśikā. - if is_vaci_svapi(dhatu) && !dhatu.text.starts_with("Sv") { + if is_vaci_svapi(dhatu) && !dhatu.starts_with("Sv") { if dhatu.has_u("ve\\Y") { p.step("6.1.40"); } else { diff --git a/vidyut-prakriya/src/sanadi.rs b/vidyut-prakriya/src/sanadi.rs index f87f203..eb42d45 100644 --- a/vidyut-prakriya/src/sanadi.rs +++ b/vidyut-prakriya/src/sanadi.rs @@ -1,84 +1,251 @@ -use crate::args::Gana; -use crate::args::Sanadi; +//! Runs rules that add sanAdi-pratyayas to the end of a dhatu or subanta. +use crate::args::Gana::*; +use crate::args::{Namadhatu, Pratipadika, Sanadi}; use crate::core::operators as op; use crate::core::Tag as T; use crate::core::Term; use crate::core::{Prakriya, Rule}; -use crate::dhatu_gana as gana; +use crate::dhatu_gana; +use crate::ganapatha as gana; use crate::it_samjna; +use crate::pratipadika_karya; use crate::sounds::{s, Set}; +use crate::Rule::Varttika; use lazy_static::lazy_static; lazy_static! { static ref HAL: Set = s("hal"); } -// These dhatus use their pratyaya optionally if followed by ArdhadhAtuka. +// These dhatus use their pratyaya optionally if followed by an ArdhadhAtuka-pratyaya. const AYADAYA: &[&str] = &[ "gupU~", "DUpa~", "viCa~", "paRa~\\", "pana~\\", "fti", "kamu~\\", ]; -/// Adds `upadesha` as a pratyaya after the dhatu at index `i_dhatu`. -fn add_sanadi(rule: impl Into, p: &mut Prakriya, i_dhatu: usize, upadesha: &str) { - p.run(rule, |p| { - let mut pratyaya = Term::make_upadesha(upadesha); - pratyaya.add_tags(&[T::Pratyaya]); - p.insert_after(i_dhatu, pratyaya); - }); - - let i_pratyaya = i_dhatu + 1; - p.add_tag_at("3.1.32", i_pratyaya, T::Dhatu); - it_samjna::run(p, i_pratyaya).expect("ok") +struct SanadiPrakriya<'a> { + p: &'a mut Prakriya, + /// The index after which we will insert the sanadi-pratyaya. + i_base: usize, } -/// Runs rules that apply only if using yaN-pratyay with luk. -fn run_rules_for_yan_luk(p: &mut Prakriya) -> Option<()> { - use Rule::Dhatupatha as DP; +impl<'a> SanadiPrakriya<'a> { + fn new(p: &'a mut Prakriya, i_base: usize) -> Self { + Self { p, i_base } + } + + fn run_for( + p: &mut Prakriya, + i_base: usize, + rule: impl Into, + upadesha: &str, + func: impl Fn(&mut Prakriya), + ) { + p.run(rule, |p| { + let mut pratyaya = Term::make_upadesha(upadesha); + pratyaya.add_tags(&[T::Pratyaya]); + p.insert_after(i_base, pratyaya); + func(p); - let i_yan = p.find_last_where(|t| t.is_pratyaya() && t.has_u("yaN"))?; + if !p.has(i_base, |t| t.is_dhatu()) { + p.set(i_base + 1, |t| t.add_tag(T::FlagNoArdhadhatuka)); + } + }); - // Apply luk. - p.run_at("2.4.74", i_yan, op::luk); + let i_pratyaya = i_base + 1; + p.add_tag_at("3.1.32", i_pratyaya, T::Dhatu); + it_samjna::run(p, i_pratyaya).expect("ok") + } - // "carkarItam ca" declares that yan-luk dhatus are part of ad-Adi gaNa. - // As a result, we will see lopa of Sap-vikarana per 2.4.72. - p.run_at(DP("02.0076"), i_yan, |d| d.set_gana(Gana::Adadi)); + /// Adds `upadesha` as a pratyaya after the dhatu at index `i_dhatu`. + fn add(&mut self, rule: impl Into, upadesha: &str) { + self.add_with(rule, upadesha, |_| {}); + } - Some(()) + fn add_with(&mut self, rule: impl Into, upadesha: &str, func: impl Fn(&mut Prakriya)) { + SanadiPrakriya::run_for(self.p, self.i_base, rule, upadesha, func); + } + + fn optional_add_sanadi(&mut self, rule: impl Into, upadesha: &str) { + let i_base = self.i_base; + self.p.optionally(rule.into(), |rule, p| { + SanadiPrakriya::run_for(p, i_base, rule, upadesha, |_| {}); + }); + } } -pub fn try_add_specific_sanadi_pratyayas(p: &mut Prakriya, is_ardhadhatuka: bool) -> Option<()> { - let i = p.find_first(T::Dhatu)?; - let dhatu = p.get(i)?; +/// Tries to add a sanAdi-pratyaya to the prakriya `p`. +/// +/// This function supports two different use cases: +/// +/// 1. If `sanadi` is defined, the function tries to add the specific pratyaya and does nothing if +/// pratyaya cannot be added. Examples: cikIrzati, putrakAmyati, ... +/// +/// 2. If `sanadi` is `None`, the function tries to add the first possible sanadi pratyaya and +/// does nothing if no such rule can be found. Examples: bAzpayate, muRqayati, ... +fn try_add(p: &mut Prakriya, sanadi: Option<&Sanadi>, is_ardhadhatuka: bool) -> Option<()> { + use Sanadi::*; + + let i_last = p.terms().len() - 1; + let i_base = p.find_last_where(|t| !t.is_empty())?; + + let mut sp = SanadiPrakriya::new(p, i_last); + let base = sp.p.get(i_base)?; + let sup = sp.p.has(i_base + 1, |t| t.is_sup()); - // non-Ardhadhatuka pratyayas - // -------------------------- // `Gana` is required so that we can exclude "03.0021 kita~". - if dhatu.has_u_in(&["gupa~\\", "tija~\\", "kita~"]) && dhatu.has_gana(Gana::Bhvadi) { + if base.is_dhatu() && base.has_u_in(&["gupa~\\", "tija~\\", "kita~"]) && base.has_gana(Bhvadi) { // jugupsate, titikzate, cikitsati - add_sanadi("3.1.5", p, i, "san"); - p.set(i + 1, |t| t.add_tag(T::FlagNoArdhadhatuka)); - } else if dhatu.has_u_in(gana::MAN_BADHA) { + sp.add_with("3.1.5", san.as_str(), |p| { + p.set(i_base + 1, |t| t.add_tag(T::FlagNoArdhadhatuka)); + }); + } else if base.is_dhatu() && base.has_u_in(dhatu_gana::MAN_BADHA) { // mImAMsate, etc. - add_sanadi("3.1.6", p, i, "san"); - // TODO: optional by extension of "vA" from 3.1.7 per Kashika? - p.set(i + 1, |t| t.add_tag(T::FlagNoArdhadhatuka)); - } + sp.add_with("3.1.6", san.as_str(), |p| { + // TODO: optional by extension of "vA" from 3.1.7 per Kashika? + p.set(i_base + 1, |t| t.add_tag(T::FlagNoArdhadhatuka)); + }); + } else if matches!(sanadi, Some(san)) { + sp.add("3.1.7", san.as_str()); + } else if sup && matches!(sanadi, Some(kyac)) { + // putrIyati, ... + sp.add("3.1.8", kyac.as_str()); + } else if sup && matches!(sanadi, Some(kAmyac)) { + // putrakAmyati, ... + sp.add("3.1.9", kAmyac.as_str()); + } else if sup && matches!(sanadi, Some(kyaN)) { + // SyenAyate, .. + sp.add("3.1.11", kyaN.as_str()); + } else if sup && base.has_text_in(gana::BHRSHA_ADI) { + // BfSAyate, .. + sp.add_with("3.1.12", kyaN.as_str(), |p| { + p.set(i_base, |t| { + if t.has_antya(&*HAL) { + t.set_antya(""); + } + }) + }); + } else if sup && base.has_text_in(gana::LOHITA_ADI) || base.has_u("qAc") { + // lohitAyati, lohitAyate, .. + sp.add("3.1.13", "kyaz"); + } else if sup && base.has_text("kazwa") { + // kazwAyate, ... + sp.add("3.1.14", kyaN.as_str()); + } else if sup && base.has_text_in(&["satra", "kakza", "kfcCra", "gahana"]) { + // kazwAyate, ... + sp.add(Varttika("3.1.14", "1"), kyaN.as_str()); + } else if sup && base.has_text_in(&["romanTa", "tapas"]) { + let is_tapas = base.has_text("tapas"); + // romanTAyate, ... + sp.add("3.1.15", kyaN.as_str()); + // tapasyati, ... + if is_tapas { + sp.p.run_at(Varttika("3.1.15", "1"), sp.p.terms().len() - 1, |t| { + t.remove_tag(T::Nit) + }); + } + } else if sup && base.has_text_in(&["bAzpa", "uzma"]) { + // bAzpAyate, ... + sp.add("3.1.16", kyaN.as_str()); + } else if sup && base.has_text("Pena") { + // PenAyate, ... + sp.add(Varttika("3.1.16", "1"), kyaN.as_str()); + } else if sup && base.has_text_in(&["Sabda", "vEra", "kalaha", "aBra", "kaRva", "meGa"]) { + // SabdAyate, ... + sp.add("3.1.17", kyaN.as_str()); + } else if sup && base.has_text_in(&["sudina", "durdina", "nIhAra"]) { + // sudinAyate, ... + sp.add(Varttika("3.1.17", "1"), kyaN.as_str()); + } else if sup + && base.has_text_in(&[ + "awA", "awwA", "SIkA", "kowA", "powA", "sowA", "kazwA", "pruzwA", "pluzwA", + ]) + { + // awAyate, ... + sp.add(Varttika("3.1.17", "2"), kyaN.as_str()); + } else if sup && base.has_text_in(gana::SUKHA_ADI) { + // suKAyate, ... + sp.add("3.1.18", kyaN.as_str()); + } else if sup && base.has_text_in(&["namas", "varivas", "citra"]) { + // namasyati, ... + sp.add_with("3.1.19", kyac.as_str(), |p| { + if p.has(i_base, |t| t.has_text("citra")) { + p.set(i_base + 2, |t| t.add_tag(T::Nit)); + } + }); + } else if sup && base.has_text_in(&["pucCa", "BARqa", "cIvara"]) { + // utpucCayate, ... + sp.add("3.1.20", "RiN"); + } else if sup + && base.has_text_in(&[ + "muRqa", "miSra", "SlakzRa", "lavaRa", "vrata", "vastra", "hali", "kali", "kfta", + "tUsta", + ]) + { + // muRqayati, ... + sp.add_with("3.1.21", Ric.as_str(), |p| { + p.set(i_base + 1, |t| { + if t.has_text_in(&["hali", "kali"]) { + t.set_antya("a"); + } + }) + }); + } else if matches!(sanadi, Some(Sanadi::yaN) | Some(Sanadi::yaNLuk)) { + if base.has_text_in(&["lup", "sad", "car", "jap", "jaB", "dah", "daS", "gF"]) { + sp.add("3.1.24", yaN.as_str()); + } else if (i_base > 0 + && sp + .p + .has(i_base - 1, |t| t.has_u_in(&["sUca", "sUtra", "mUtra"]))) + || base.has_u_in(&["awa~", "f\\", "aSa~", "aSU~\\", "UrRuY"]) + { + sp.add("3.1.22.v1", yaN.as_str()); + } else if base.is_ekac() && base.has_adi(&*HAL) { + sp.add("3.1.22", yaN.as_str()); + } - // Ardhadhatuka pratyayas - // ---------------------- - let dhatu = p.get(i)?; - if dhatu.has_gana(Gana::Curadi) { - // corayati - add_sanadi("3.1.25", p, i, "Ric"); - } else if dhatu.has_u_in(gana::KANDU_ADI) { - add_sanadi("3.1.27", p, i, "yak"); - } else if dhatu.has_u_in(AYADAYA) { + if matches!(sanadi, Some(Sanadi::yaNLuk)) { + use Rule::Dhatupatha as DP; + + let i_yan = p.find_last_where(|t| t.is_pratyaya() && t.has_u("yaN"))?; + + // Apply luk. + p.run_at("2.4.74", i_yan, op::luk); + + // "carkarItam ca" declares that yan-luk dhatus are part of ad-Adi gaNa. + // As a result, we will see lopa of Sap-vikarana per 2.4.72. + p.run_at(DP("02.0076"), i_yan, |d| d.set_gana(Adadi)); + } + } else if (sup + && base.has_text_in(&[ + "satya", "pASa", "rUpa", "vIRA", "tUla", "Sloka", "senA", "loman", "tvaca", "varman", + "varRa", "cUrRa", "arTa", "veda", + ])) + || base.has_gana(Curadi) + { + // satyApayati, ..., corayati, ... + sp.add("3.1.25", Ric.as_str()); + + let base = sp.p.get(i_base)?; + if sup && base.has_text_in(&["satya", "arTa", "veda"]) { + // satyApayati, arTApayati, vedApayati + op::insert_agama_at(Varttika("3.1.25", "1"), sp.p, i_base + 2, "Apu~k"); + } + } else if matches!(sanadi, Some(Ric)) { + sp.add("3.1.26", Ric.as_str()); + } else if base.has_u_in(gana::KANDU_ADI) { + // kaNDUyati, ... + // + // "dvivadhāḥ kaṇḍvādayo, dhātavaḥ prātipādikāni ca. tatra dhātvadhikārād + // dhātubhyaḥ eva pratyayo vidhīyate, na tu prātipadikebhyaḥ" + // + // -- KV on 3.1.27. + sp.add("3.1.27", "yak"); + } else if base.has_u_in(AYADAYA) { let mut can_add_pratyaya = true; if is_ardhadhatuka { - can_add_pratyaya = !p.optionally("3.1.31", |rule, p| { - p.run_at(rule, i, |t| { + can_add_pratyaya = !sp.p.optionally("3.1.31", |rule, p| { + p.run_at(rule, i_base, |t| { // TODO: not sure where to do this. if t.has_u("fti") { t.set_text("ft") @@ -88,20 +255,18 @@ pub fn try_add_specific_sanadi_pratyayas(p: &mut Prakriya, is_ardhadhatuka: bool } if can_add_pratyaya { - let dhatu = p.get(i)?; - if dhatu.has_u_in(&["gupU~", "DUpa~", "viCa~", "paRa~\\", "pana~\\"]) { + let base = sp.p.get(i_base)?; + if base.has_u_in(&["gupU~", "DUpa~", "viCa~", "paRa~\\", "pana~\\"]) { let rule = "3.1.28"; - if dhatu.has_u("paRa~\\") { + if base.has_u("paRa~\\") { // > stutyarthena paninā sāhacaryāt tadarthaḥ paṇiḥ pratyayamutpādayati na // > vyavahārārthaḥ. śatasya paṇate. sahasrasaya paṇate // -- KV on 3.1.28 - p.optionally(rule, |rule, p| { - add_sanadi(rule, p, i, "Aya"); - }); + sp.optional_add_sanadi(rule, "Aya"); } else { - add_sanadi(rule, p, i, "Aya"); + sp.add(rule, "Aya"); } - } else if dhatu.has_u("fti") { + } else if base.has_u("fti") { // ftIyate // // From the bAlamanorAma: @@ -110,10 +275,11 @@ pub fn try_add_specific_sanadi_pratyayas(p: &mut Prakriya, is_ardhadhatuka: bool // savarṇadīrgheṇaiva siddhe īyaṅiti īkāroccāraṇavaiyarthyāt । naca idantatve sati // 'eranekācaḥ' iti yaṇ syāditi vācyam, evamapi 'ṛterṅyaḥ' iti ṅyapratyaye // kṛte "akṛtsārvadhātukayordīrgha" iti dīrgheṇaiva siddhe iyaṅvidhivaiyarthyāt - p.set(i, |t| t.set_antya("")); - add_sanadi("3.1.29", p, i, "IyaN"); - } else if dhatu.has_u("kamu~\\") { - add_sanadi("3.1.30", p, i, "RiN"); + sp.add_with("3.1.29", "IyaN", |p| { + p.set(i_base, |t| t.set_antya("")); + }); + } else if base.has_u("kamu~\\") { + sp.add("3.1.30", "RiN"); } } } @@ -121,109 +287,29 @@ pub fn try_add_specific_sanadi_pratyayas(p: &mut Prakriya, is_ardhadhatuka: bool Some(()) } -// TODO: 3.1.8 - 3.1.21 -pub fn try_add_general_sanadi_pratyaya(p: &mut Prakriya, sanadi: Sanadi) -> Option<()> { - // We skip 3.1.23 because it conditions on the dhatu implying a sense of motion, which - // we can't easily model. - let i = p.find_last(T::Dhatu)?; - let dhatu = p.get(i)?; - match sanadi { - Sanadi::San => { - add_sanadi("3.1.7", p, i, "san"); - } - Sanadi::Yan | Sanadi::YanLuk => { - if dhatu.has_text_in(&["lup", "sad", "car", "jap", "jaB", "dah", "daS", "gF"]) { - add_sanadi("3.1.24", p, i, "yaN"); - } else if (i > 0 && p.has(i - 1, |t| t.has_u_in(&["sUca", "sUtra", "mUtra"]))) - || dhatu.has_u_in(&["awa~", "f\\", "aSa~", "aSU~\\", "UrRuY"]) - { - add_sanadi("3.1.22.v1", p, i, "yaN"); - } else if dhatu.is_ekac() && dhatu.has_adi(&*HAL) { - add_sanadi("3.1.22", p, i, "yaN"); - } - - // Extra work for yan-luk. - if sanadi == Sanadi::YanLuk { - run_rules_for_yan_luk(p); - } - } - Sanadi::Nic => { - add_sanadi("3.1.26", p, i, "Ric"); - } - } - - Some(()) +pub fn try_add_mandatory(p: &mut Prakriya, is_ardhadhatuka: bool) { + try_add(p, None, is_ardhadhatuka); } -#[cfg(test)] -mod tests { - use super::*; - use crate::args::Gana; - use crate::dhatu_karya; - use crate::dhatupatha; - - fn check_sanadi(upadesha: &str, gana: Gana, number: u16, sanadi: Sanadi) -> (Term, Term) { - let mut p = Prakriya::new(); - let dhatu = dhatupatha::create_dhatu(upadesha, gana, number).unwrap(); - dhatu_karya::run(&mut p, &dhatu).unwrap(); - - try_add_general_sanadi_pratyaya(&mut p, sanadi).unwrap(); - let dhatu = p.get(0).unwrap(); - let pratyaya = p.get(1).unwrap(); - (dhatu.clone(), pratyaya.clone()) - } - - fn check_basic(upadesha: &str, gana: Gana, number: u16) -> (Term, Term) { - let mut p = Prakriya::new(); - let dhatu = dhatupatha::create_dhatu(upadesha, gana, number).unwrap(); - dhatu_karya::run(&mut p, &dhatu).unwrap(); - try_add_specific_sanadi_pratyayas(&mut p, false).unwrap(); - - let dhatu = p.get(0).unwrap(); - let pratyaya = p.get(1).unwrap(); - (dhatu.clone(), pratyaya.clone()) - } - - #[test] - fn test_gup() { - let (_, san) = check_basic("gupa~\\", Gana::Bhvadi, 1125); - assert_eq!(san.text, "sa"); - assert!(san.has_all_tags(&[T::Pratyaya, T::FlagNoArdhadhatuka])); - } - - #[test] - fn test_man() { - let (_, san) = check_basic("mAna~\\", Gana::Bhvadi, 1127); - assert_eq!(san.text, "sa"); - assert!(san.has_all_tags(&[T::Pratyaya, T::FlagNoArdhadhatuka])); - } - - #[test] - fn test_curadi() { - let (_, nic) = check_basic("cura~", Gana::Curadi, 1); - assert_eq!(nic.text, "i"); - assert!(nic.is_pratyaya()); +/// Tries to create a namadhatu using the given arguments. +pub fn try_create_namadhatu(p: &mut Prakriya, dhatu: &Namadhatu) -> Option<()> { + match dhatu.pratipadika() { + Pratipadika::Basic(s, nyap) => { + pratipadika_karya::add_string(p, s, *nyap); + } + _ => panic!("Unsupported type for namadhatu"), } - #[test] - fn test_hetumati() { - let (_, nic) = check_sanadi("BU", Gana::Bhvadi, 1, Sanadi::Nic); - assert_eq!(nic.text, "i"); - assert!(nic.is_pratyaya()); - } + let mut su = Term::make_upadesha("su~"); + su.set_text(""); + su.add_tags(&[T::Pratyaya, T::Sup, T::Vibhakti, T::V1, T::Luk]); + p.push(su); - #[test] - fn test_ayadaya() { - let (_, aya) = check_basic("gupU~", Gana::Bhvadi, 461); - assert_eq!(aya.text, "Aya"); - assert!(aya.is_pratyaya()); + try_add(p, dhatu.sanadi().first(), false); - let (_, iiya) = check_basic("fti", Gana::Bhvadi, 1166); - assert_eq!(iiya.text, "Iya"); - assert!(iiya.has_all_tags(&[T::Pratyaya, T::Nit])); + Some(()) +} - let (_, nin) = check_basic("kamu~\\", Gana::Bhvadi, 511); - assert_eq!(nin.text, "i"); - assert!(nin.has_all_tags(&[T::Pratyaya, T::Rit, T::Nit])); - } +pub fn try_add_optional(p: &mut Prakriya, sanadi: Sanadi) { + try_add(p, Some(&sanadi), false); } diff --git a/vidyut-prakriya/src/sounds.rs b/vidyut-prakriya/src/sounds.rs index c3a8457..83f1e21 100644 --- a/vidyut-prakriya/src/sounds.rs +++ b/vidyut-prakriya/src/sounds.rs @@ -54,21 +54,24 @@ pub struct Set([u8; 256]); impl Set { /// Creates an empty set. - pub fn new() -> Self { + pub const fn new() -> Self { Set([0; 256]) } /// Creates a set whose members are the characters in `string`. - pub fn from(string: impl AsRef) -> Self { - let mut res = Self::new(); - for c in string.as_ref().chars() { + pub const fn from(text: &str) -> Self { + let mut res = Set([0; 256]); + let mut i = 0; + while i < text.len() { + let c = text.as_bytes()[i] as char; res.0[c as usize] = 1; + i += 1; } res } /// Returns whether the set contains the given sound. - pub fn contains(&self, c: Sound) -> bool { + pub const fn contains(&self, c: Sound) -> bool { self.0[c as usize] == 1 } } diff --git a/vidyut-prakriya/src/stem_gana.rs b/vidyut-prakriya/src/stem_gana.rs index 2c00529..51895f4 100644 --- a/vidyut-prakriya/src/stem_gana.rs +++ b/vidyut-prakriya/src/stem_gana.rs @@ -1,8 +1,26 @@ pub const LAUKIKA_SANKHYA: &[&str] = &[ - "eka", "dvi", "tri", "catur", "paYcan", "zaz", "saptan", "azwan", "navan", "daSan", "zoqaSan", + "eka", + "dvi", + "tri", + "catur", + "paYcan", + "zaz", + "saptan", + "azwan", + "navan", + "daSan", + "ekadaSan", + "dvAdaSan", + "trayodaSan", + "zoqaSan", + "Sata", + "sahasra", ]; -pub const TYAD_ADI: &[&str] = &["tyad", "tad", "yad", "etad", "idam", "adas", "eka", "dvi"]; +/// A subsection of SARVA_ADI (1). +pub const TYAD_ADI: &[&str] = &[ + "tyad", "tad", "yad", "etad", "idam", "adas", "eka", "dvi", "yuzmad", "asmad", "Bavatu~", "kim", +]; #[allow(unused)] pub const USES_DATARA_DATAMA: &[&str] = &[ diff --git a/vidyut-prakriya/src/stritva.rs b/vidyut-prakriya/src/stritva.rs index 8d6f2a3..9580385 100644 --- a/vidyut-prakriya/src/stritva.rs +++ b/vidyut-prakriya/src/stritva.rs @@ -34,12 +34,13 @@ enum Stri { NIn, NIp, NIz, + UN, } impl Stri { fn to_term(self) -> Term { let mut stri = Term::make_upadesha(self.as_str()); - stri.add_tags(&[T::Pratyaya, T::Nyap]); + stri.add_tags(&[T::Pratyaya, T::Nyap, T::Stri]); stri } } @@ -51,6 +52,7 @@ enum_boilerplate!(Stri, { NIn => "NIn", NIp => "NIp", NIz => "NIz", + UN => "UN", }); const INDRA_ADI: &[&str] = &[ @@ -108,7 +110,7 @@ impl<'a> StriPrakriya<'a> { it_samjna::run(self.p, self.i_prati + 1).expect("should never fail"); // HACK: nadi for NIz, etc. - if stri.as_str().contains("I") { + if stri.as_str().contains('I') { self.p.add_tag_at("1.4.3", self.i_prati + 1, T::Nadi); } @@ -164,6 +166,7 @@ pub fn run(p: &mut Prakriya) -> Option<()> { } let mut sp = StriPrakriya::new(p)?; + let i_prati = sp.i_prati; let last = sp.last(); // HACK: block uzRihA for now. @@ -178,8 +181,9 @@ pub fn run(p: &mut Prakriya) -> Option<()> { // always napumsaka. || last.has_u_in(&["Qak", "QaY"]) // Other pratyayas are as given. + // Include "ayac" which replaces "tayap" by 5.2.43. || last.has_u_in(&[ - "aR", "aY", "dvayasac", "daGnac", "mAtrac", "tayap", "Wak", "WaY", "kaY", "kvarap", + "aR", "aY", "dvayasac", "daGnac", "mAtrac", "tayap", "ayac", "Wak", "WaY", "kaY", "kvarap", ]) { sp.try_add("4.1.15", NIp); @@ -192,27 +196,27 @@ pub fn run(p: &mut Prakriya) -> Option<()> { // bahvI, bahu sp.optional_try_add("4.1.45", NIz); } else if last.has_text_in(INDRA_ADI) { + // indrARI, ... sp.try_add_with_agama("4.1.49", NIz, "Anu~k"); + } else if last.has_text_in(&["saKi", "aSiSu"]) { + let sub = if last.has_text("saKi") { + "saK" + } else { + "aSiSv" + }; + // saKI, ... + sp.p.run("4.1.62", |p| { + p.set(i_prati, |t| t.set_text(sub)); + p.insert_after(i_prati, Stri::NIz.to_term()); + }); + it_samjna::run(sp.p, i_prati + 1).expect("ok"); } } let last = sp.last(); - if last.has_text_in(gana::AJA_ADI) || last.has_antya('a') { - // ajA, ... - sp.try_add("4.1.4", wAp); - } else if last.has_tag_in(&[T::udit, T::fdit, T::xdit]) { - if last.is_dhatu() { - sp.block("4.1.6.v1") - } else { - // BavatI, pacantI, ... - sp.try_add("4.1.6", NIp); - } - } else if last.ends_with("van") { - let i_prati = sp.i_prati; - // SarvarI - sp.try_add_with("4.1.7", NIp, |p| { - p.set(i_prati, |t| t.set_antya("r")); - }); + if last.has_tag(T::zaw) || last.has_text_in(gana::SVASR_ADI) { + // svasA, duhitA, ... + sp.block("4.1.10"); } else if last.has_text("pAd") { // dvipadA, ... let done = sp.optional_try_add("4.1.9", wAp); @@ -220,18 +224,57 @@ pub fn run(p: &mut Prakriya) -> Option<()> { // dvipAt, dvipadI, ... sp.optional_try_add("4.1.8", NIp); } - } else if last.has_tag(T::zaw) || last.has_text_in(gana::SVASR_ADI) { - // - sp.block("4.1.10"); } else if last.ends_with("man") { - let done = sp.optional_try_add("4.1.13", wAp); + let done = sp.optional_try_add("4.1.13", qAp); if !done { // pAme, pAmAnO, ... sp.block("4.1.11"); } + } else if last.has_text("bAhu") && last.is_samasa() { + // madrabAhUH + // TODO: samjna only + sp.try_add("4.1.67", UN); + } else if last.has_text("paNgu") { + // paNgUH + sp.try_add("4.1.68", UN); + } else if last.has_text("SvaSura") { + // SvaSrUH + sp.try_add_with("4.1.68.v1", UN, |p| { + p.set(i_prati, |t| t.set_text("SvaSr")); + }); + } else if sp.p.is_chandasi() && last.has_text_in(&["kadru", "kamaRqalu"]) { + // kadrUH, ... + sp.try_add("4.1.71", UN); + } else if last.has_text("SArNgarava") || last.has_u("aY") { + // SArNgaravI, ... + sp.try_add("4.1.73", NIn); + } else if last.has_u_in(&["YyaN", "zyaN"]) { + sp.try_add("4.1.74", NIn); + } else if last.has_text("Avawya") { + // AvawyA, ... + sp.try_add("4.1.75", cAp); + } + + // Base cases. + let last = sp.last(); + if last.has_text_in(gana::AJA_ADI) || last.has_antya('a') { + // ajA, ... + sp.try_add("4.1.4", wAp); + } else if last.ends_with("van") { + // SarvarI, ... + sp.try_add_with("4.1.7", NIp, |p| { + p.set(i_prati, |t| t.set_antya("r")); + }); } else if last.has_antya('f') || last.has_antya('n') { // kartrI, daRqinI, ... sp.try_add("4.1.5", NIp); + } else if last.has_tag_in(&[T::udit, T::fdit, T::xdit]) { + if last.is_dhatu() { + sp.block("4.1.6.v1"); + } else { + // BavatI, pacantI, ... + sp.try_add("4.1.6", NIp); + } } Some(()) diff --git a/vidyut-prakriya/src/sup_karya.rs b/vidyut-prakriya/src/sup_karya.rs index 52375ae..726381d 100644 --- a/vidyut-prakriya/src/sup_karya.rs +++ b/vidyut-prakriya/src/sup_karya.rs @@ -1,4 +1,4 @@ -use crate::args::{SubantaArgs, Vacana, Vibhakti}; +use crate::args::{Linga, Vacana, Vibhakti}; use crate::core::Prakriya; use crate::core::Tag as T; use crate::core::Term; @@ -36,20 +36,20 @@ fn find_sup(vibhakti: Vibhakti, vacana: Vacana) -> &'static str { } } -pub fn run(p: &mut Prakriya, args: &SubantaArgs) -> Option<()> { - let sup = find_sup(args.vibhakti(), args.vacana()); +pub fn run(p: &mut Prakriya, linga: Linga, vibhakti: Vibhakti, vacana: Vacana) -> Option<()> { + let sup = find_sup(vibhakti, vacana); let mut sup = Term::make_upadesha(sup); sup.add_tags(&[ T::Pratyaya, T::Vibhakti, T::Sup, - args.vibhakti().as_tag(), - args.vacana().as_tag(), + vibhakti.as_tag(), + vacana.as_tag(), ]); - p.add_tags(&[args.linga().as_tag(), args.vacana().as_tag()]); - if args.vibhakti() == Vibhakti::Sambodhana { + p.add_tags(&[linga.as_tag(), vacana.as_tag()]); + if vibhakti == Vibhakti::Sambodhana { p.add_tag(T::Sambodhana); } diff --git a/vidyut-prakriya/src/sutrapatha.rs b/vidyut-prakriya/src/sutrapatha.rs index 3dc5630..0c00a9c 100644 --- a/vidyut-prakriya/src/sutrapatha.rs +++ b/vidyut-prakriya/src/sutrapatha.rs @@ -28,12 +28,13 @@ use crate::angasya; use crate::ardhadhatuka; use crate::args::Upapada; use crate::args::{ - Artha, Dhatu, KrdantaArgs, Lakara, Pada, Pratipadika, Prayoga, SamasaArgs, SubantaArgs, - TaddhitantaArgs, TinantaArgs, + Artha, Dhatu, Krdanta, Lakara, Pada, Pratipadika, Prayoga, Samasa, Subanta, Taddhitanta, + Tinanta, }; use crate::atidesha; use crate::atmanepada; use crate::core::errors::*; +use crate::core::prakriya_stack::PrakriyaStack; use crate::core::Prakriya; use crate::core::Tag; use crate::core::Term; @@ -51,6 +52,7 @@ use crate::samprasarana; use crate::sanadi; use crate::stritva; use crate::sup_karya; +use crate::svara; use crate::taddhita; use crate::tin_pratyaya; use crate::tripadi; @@ -63,31 +65,45 @@ use crate::vikarana; /// - replacing initial `R` and `z` with `n` and `s`, respectively. /// - recording and removing any it-samjnas /// - adding any necessary sanAdi-pratyayas. -/// -/// Scope: tinantas and krdantas -fn add_dhatu(p: &mut Prakriya, dhatu: &Dhatu, is_ardhadhatuka: bool) -> Result<()> { - dhatu_karya::run(p, dhatu)?; +fn prepare_dhatu(mut prakriya: Prakriya, dhatu: &Dhatu, is_ardhadhatuka: bool) -> Result { + let p = &mut prakriya; + match dhatu { + Dhatu::Mula(m) => { + dhatu_karya::run(p, m)?; + } + Dhatu::Nama(n) => { + dhatu_karya::try_add_prefixes(p, n.prefixes()); + sanadi::try_create_namadhatu(p, n); + if !p.terms().last().expect("ok").is_dhatu() { + println!("{:#?}", p); + return Err(Error::Abort(Box::new(prakriya))); + } + } + } - sanadi::try_add_specific_sanadi_pratyayas(p, is_ardhadhatuka); + let p = &mut prakriya; + sanadi::try_add_mandatory(p, is_ardhadhatuka); if p.terms().last().expect("ok").is_pratyaya() { samjna::run(p); run_main_rules(p, None, false)?; + // Defer tripadi until we add other pratyayas. } for s in dhatu.sanadi() { - sanadi::try_add_general_sanadi_pratyaya(p, *s); + sanadi::try_add_optional(p, *s); samjna::run(p); // Needed for BIzayate, etc. // TODO: revisit this. Is this really necessary here? atmanepada::run(p); run_main_rules(p, None, false)?; + // Defer tripadi until we add other pratyayas. } if !dhatu.sanadi().is_empty() { p.debug("~~~~~~~~~~~~~~ completed dhatu ~~~~~~~~~~~~~~~~~~") } - Ok(()) + Ok(prakriya) } /// Adds a lakara to the prakriya and decides which pada it is allowed to use. @@ -106,37 +122,8 @@ fn add_lakara_and_decide_pada(p: &mut Prakriya, lakara: Lakara) { vikarana::try_add_am_pratyaya_for_lit(p); } -/// Scope: tinantas and krdantas -fn run_dhatu_tasks_before_pratyaya(p: &mut Prakriya) { - // Needed transitively for dhatu-samprasarana. - angasya::try_pratyaya_adesha(p); - // Must run before it-Agama. - angasya::try_cinvat_for_bhave_and_karmani_prayoga(p); - - // Depends on jha_adesha since it conditions on the first sound. - it_agama::run_before_attva(p); - // Depends on it_agama for certain rules. - atidesha::run_before_attva(p); - - // Samprasarana of the dhatu is conditioned on several other operations, which we must execute - // first: - // - // 1. jha_adesha (affects it-Agama). - // 2. it_agama (affects kit-Nit) - // 3. atidesha (for kit-Nit) - samprasarana::run_for_dhatu(p); - // Ad-Adeza and other special tasks for Ardhadhatuka - ardhadhatuka::run_before_dvitva(p); - - // Now finish it_agama and atidesha - it_agama::run_after_attva(p); - atidesha::run_after_attva(p); -} - /// Scope: all prakriyas fn run_main_rules(p: &mut Prakriya, lakara: Option, is_ardhadhatuka: bool) -> Result<()> { - misc::run_pad_adi(p); - p.debug("==== Tin-siddhi ===="); // Do lit-siddhi and AzIrlin-siddhi first to support the valAdi vArttika for aj -> vi. let is_lit_or_ashirlin = matches!(lakara, Some(Lakara::Lit) | Some(Lakara::AshirLin)); @@ -164,7 +151,31 @@ fn run_main_rules(p: &mut Prakriya, lakara: Option, is_ardhadhatuka: boo angasya::try_add_or_remove_nit(p); p.debug("==== Dhatu tasks ===="); - run_dhatu_tasks_before_pratyaya(p); + { + // Needed transitively for dhatu-samprasarana. + angasya::try_pratyaya_adesha(p); + // Must run before it-Agama. + angasya::try_cinvat_for_bhave_and_karmani_prayoga(p); + + // Depends on jha_adesha since it conditions on the first sound. + it_agama::run_before_attva(p); + // Depends on it_agama for certain rules. + atidesha::run_before_attva(p); + + // Samprasarana of the dhatu is conditioned on several other operations, which we must execute + // first: + // + // 1. jha_adesha (affects it-Agama). + // 2. it_agama (affects kit-Nit) + // 3. atidesha (for kit-Nit) + samprasarana::run_for_dhatu(p); + // Ad-Adeza and other special tasks for Ardhadhatuka + ardhadhatuka::run_before_dvitva(p); + + // Now finish it_agama and atidesha + it_agama::run_after_attva(p); + atidesha::run_after_attva(p); + } // Must follow tin-siddhi and it-Agama, which could change the first sound of the pratyaya. ardhadhatuka::try_add_am_agama(p); @@ -184,7 +195,13 @@ fn run_main_rules(p: &mut Prakriya, lakara: Option, is_ardhadhatuka: boo tin_pratyaya::try_siddhi_for_jhi(p, lakara); } } + + // Samasa rules. + // TODO: can these be put somewhere more sensible? uttarapade::run(p); + samasa::try_sup_luk(p); + misc::run_pad_adi(p); + angasya::maybe_do_jha_adesha(p); ac_sandhi::try_sup_sandhi_before_angasya(p); @@ -198,84 +215,24 @@ fn run_main_rules(p: &mut Prakriya, lakara: Option, is_ardhadhatuka: boo p.debug("==== After dvitva ===="); angasya::run_after_dvitva(p); - uttarapade::run_after_guna(p); + uttarapade::run_after_guna_and_bhasya(p); + + samjna::try_run_for_pada_or_bha(p); ac_sandhi::try_sup_sandhi_after_angasya(p); ac_sandhi::run_common(p); - p.debug("==== Tripadi ===="); - tripadi::run(p); - - Ok(()) -} - -/// Derives a single tinanta from the given conditions. -pub fn derive_tinanta( - mut prakriya: Prakriya, - dhatu: &Dhatu, - args: &TinantaArgs, -) -> Result { - let p = &mut prakriya; - let prayoga = args.prayoga(); - let lakara = args.lakara(); - let purusha = args.purusha(); - let vacana = args.vacana(); - p.add_tags(&[prayoga.as_tag(), purusha.as_tag(), vacana.as_tag()]); - p.set_lakara(lakara); - - // Prayogas other than kartari will never be sarvadhatuka, since yak-vikarana is not - // sarvadhatuka. - let is_ardhadhatuka = match prayoga { - Prayoga::Kartari => lakara.is_ardhadhatuka(), - _ => true, - }; - - add_dhatu(p, dhatu, is_ardhadhatuka)?; - add_lakara_and_decide_pada(p, lakara); - tin_pratyaya::adesha(p, purusha, vacana); - samjna::run(p); - run_main_rules(p, Some(lakara), is_ardhadhatuka)?; - - Ok(prakriya) -} - -/// Derives a single subanta from the given conditions. -pub fn derive_subanta( - mut prakriya: Prakriya, - pratipadika: &Pratipadika, - args: &SubantaArgs, -) -> Result { - let p = &mut prakriya; - - // First, create the pratipadika. - pratipadika_karya::add_one(p, pratipadika); - - p.add_tag(args.linga().as_tag()); - pratipadika_karya::run_napumsaka_rules(p); - - // Then, add the sup-pratyaya. - sup_karya::run(p, args); - samjna::run(p); - - // Add strI-pratyayas. This should be done after adding the sup-pratyaya so that we satisfy the - // following constraints: - // - // - su~ must be added before sup-luk (7.1.23) - // - sup-luk must be checked before changing adas to ada (7.2.102) - // - ada must be in place before running stritva (4.1.4) - angasya::run_before_stritva(p); - stritva::run(p); + if p.use_svaras() { + p.debug("==== Svaras ===="); + svara::run(p); + } - run_main_rules(p, None, false)?; + // Run tripadi rules separately. - Ok(prakriya) + Ok(()) } -/// Derives a single krdanta from the given conditions. -pub fn derive_krdanta( - mut prakriya: Prakriya, - dhatu: &Dhatu, - args: &KrdantaArgs, -) -> Result { +/// Adds the basic terms necessary to create a krdanta. +fn prepare_krdanta(mut prakriya: Prakriya, args: &Krdanta) -> Result { let p = &mut prakriya; // If defined, set the meaning condition that this prakriya must follow. @@ -299,29 +256,77 @@ pub fn derive_krdanta( } let krt = args.krt(); - add_dhatu(p, dhatu, krt.is_ardhadhatuka())?; + prakriya = prepare_dhatu(prakriya, args.dhatu(), krt.is_ardhadhatuka())?; + let p = &mut prakriya; if let Some(la) = args.lakara() { p.add_tag(Tag::Kartari); add_lakara_and_decide_pada(p, la); } let added = krt::run(p, args); if !added { - return Err(Error::Abort(prakriya)); + println!("{:#?}", p); + return Err(Error::Abort(Box::new(prakriya))); } linganushasanam::run(p); stritva::run(p); samjna::run(p); - run_main_rules(p, None, true)?; Ok(prakriya) } -pub fn derive_taddhitanta( - mut prakriya: Prakriya, - pratipadika: &Pratipadika, - args: &TaddhitantaArgs, -) -> Result { +fn prepare_pratipadika(mut prakriya: Prakriya, pratipadika: &Pratipadika) -> Result { + use Pratipadika as Prati; + match pratipadika { + Pratipadika::Krdanta(k) if k.require().is_some() => { + let mut stack = PrakriyaStack::new(false, false, false); + stack.find_all(|p| derive_krdanta(p, k)); + + let mut added = false; + if let Some(s) = k.require() { + for p in stack.prakriyas() { + if *s == p.text() { + prakriya.extend(p.terms()); + added = true; + } + break; + } + } + if !added { + return Err(Error::Abort(Box::new(prakriya))); + } + } + Pratipadika::Taddhitanta(t) if t.require().is_some() => { + let mut stack = PrakriyaStack::new(false, false, false); + stack.find_all(|p| derive_taddhitanta(p, t)); + + let mut added = false; + if let Some(s) = t.require() { + for p in stack.prakriyas() { + if *s == p.text() { + prakriya.extend(p.terms()); + added = true; + } + break; + } + } + if !added { + return Err(Error::Abort(Box::new(prakriya))); + } + } + Prati::Basic(s, nyap) => pratipadika_karya::add_string(&mut prakriya, s, *nyap), + Prati::Krdanta(krdanta) => prakriya = prepare_krdanta(prakriya, krdanta)?, + Prati::Taddhitanta(taddhitanta) => prakriya = prepare_taddhitanta(prakriya, taddhitanta)?, + Prati::Samasa(samasa) => prakriya = derive_samasa(prakriya, samasa)?, + } + + samjna::try_decide_pratipadika(&mut prakriya); + + Ok(prakriya) +} + +/// Adds the basic terms necessary to create a krdanta. +fn prepare_taddhitanta(mut prakriya: Prakriya, args: &Taddhitanta) -> Result { let taddhita = args.taddhita(); let p = &mut prakriya; @@ -330,66 +335,227 @@ pub fn derive_taddhitanta( p.set_artha(Artha::Taddhita(artha)); } - // Begin the derivation. - pratipadika_karya::add_one(p, pratipadika); - samjna::run(p); + prakriya = prepare_pratipadika(prakriya, args.pratipadika())?; + samjna::run(&mut prakriya); + + let p = &mut prakriya; let added = taddhita::run(p, taddhita); if !added { if cfg!(debug_assertions) { println!("{:?}: {:#?}", args.taddhita(), p); } - return Err(Error::Abort(prakriya)); + return Err(Error::Abort(Box::new(prakriya))); } angasya::run_before_stritva(p); linganushasanam::run(p); stritva::run(p); samjna::run(p); + + Ok(prakriya) +} + +/// Derives a single tinanta from the given conditions. +pub fn derive_tinanta(mut prakriya: Prakriya, args: &Tinanta) -> Result { + let p = &mut prakriya; + let prayoga = args.prayoga(); + let lakara = args.lakara(); + let purusha = args.purusha(); + let vacana = args.vacana(); + p.add_tags(&[prayoga.as_tag(), purusha.as_tag(), vacana.as_tag()]); + p.set_lakara(lakara); + + // Prayogas other than kartari will never be sarvadhatuka, since yak-vikarana is not + // sarvadhatuka. + let is_ardhadhatuka = match prayoga { + Prayoga::Kartari => lakara.is_ardhadhatuka(), + _ => true, + }; + + prakriya = prepare_dhatu(prakriya, args.dhatu(), is_ardhadhatuka)?; + let p = &mut prakriya; + add_lakara_and_decide_pada(p, lakara); + tin_pratyaya::adesha(p, purusha, vacana); + samjna::run(p); + run_main_rules(p, Some(lakara), is_ardhadhatuka)?; + tripadi::run(p); + + Ok(prakriya) +} + +/// Derives a single subanta from the given conditions. +pub fn derive_subanta(mut prakriya: Prakriya, args: &Subanta) -> Result { + prakriya = prepare_pratipadika(prakriya, args.pratipadika())?; + + let p = &mut prakriya; + p.add_tag(args.linga().as_tag()); + pratipadika_karya::run_napumsaka_rules(p); + + // Then, add the sup-pratyaya. + sup_karya::run(p, args.linga(), args.vibhakti(), args.vacana()); + samjna::run(p); + + // Add strI-pratyayas. This should be done after adding the sup-pratyaya so that we satisfy the + // following constraints: + // + // - su~ must be added before sup-luk (7.1.23) + // - sup-luk must be checked before changing adas to ada (7.2.102) + // - ada must be in place before running stritva (4.1.4) + angasya::run_before_stritva(p); + stritva::run(p); + run_main_rules(p, None, false)?; + tripadi::run(p); Ok(prakriya) } -pub fn derive_stryanta(mut prakriya: Prakriya, pratipadika: &Pratipadika) -> Result { +/// Derives a single krdanta from the given conditions. +pub fn derive_krdanta(mut prakriya: Prakriya, args: &Krdanta) -> Result { + prakriya = prepare_krdanta(prakriya, args)?; + run_main_rules(&mut prakriya, None, true)?; + tripadi::run(&mut prakriya); + + Ok(prakriya) +} + +pub fn derive_taddhitanta(mut prakriya: Prakriya, args: &Taddhitanta) -> Result { + prakriya = prepare_taddhitanta(prakriya, args)?; + let p = &mut prakriya; + run_main_rules(p, None, false)?; + tripadi::run(p); + + Ok(prakriya) +} - pratipadika_karya::add_one(p, pratipadika); +pub fn derive_stryanta(mut prakriya: Prakriya, pratipadika: &Pratipadika) -> Result { + prakriya = prepare_pratipadika(prakriya, pratipadika)?; + + let p = &mut prakriya; p.add_tag(Tag::Stri); stritva::run(p); samjna::run(p); run_main_rules(p, None, false)?; + tripadi::run(p); Ok(prakriya) } -pub fn derive_samasa(mut prakriya: Prakriya, args: &SamasaArgs) -> Result { +/// Creates a dummy sup-pratyaya. +/// +/// Scope: samasas +fn make_sup_pratyaya(vibhakti: crate::args::Vibhakti) -> Term { + use crate::args::Vibhakti::*; + use crate::core::Tag as T; + let (u, vibhakti) = match vibhakti { + Prathama | Sambodhana => ("su~", T::V1), + Dvitiya => ("am", T::V2), + Trtiya => ("wA", T::V3), + Caturthi => ("Ne", T::V4), + Panchami => ("Nasi~", T::V5), + Sasthi => ("Nas", T::V6), + Saptami => ("Ni", T::V7), + }; + + let mut su = Term::make_upadesha(u); + su.add_tags(&[T::Pratyaya, T::Sup, T::Vibhakti, T::Pada, vibhakti]); + su +} + +pub fn derive_samasa(mut prakriya: Prakriya, args: &Samasa) -> Result { + use crate::core::Tag as T; + use crate::it_samjna; + + for pada in args.padas() { + let pratipadika = pada.pratipadika(); + prakriya = prepare_pratipadika(prakriya, pratipadika)?; + + let p = &mut prakriya; + if pada.is_avyaya() { + let i = p.terms().len() - 1; + p.set(i, |t| t.add_tag(T::Avyaya)); + if p.has(i, |t| t.has_u("naY")) { + it_samjna::run(p, i).expect("ok"); + } + } + p.push(make_sup_pratyaya(pada.vibhakti())); + } let p = &mut prakriya; + // Remove the trailing sup-pratyaya. + p.terms_mut().pop(); - pratipadika_karya::add_all(p, &args); - let added = samasa::run(p, &args); + samjna::run(p); + + let added = samasa::run(p, args); if !added { - return Err(Error::Abort(prakriya)); + return Err(Error::Abort(Box::new(prakriya))); } pratipadika_karya::run_napumsaka_rules(p); taddhita::run_for_samasas(p); + + if let Some((linga, vibhakti, vacana)) = args.sup() { + sup_karya::run(p, linga, vibhakti, vacana); + samjna::run(p); + } + + samasa::run_rules_for_avyayibhava(p); + samjna::try_decide_pratipadika(p); + + if args.stri() { + p.add_tag(T::Stri); + stritva::run(p); + p.remove_tag(T::Stri); + } + run_main_rules(p, None, false)?; + tripadi::run(p); Ok(prakriya) } pub fn derive_vakya(mut prakriya: Prakriya, padas: &[Pada]) -> Result { - let p = &mut prakriya; for pada in padas { - for term in pada.terms() { - p.push(term.clone()); + match pada { + Pada::Subanta(s) => { + let mut stack = PrakriyaStack::new(false, false, false); + stack.find_all(|p| derive_subanta(p, s)); + + if let Some(p) = stack.prakriyas().first() { + prakriya.extend(p.terms()); + } + } + Pada::Tinanta(t) => { + let mut stack = PrakriyaStack::new(false, false, false); + stack.find_all(|p| derive_tinanta(p, t)); + + if let Some(p) = stack.prakriyas().first() { + prakriya.extend(p.terms()); + } + } + Pada::Dummy(s) => { + let mut pada = Term::make_upadesha(s); + pada.add_tags(&[Tag::Pada]); + prakriya.push(pada); + } + Pada::Nipata(s) => { + let mut pada = Term::make_upadesha(s); + pada.add_tags(&[Tag::Pada, Tag::Avyaya, Tag::Nipata]); + if pada.has_antya('N') || pada.has_antya('Y') { + pada.set_antya(""); + } + prakriya.push(pada); + } } } - samjna::run_for_pragrhya(p); + let p = &mut prakriya; + samjna::try_pragrhya_rules(p); run_main_rules(p, None, false)?; + tripadi::run(p); Ok(prakriya) } diff --git a/vidyut-prakriya/src/svara.rs b/vidyut-prakriya/src/svara.rs new file mode 100644 index 0000000..bd8a152 --- /dev/null +++ b/vidyut-prakriya/src/svara.rs @@ -0,0 +1,285 @@ +use crate::core::term::Svara::*; +use crate::core::{Prakriya, Rule, Tag as T, Term}; +use crate::ganapatha as gana; +use crate::phit_sutraani; +use crate::sounds::{s, Set}; + +use lazy_static::lazy_static; + +lazy_static! { + static ref JHAL: Set = s("Jal"); + static ref HAL: Set = s("hal"); +} + +/// Clear all svaras for the terms in [i_start, i_end]. +fn set_anudattas(p: &mut Prakriya, i_start: usize, i_end: usize) { + for i in i_start..=i_end { + p.set(i, |t| t.set_svara(Anudatta)); + } +} + +/// Marks `t` as having udAtta on its first vowel. +fn set_adi_udatta(t: &mut Term) { + let num_vowels = t.num_vowels(); + debug_assert!(num_vowels >= 1, "{:?}", t); + t.set_svara(Udatta(0)) +} + +/// Marks `t` as having udAtta on its penultimate vowel. +fn set_upadha_udatta(t: &mut Term) { + let num_vowels = t.num_vowels(); + debug_assert!(num_vowels >= 2, "{:?}", t); + t.set_svara(Udatta(num_vowels - 2)) +} + +/// Marks `t` as having udAtta on its last vowel. +fn set_antya_udatta(t: &mut Term) { + let num_vowels = t.num_vowels(); + debug_assert!(num_vowels >= 1, "{:?}", t); + t.set_svara(Udatta(num_vowels - 1)) +} + +/// Marks `t` as having svarita on its last vowel. +fn set_antya_svarita(t: &mut Term) { + let num_vowels = t.num_vowels(); + debug_assert!(num_vowels >= 1, "{:?}", t); + t.set_svara(Svarita(num_vowels - 1)) +} + +#[derive(Debug)] +struct SvaraPrakriya<'a> { + p: &'a mut Prakriya, +} + +impl<'a> SvaraPrakriya<'a> { + fn new(p: &'a mut Prakriya) -> Self { + Self { p } + } + + fn reset_svaras(&mut self, rule: impl Into, i_term: usize, func: fn(&mut Term)) { + self.p.run(rule.into(), |p| { + set_anudattas(p, 0, p.terms().len() - 1); + p.set(i_term, func); + }); + } + + fn mark_adi_udatta(&mut self, rule: impl Into, i_term: usize) { + self.p.run(rule.into(), |p| { + set_anudattas(p, 0, i_term); + p.set(i_term, set_adi_udatta); + }); + } + + fn mark_upadha_udatta(&mut self, rule: impl Into, i_term: usize) { + self.p.run(rule.into(), |p| { + set_anudattas(p, 0, i_term); + p.set(i_term, set_upadha_udatta); + }); + } + + fn mark_antya_udatta(&mut self, rule: impl Into, i_term: usize) { + self.p.run(rule.into(), |p| { + set_anudattas(p, 0, i_term); + p.set(i_term, set_antya_udatta); + }); + } + + fn mark_antya_svarita(&mut self, rule: impl Into, i_term: usize) { + self.p.run(rule.into(), |p| { + set_anudattas(p, 0, i_term); + p.set(i_term, set_antya_svarita); + }); + } + + fn mark_anudatta(&mut self, rule: impl Into, i_term: usize) { + self.p.run(rule.into(), |p| { + p.set(i_term, |t| t.set_svara(Anudatta)); + }); + } +} + +enum SvaraState { + Continue, + Break, +} + +fn run_at(sp: &mut SvaraPrakriya, i_x: usize) -> Option { + let i_next = sp.p.find_next_where(i_x, |t| !t.is_empty()); + let i_y = sp.p.find_next_where(i_x, |t| t.num_vowels() > 0); + let temp = Term::make_text(""); + + sp.p.debug(format!("svara::run_at x={i_x} next={i_next:?} y={i_y:?}")); + + let x = sp.p.get(i_x)?; + let y = match i_y { + Some(i) => sp.p.get(i)?, + None => &temp, + }; + let next = match i_next { + Some(i) => sp.p.get(i)?, + None => &temp, + }; + + if (x.has_u("kf\\za~") || x.has_antya('A')) && y.has_u("GaY") { + // ka/rzaH + sp.mark_antya_udatta("6.1.156", i_y?); + return Some(SvaraState::Break); + } else if (x.has_tag(T::zaw) || x.has_u_in(&["tri", "catur"])) && next.has_adi(&*HAL) { + if y.has_adi(&*JHAL) && x.num_vowels() >= 2 { + // paYca/BiH + sp.mark_antya_udatta("6.1.180", i_x); + } else { + // paYcAnA/m + sp.mark_antya_udatta("6.1.179", i_y?); + } + } else if x.has_text("tisr") && y.has_u("jas") { + // tisra/H + sp.mark_antya_udatta("6.1.166", i_y?); + } else if x.has_u("catur") && y.has_u("Sas") { + // catu/raH + sp.mark_antya_udatta("6.1.167", i_x); + } else if x.has_text("dyu") && y.has_adi(&*JHAL) { + // dyu/BiH + sp.mark_anudatta("6.1.183", i_y?); + } else if x.has_tag(T::tit) { + // cikIrzya^, ... + sp.mark_antya_svarita("6.1.184", i_x); + } else if x.has_u("sarva") && next.is_sup() { + // sa/rvaH + sp.mark_adi_udatta("6.1.191", i_x); + } else if x.has_tag(T::lit) { + // cikI/rzakaH + sp.p.run("6.1.193", |p| { + set_anudattas(p, 0, i_x); + if let Some(i) = p.find_prev_where(i_x, |t| t.num_vowels() > 0) { + p.set(i, set_antya_udatta); + } + }); + } else if x.is_taddhita() && x.has_tag(T::cit) { + // kOyjAyana/ + sp.mark_antya_udatta("6.1.164", i_x); + } else if x.is_taddhita() && x.has_tag(T::kit) { + // nAqAyana/ + sp.mark_antya_udatta("6.1.165", i_x); + } else if x.is_pratyaya() && x.has_tag_in(&[T::Yit, T::nit]) { + // gA/rgya + sp.p.run("6.1.197", |p| { + set_anudattas(p, 0, i_x); + if let Some(i) = p.find_first_where(|t| t.num_vowels() > 0) { + p.set(i, set_adi_udatta); + } + }); + } else if x.has_u_in(&["paTin", "maTin"]) && next.is_sarvanamasthana() { + // pa/nTA + sp.mark_adi_udatta("6.1.199", i_x); + } else if x.has_text_in(gana::VRSHA_ADI) { + sp.mark_adi_udatta("6.1.203", i_x); + } else if x.has_u_in(&["yuzmad", "asmad"]) { + if y.has_u("Nasi") { + // ta/va, ma/ma + sp.mark_adi_udatta("6.1.211", i_x); + } else if y.has_u("Ne") { + // tu/Byam, ma/hyam + sp.mark_adi_udatta("6.1.212", i_x); + } + } else if x.has_tag(T::rit) { + sp.mark_upadha_udatta("6.1.217", i_x); + } else if next.has_u("ancu~") && next.has_text("c") { + // daDIcaH, ... + sp.mark_antya_udatta("6.1.212", i_x); + } else if x.has_tag(T::cit) { + // BaNgura/m + sp.mark_antya_udatta("6.1.163", i_x); + } else if x.is_dhatu() { + // pa/cati + // (This is a general case superseded by the rules above.) + sp.mark_antya_udatta("6.1.159", i_x); + } else if x.is_pratyaya() { + if i_x > 0 && x.svara != Some(Anudatta) { + sp.p.run("6.1.158", |p| { + set_anudattas(p, 0, i_x - 1); + }); + } + } else { + sp.p.debug("No match."); + } + + Some(SvaraState::Continue) +} + +fn run_for_samasa(sp: &mut SvaraPrakriya) -> Option<()> { + // TODO: calculate this properly + let i_purva = 0; + let i_uttara = sp.p.find_next_where(i_purva, |t| !t.is_empty())?; + let purva = sp.p.get(i_purva)?; + let uttara = sp.p.get_if(i_uttara, |t| t.is_samasa())?; + + if sp.p.is_karmadharaya() { + if purva.has_text("kumAra") && uttara.has_text("pratyenas") { + // ku/mArapratyenAH + sp.reset_svaras("6.2.27", i_purva, set_adi_udatta); + } + } else if purva.is_upasarga() && uttara.has_u("vana") { + // pravana/H + sp.mark_antya_udatta("6.2.178", i_uttara); + } else if purva.has_u("antar") && uttara.has_u("vana") { + // antarvaRa/H + sp.mark_antya_udatta("6.2.179", i_uttara); + } else if purva.is_upasarga() && uttara.has_u("antar") { + if purva.has_u_in(&["ni", "vi"]) { + sp.p.step("6.2.181"); + } else { + // prAnta/H + sp.mark_antya_udatta("6.2.180", i_uttara); + } + } else if purva.has_u("aBi") && uttara.has_u("muKa") { + // aBimuKa/H + sp.mark_antya_udatta("6.2.185", i_uttara); + } else if purva.has_u("apa") && uttara.has_u("muKa") { + // apawmuKa/H + sp.mark_antya_udatta("6.2.186", i_uttara); + } else if purva.has_u("apa") + && uttara.has_u_in(&[ + "sPiga", "pUta", "vIRA", "aYjas", "aDvan", "kukzi", "sIra", "nAman", + ]) + { + // apasPiga/m + sp.mark_antya_udatta("6.2.187", i_uttara); + } + + Some(()) +} + +pub fn run(p: &mut Prakriya) { + phit_sutraani::run(p); + + // First pass to add basic svaras. Components are: + // - dhatus + // - pratipadikas + // - pratyayas + // - agamas (ignore?) + for i in 0..p.terms().len() { + let t = p.get(i).expect("ok"); + if t.is_pratyaya() { + if t.is_sup() || t.has_tag(T::pit) { + p.run_at("3.1.4", i, |t| t.set_svara(Anudatta)); + } else { + p.run_at("3.1.3", i, |t| t.set_svara(Udatta(0))); + } + } + } + + let mut prakriya = SvaraPrakriya::new(p); + let sp = &mut prakriya; + for i in 0..sp.p.terms().len() { + // Check terms that have a vowel because svaras apply only to vowels. + if sp.p.has(i, |t| !t.is_empty() && t.num_vowels() > 0) { + let state = run_at(sp, i); + if matches!(state, Some(SvaraState::Break)) { + break; + } + } + } + + run_for_samasa(sp); +} diff --git a/vidyut-prakriya/src/taddhita/matvartha_prakarana.rs b/vidyut-prakriya/src/taddhita/matvartha_prakarana.rs index 4cd35f5..3fcf7eb 100644 --- a/vidyut-prakriya/src/taddhita/matvartha_prakarana.rs +++ b/vidyut-prakriya/src/taddhita/matvartha_prakarana.rs @@ -1,57 +1,130 @@ +use crate::args::Taddhita; use crate::args::Taddhita::*; +use crate::args::TaddhitaArtha; use crate::args::TaddhitaArtha::*; +use crate::core::operators as op; +use crate::core::Rule; +use crate::core::Rule::Varttika; +use crate::ganapatha as gana; use crate::taddhita::utils::TaddhitaPrakriya; +/// Shorthand for contexts that model simple one-time rules. +fn with_context_simple( + tp: &mut TaddhitaPrakriya, + rule: impl Into, + values: &[&str], + artha: TaddhitaArtha, + taddhita: Taddhita, +) { + let rule = rule.into(); + tp.with_context(artha, move |tp| { + let prati = tp.prati(); + if prati.has_text_in(values) { + tp.try_add(rule, taddhita); + } + }); +} + pub fn run(tp: &mut TaddhitaPrakriya) { - const RASA_ADI: &[&str] = &[ - "rasa", "rUpa", "ganDa", "sparSa", "Sabda", "sneha", "guRAt", "ekAcaH", - ]; - // TODO: others - const SIDHMA_ADI: &[&str] = &[ - "siDma", "gaqu", "maRi", "nABi", "jIva", "nizpAva", "pAMsu", "saktu", "hanu", "mAMsa", - "paraSu", - ]; - // TODO: others - const LOMA_ADI: &[&str] = &[ - "loman", "roman", "valgu", "baBrO", "hari", "kapi", "Suni", "taru", - ]; - // TODO: others - const PAMA_ADI: &[&str] = &[ - "pAman", "vAman", "heman", "Slezman", "kadru", "bali", "SrezWa", "palala", "sAman", - ]; - // TODO: others - const PICCHA_ADI: &[&str] = &[ - "picCa", "uras", "GruvakA", "kzuvakA", "varRa", "udaka", "paNka", "prajYA", - ]; + tp.with_context(Nimana, |tp| { + let prati = tp.prati(); + if prati.is_sankhya() { + // dvimaya, ... + tp.try_add("5.2.47", mayaw); + } + }); + + tp.with_context(Purana, |tp| { + let prati = tp.prati(); + if prati.is_sankhya() { + let i_prati = tp.i_prati; + if prati.has_text("dvi") { + // dvitIya + tp.try_add("5.2.54", tIya); + } else if prati.has_text("tri") { + // tftIya + tp.try_add_with("5.2.55", tIya, |p| p.set(i_prati, |t| t.set_text("tf"))); + } else { + // ekadaSaH, ... + let added = tp.try_add("5.2.48", qaw); + if added { + op::insert_agama_at("5.2.49", tp.p, tp.i_prati + 1, "maw"); + } + } + } + }); tp.with_context(TadAsyaAstiAsmin, |tp| { let prati = tp.prati(); - if prati.has_text_in(RASA_ADI) { + // TODO: do these block matup? + if prati.has_text_in(gana::VIMUKTA_ADI) { + tp.try_add("5.2.61", aR); + } else if prati.has_text_in(gana::GOSHADA_ADI) { + tp.try_add("5.2.62", vun); + } + }); + + tp.with_context(TatraKushala, |tp| { + let prati = tp.prati(); + if prati.has_text("paTin") { + tp.try_add("5.2.63", vun); + } else if prati.has_text_in(gana::AKARSHA_ADI) { + tp.try_add("5.2.64", kan); + } + }); + + with_context_simple(tp, "5.2.65", &["Dana", "hiraRya"], TatraKama, kan); + with_context_simple(tp, "5.2.67", &["udara"], TatraAdyuna, Wak); + with_context_simple(tp, "5.2.68", &["sasya"], TatraParijata, kan); + with_context_simple(tp, "5.2.69", &["aMSa"], Hari, kan); + with_context_simple(tp, "5.2.70", &["tantra"], AciraApahrta, kan); + with_context_simple(tp, "5.2.72", &["SIta", "uzRa"], Karin, kan); + with_context_simple(tp, "5.2.75", &["pArSva"], Anvicchati, kan); + + tp.with_context(TadAsyaAstiAsmin, |tp| { + let prati = tp.prati(); + + if prati.has_text_in(gana::RASA_ADI) { tp.try_add("5.2.95", matup); } else if prati.has_antya('A') { tp.optional_try_add("5.2.96", lac); - } else if prati.has_text_in(SIDHMA_ADI) { + } else if prati.has_text_in(gana::SIDHMA_ADI) { tp.optional_try_add("5.2.97", lac); } else if prati.has_text_in(&["vatsa", "aMsa"]) { tp.optional_try_add("5.2.98", lac); } else if prati.has_text("Pena") { let code = "5.2.99"; - tp.optional_try_add(code, lac); - tp.optional_try_add(code, ilac); - } else if prati.has_text_in(LOMA_ADI) - || prati.has_text_in(PAMA_ADI) - || prati.has_text_in(PICCHA_ADI) + tp.try_add(code, lac); + tp.try_add(code, ilac); + } else if prati.has_text_in(gana::LOMA_ADI) + || prati.has_text_in(gana::PAMA_ADI) + || prati.has_text_in(gana::PICCHA_ADI) { - let sub = if prati.has_text_in(LOMA_ADI) { + let sub = if prati.has_text_in(gana::LOMA_ADI) { Sa - } else if prati.has_text_in(PAMA_ADI) { + } else if prati.has_text_in(gana::PAMA_ADI) { na } else { ilac }; tp.try_add("5.2.100", sub); + } else if prati.has_text_in(&["rajas", "kfzi", "Asuti", "parizad"]) { + // rajasvala, ... + tp.try_add("5.2.112", valac); + } else if prati.has_text_in(gana::TUNDA_ADI) { + let code = "5.2.117"; + tp.optional_try_add(code, ini); + tp.optional_try_add(code, Wan); + tp.optional_try_add(code, ilac); + } else if prati.has_antya('a') { + let code = "5.2.115"; + tp.optional_try_add(code, ini); + tp.optional_try_add(code, Wan); } + // BrAtfvala, ... + tp.try_add(Varttika("5.2.112", "1"), valac); + let prati = tp.prati(); if prati.ends_with("as") || prati.has_text_in(&["mAyA", "meDA", "sraj"]) { tp.try_add("5.2.121", vini); diff --git a/vidyut-prakriya/src/taddhita/panchami_prakarana.rs b/vidyut-prakriya/src/taddhita/panchami_prakarana.rs index ca60836..8f14123 100644 --- a/vidyut-prakriya/src/taddhita/panchami_prakarana.rs +++ b/vidyut-prakriya/src/taddhita/panchami_prakarana.rs @@ -1,5 +1,6 @@ use crate::args::Taddhita::*; use crate::args::TaddhitaArtha::*; +use crate::core::operators as op; use crate::ganapatha as gana; use crate::taddhita::utils::TaddhitaPrakriya; @@ -143,38 +144,53 @@ pub fn run(tp: &mut TaddhitaPrakriya) { let prati = tp.prati(); if prati.has_text_in(&["sam", "pra", "ud", "vi"]) { if prati.has_text("vi") { + // viSAla, viSaNkawa, ... let code = "5.2.28"; tp.try_add(code, SAlac); tp.try_add(code, SaNkawac); } + // saNkawa, ... tp.try_add("5.2.29", kawac); + } else if prati.has_text_in(&["alAbU", "tila", "umA", "BaNgA"]) { + // alAbUkawa, ... + tp.try_add("5.2.29.v1", kawac); } else if prati.has_text("ava") { + // avakawa, ... let code = "5.2.30"; tp.try_add(code, kawac); tp.try_add(code, kuwArac); - } else if prati.has_text("ava") { + + // avawIwa, ... let code = "5.2.31"; tp.try_add(code, wIwac); tp.try_add(code, nAwac); tp.try_add(code, Brawac); } else if prati.has_text("ni") { + // nibiqa, nibirIsa let code = "5.2.32"; tp.try_add(code, biqac); tp.try_add(code, birIsac); + // cikina, cipiwa let code = "5.2.33"; let i_prati = tp.i_prati; tp.try_add_with(code, inac, |p| p.set(i_prati, |t| t.set_text("cik"))); tp.try_add_with(code, piwac, |p| p.set(i_prati, |t| t.set_text("ci"))); } else if prati.has_text_in(&["upa", "aDi"]) { + // upatyaka, ... tp.try_add("5.2.34", tyakan); } else if prati.has_text("karman") { tp.try_add("5.2.35", aWac); - } else if prati.has_text_in(gana::TARAKA_ADI) { - tp.try_add("5.2.36", itac); } - tp.with_context(Pramana, |tp| { + tp.with_context(TadAsyaSamjatam, |tp| { + let prati = tp.prati(); + if prati.has_text_in(gana::TARAKA_ADI) { + tp.try_add("5.2.36", itac); + } + }); + + tp.with_context(TadAsyaPramanam, |tp| { let prati = tp.prati(); if prati.has_text_in(&["puruza", "hastin"]) { @@ -197,7 +213,34 @@ pub fn run(tp: &mut TaddhitaPrakriya) { tp.try_add("5.2.39", vatup); } else if prati.has_text_in(&["kim", "idam"]) { let i_prati = tp.i_prati; - tp.try_add_with("5.2.40", vatup, |p| p.set(i_prati + 1, |t| t.set_adi("G"))); + let done = tp.try_add("5.2.40.1", vatup); + if done { + tp.p.run_at("5.2.40.2", i_prati + 1, |t| t.set_adi("G")); + } + + let prati = tp.prati(); + if prati.has_text("kim") { + // kati + tp.try_add("5.2.41", qati); + } + } + }); + + tp.with_context(Avasana, |tp| { + let prati = tp.prati(); + // Also include "uBa" by 5.2.44. + if prati.is_sankhya() || prati.has_text("uBa") { + // paYcataya, ... + let added = tp.try_add("5.2.42", tayap); + if added { + let prati = tp.prati(); + let i_t = tp.i_prati + 1; + if prati.has_text_in(&["dvi", "tri"]) { + op::optional_adesha("5.2.43", tp.p, i_t, "ayac"); + } else if prati.has_text("uBa") { + op::adesha("5.2.44", tp.p, i_t, "ayac"); + } + } } }); } diff --git a/vidyut-prakriya/src/taddhita/pragdivyatiya.rs b/vidyut-prakriya/src/taddhita/pragdivyatiya.rs index e5386cd..ba1a346 100644 --- a/vidyut-prakriya/src/taddhita/pragdivyatiya.rs +++ b/vidyut-prakriya/src/taddhita/pragdivyatiya.rs @@ -87,6 +87,9 @@ fn try_shaishika_rules(tp: &mut TaddhitaPrakriya, rule: &'static str) { } else if prati.has_text("kanTA") { tp.try_add("4.2.102", Wak); tp.try_add("4.2.103", vuk); + } else if prati.is_avyaya() { + // amAtyaH, ihatyaH, ... + tp.optional_try_add("4.2.104", tyap); } else if prati.has_text_in(&["Ezamas", "hyas", "Svas"]) { tp.optional_try_add("4.2.105", tyap); } else if prati.has_suffix_in(&["tIra", "rUpya"]) { @@ -256,7 +259,10 @@ pub fn run(tp: &mut TaddhitaPrakriya) { } let prati = tp.prati(); - if prati.has_text_in(&["rAjan", "Svasura"]) { + if prati.has_text_in(&["kamaRqalu", "SItabAhu", "jambu"]) { + // TODO: support non-KV examples + tp.try_add("4.1.135", QaY); + } else if prati.has_text_in(&["rAjan", "Svasura"]) { // [blocks aR & iY, respectively] tp.try_add("4.1.137", yat); } else if prati.has_text("kzatra") { @@ -355,7 +361,7 @@ pub fn run(tp: &mut TaddhitaPrakriya) { // Atreya, ... // TODO: an-iY tp.try_add("4.1.122", Qak); - } else if prati.has_tag(T::StriNyap) { + } else if prati.has_tag_in(&[T::Stri, T::StriNyap]) { // General case. if is_dvi_ac { // dAtteya, ... @@ -588,6 +594,36 @@ pub fn run(tp: &mut TaddhitaPrakriya) { } }); + tp.with_context(TasyaVishayoDeshe, |tp| { + let prati = tp.prati(); + let code = "4.2.54"; + + if prati.has_text_in(gana::RAJANYA_ADI) + || prati.has_text_in(&["devayAna", "mAlava", "virAwa", "trigarta"]) + { + // rAjanyaka, ... + // (Akrti-gana) + tp.try_add("4.2.53", vuY); + } else if prati.has_text_in(gana::BHAURIKI_ADI) { + tp.try_add(code, viDal); + } else if prati.has_text_in(gana::AISHUKARI_ADI) { + tp.try_add(code, Baktal); + } + + if !tp.had_match { + try_base_cases(tp, "4.2.52"); + } + }); + + tp.with_context(TadAdhiteTadVeda, |tp| { + let prati = tp.prati(); + if prati.has_text_in(gana::KRAMA_ADI) { + tp.try_add("4.2.61", vun); + } else { + try_base_cases(tp, "4.2.59"); + } + }); + tp.with_context(Caturarthika, |tp| { let prati = tp.prati(); if prati.has_suffix_in(&["mat", "vat"]) && prati.num_vowels() > 3 { diff --git a/vidyut-prakriya/src/taddhita/pragiviya.rs b/vidyut-prakriya/src/taddhita/pragiviya.rs index 2f020e0..b143730 100644 --- a/vidyut-prakriya/src/taddhita/pragiviya.rs +++ b/vidyut-prakriya/src/taddhita/pragiviya.rs @@ -100,7 +100,8 @@ pub fn run(tp: &mut TaddhitaPrakriya) -> Option<()> { } // vaiyAkaraRarUpa - tp.try_add("5.3.66", rUpap); + + // 5.3.66 is stated near 5.4.41 -- see that rule for details. // pawukalpa let code = "5.3.67"; @@ -110,7 +111,7 @@ pub fn run(tp: &mut TaddhitaPrakriya) -> Option<()> { tp.try_prepend("5.3.68", bahuc); - tp.try_add("5.3.69", jAtIyar); + // 5.3.69 is stated near 5.4.3 -- see that rule for details. // -------------------- // 5.3.70 prAg ivAt kaH @@ -146,7 +147,9 @@ pub fn run(tp: &mut TaddhitaPrakriya) -> Option<()> { tp.try_add("5.3.90", zwarac); } tp.optional_try_add("5.3.87", kan); - try_base_cases(tp, "5.3.86"); + if !tp.had_match { + try_base_cases(tp, "5.3.86"); + } }); tp.with_context(Tanutve, |tp| { @@ -156,6 +159,25 @@ pub fn run(tp: &mut TaddhitaPrakriya) -> Option<()> { } }); + tp.with_context(DvayorEka, |tp| { + let prati = tp.prati(); + if prati.has_text_in(&["kim", "yad", "tad"]) { + tp.try_add("5.3.92", qatarac); + } else if prati.has_text("eka") { + tp.try_add("5.3.94", qatarac); + } + }); + + tp.with_context(BahunamEka, |tp| { + let prati = tp.prati(); + if prati.has_text_in(&["kim", "yad", "tad"]) { + tp.try_add("5.3.93", qatamac); + } else if prati.has_text("eka") { + // Also appears in DvayorEka above. + tp.try_add("5.3.94", qatarac); + } + }); + tp.with_context(Avakshepane, |tp| { tp.try_add("5.3.95", kan); }); diff --git a/vidyut-prakriya/src/taddhita/pragvatiya.rs b/vidyut-prakriya/src/taddhita/pragvatiya.rs index bfbe15d..697b367 100644 --- a/vidyut-prakriya/src/taddhita/pragvatiya.rs +++ b/vidyut-prakriya/src/taddhita/pragvatiya.rs @@ -8,62 +8,86 @@ use crate::args::TaddhitaArtha::*; use crate::core::Tag as T; use crate::ganapatha as gana; use crate::taddhita::utils::TaddhitaPrakriya; +use crate::Rule::Varttika; fn try_base_cases(tp: &mut TaddhitaPrakriya, _code: &'static str) { use Taddhita as P; - tp.try_add("5.1.18", P::WaY); } -pub fn run(tp: &mut TaddhitaPrakriya) { +fn try_base_cases_arhiya(tp: &mut TaddhitaPrakriya, code: &'static str) { use Taddhita as P; + let prati = tp.prati(); + + if !prati.has_text("gopucCa") && !prati.is_sankhya() { + tp.try_add("5.1.19", P::Wak); + } else if prati.has_text_in(gana::NISHKA_ADI) && !prati.is_samasa() { + tp.try_add("5.1.20", P::Wak); + } else if prati.has_text("Sata") && !prati.is_samasa() { + // Satika, Satya + let code = "5.1.21"; + tp.try_add(code, P::Wan); + tp.try_add(code, P::yat); + } else if prati.has_text("kaMsa") { + tp.try_add("5.1.25", P::wiWan); + } else if prati.has_text("SUrpa") { + tp.optional_try_add("5.1.26", P::aY); + } else if prati.has_text_in(&["SatamAna", "viMSatika", "sahasra", "vasana"]) { + tp.optional_try_add("5.1.27", P::aR); + } else if prati.is_sankhya() && !prati.has_prefix_in(&["ti", "Sat"]) { + tp.try_add("5.1.22", P::kan); + } + + try_base_cases(tp, code); +} + +pub fn run(tp: &mut TaddhitaPrakriya) { + use Taddhita::*; tp.with_context(TenaKritam, |tp| { let prati = tp.prati(); if prati.has_tag(T::Sankhya) { - tp.try_add("5.1.22", P::kan); + tp.try_add("5.1.22", kan); } else if prati.has_text_in(&["viMSati", "triMSat"]) { - tp.try_add("5.1.24", P::qvun); + tp.try_add("5.1.24", qvun); } else if prati.has_text("kaMsa") { - tp.try_add("5.1.25", P::wiWan); + tp.try_add("5.1.25", wiWan); } else if prati.has_text("SUrpA") { - tp.optional_try_add("5.1.26", P::aY); + tp.optional_try_add("5.1.26", aY); } else if prati.has_text_in(&["SatamAna", "viMSatika", "sahasra", "vasana"]) { - tp.try_add("5.1.27", P::aR); + tp.try_add("5.1.27", aR); } else if prati.has_text_in(&["dviSARa", "triSARa"]) { let code = "5.1.36"; - tp.try_add(code, P::yat); - tp.try_add(code, P::aR); + tp.try_add(code, yat); + tp.try_add(code, aR); } else { - try_base_cases(tp, "5.1.37"); + try_base_cases_arhiya(tp, "5.1.37"); } }); tp.with_context(TadArhati, |tp| { let prati = tp.prati(); if prati.has_text_in(gana::DANDA_ADI) { - tp.try_add("5.1.66", P::yat); + tp.try_add("5.1.66", yat); } else if prati.has_text("pAtra") { let code = "5.1.68"; - tp.try_add(code, P::yat); - tp.try_add(code, P::Gan); - } else if prati.has_text_in(&["kaqaNgara", "dakzirA"]) { + tp.try_add(code, yat); + tp.try_add(code, Gan); + } else if prati.has_text_in(&["kaqaNkara", "dakziRA"]) { let code = "5.1.69"; - tp.try_add(code, P::yat); - tp.try_add(code, P::Ca); + tp.try_add(code, yat); + tp.try_add(code, Ca); } else if prati.has_text("sTAlIbila") { let code = "5.1.70"; - tp.try_add(code, P::yat); - tp.try_add(code, P::Ca); + tp.try_add(code, yat); + tp.try_add(code, Ca); } else if prati.has_text_in(&["yajYa", "ftvij"]) { - let t = if prati.has_text("yajYa") { - P::Ga - } else { - P::KaY - }; + let t = if prati.has_text("yajYa") { Ga } else { KaY }; tp.try_add("5.1.71", t); + } else if tp.p.is_chandasi() { + tp.try_add("5.1.67", yat); } else { - try_base_cases(tp, "5.1.63"); + try_base_cases_arhiya(tp, "5.1.63"); } }); @@ -85,16 +109,23 @@ pub fn run(tp: &mut TaddhitaPrakriya) { let i_prati = tp.i_prati; let prati = tp.prati(); if prati.has_text("yojana") { - try_base_cases(tp, "5.1.74"); + tp.try_add("5.1.74", WaY); } else if prati.has_text("paTin") { - tp.try_add("5.1.75", P::zkan); - tp.try_add_with("5.1.76", P::Ra, |p| p.set(i_prati, |t| t.set_text("panTa"))); + tp.try_add("5.1.75", zkan); + tp.try_add_with("5.1.76", Ra, |p| p.set(i_prati, |t| t.set_text("panTa"))); + } + }); + + tp.with_context(AbhigamanamArhati, |tp| { + let prati = tp.prati(); + if prati.has_text_in(&["kroSaSata", "yojanaSata"]) { + tp.try_add(Varttika("5.1.74", "1"), WaY); } }); let prati = tp.prati(); if prati.has_text("ftu") { - tp.try_add("5.1.105", P::aR); - tp.try_add("5.1.106", P::Gas); + tp.try_add("5.1.105", aR); + tp.try_add("5.1.106", Gas); } } diff --git a/vidyut-prakriya/src/taddhita/prakkritiya.rs b/vidyut-prakriya/src/taddhita/prakkritiya.rs index 56e2850..19bc296 100644 --- a/vidyut-prakriya/src/taddhita/prakkritiya.rs +++ b/vidyut-prakriya/src/taddhita/prakkritiya.rs @@ -5,16 +5,20 @@ Implements the taddhita rules in the "prAk krItAc CaH" section of pada 5.1. */ use crate::args::Taddhita::*; use crate::args::TaddhitaArtha::*; +use crate::ganapatha as gana; use crate::taddhita::utils::TaddhitaPrakriya; fn try_base_cases(tp: &mut TaddhitaPrakriya, _rule: &'static str) { - const GO_ADI: &[&str] = &[ - "go", "havis", "varhiz", "Kawa", "azwakA", "yuga", "meDA", "srak", "nABi", "naBam", - ]; - // TODO: use `_rule` as well -- this should be simultaneous application. let prati = tp.prati(); - if prati.has_antya('u') || prati.has_antya('U') || prati.has_text_in(GO_ADI) { + if prati.has_text("kambala") { + tp.optional_try_add("5.1.3", yat); + } else if prati.has_text("havis") || prati.has_text_in(gana::APUPA_ADI) { + tp.optional_try_add("5.1.4", yat); + } + + let prati = tp.prati(); + if prati.has_antya('u') || prati.has_antya('U') || prati.has_text_in(gana::GAVADI) { tp.try_add("5.1.2", yat); } else { tp.try_add("5.1.1", Ca); @@ -47,15 +51,17 @@ pub fn run(tp: &mut TaddhitaPrakriya) { tp.with_context(TadarthamVikrtehPrakrtau, |tp| { let prati = tp.prati(); - if prati.has_text_in(&["Cadis", "upaDi", "bAli"]) { + let pratipadika = tp.nyap_pratipadika(); + if pratipadika.has_text_in(&["Cadis", "upaDi", "bAli"]) { tp.try_add("5.1.13", QaY); } else if prati.has_text_in(&["fzaBa", "upAnah"]) { tp.try_add("5.1.14", Yya); - } else if prati.has_text_in(&["vardhra", "varatrA"]) { + } else if prati.has_text_in(&["varDrI", "varatrA"]) { // HACK: The rule states "carman," i.e. words referring to a skin or leather. For now, // use the two examples found in the Kashika Vrtti. tp.try_add("5.1.15", aY); } else { + // aNgArIya, ... try_base_cases(tp, "5.1.12"); } }); diff --git a/vidyut-prakriya/src/taddhita/samasanta_prakarana.rs b/vidyut-prakriya/src/taddhita/samasanta_prakarana.rs index cd9425d..87d1d14 100644 --- a/vidyut-prakriya/src/taddhita/samasanta_prakarana.rs +++ b/vidyut-prakriya/src/taddhita/samasanta_prakarana.rs @@ -14,18 +14,19 @@ use lazy_static::lazy_static; lazy_static! { static ref CU: Set = s("cu~"); + static ref JHAY: Set = s("Jay"); } impl Prakriya { - fn is_bahuvrihi(&self) -> bool { + pub(crate) fn is_bahuvrihi(&self) -> bool { self.has_tag(T::Bahuvrihi) } - fn is_tatpurusha(&self) -> bool { + pub(crate) fn is_tatpurusha(&self) -> bool { self.has_tag(T::Tatpurusha) } - fn is_avyayibhava(&self) -> bool { + pub(crate) fn is_avyayibhava(&self) -> bool { self.has_tag(T::Avyayibhava) } @@ -35,20 +36,26 @@ impl Prakriya { } fn add(rule: impl Into, p: &mut Prakriya, taddhita: Taddhita) -> bool { + let i_antya = p + .find_last_where(|t| t.is_pratipadika_or_nyapu()) + .expect("ok"); let rule = rule.into(); - - p.run(rule, |p| { - p.push(taddhita.to_term()); - }); - let i_last = p.terms().len() - 1; - it_samjna::run(p, i_last).expect("should never fail"); + // Insert after pratipadika but before any subantas + p.run(rule, |p| p.insert_after(i_antya, taddhita.to_term())); + it_samjna::run(p, i_antya + 1).expect("should never fail"); true } +fn optional_add(rule: impl Into, p: &mut Prakriya, taddhita: Taddhita) -> bool { + p.optionally(rule.into(), |rule, p| { + add(rule, p, taddhita); + }) +} + pub fn run(p: &mut Prakriya) -> Option<()> { - let i_uttara = p.find_last_where(|t| t.is_pratipadika_or_nyap())?; - let i_purva = p.find_prev_where(i_uttara, |t| t.is_pratipadika_or_nyap())?; + let i_uttara = p.find_last_where(|t| t.is_pratipadika_or_nyapu())?; + let i_purva = p.find_prev_where(i_uttara, |t| t.is_pratipadika_or_nyapu())?; let purva = p.get(i_purva)?; let uttara = p.get(i_uttara)?; @@ -96,9 +103,46 @@ pub fn run(p: &mut Prakriya) -> Option<()> { if uttara.ends_with("an") { // uparAjam, ... add("5.4.108", p, wac); + } else if uttara.has_antya(&*JHAY) { + // upasamiDa, upasamit, ... + optional_add("5.4.111", p, wac); + } else if uttara.has_text("giri") { + // antargiram, antargiri, ... + optional_add("5.4.112", p, wac); } } else if p.is_bahuvrihi() { - if uttara.has_text("Danus") { + if purva.has_text_in(&["dvi", "tri"]) && uttara.has_text("mUrDan") { + // dvimUrDa, trimUrDa + add("5.4.115", p, za); + } else if purva.has_text_in(&["antar", "bahis"]) && uttara.has_text("loman") { + // antarloma, bahirloma + add("5.4.117", p, ap); + } else if purva.is_upasarga() && uttara.has_text("nas") { + // unnasa, ... + add("5.4.119", p, ac); + } else if purva.has_text_in(&["a", "dus", "su"]) && uttara.has_text_in(&["hali", "sakTi"]) { + // ahala, ahali, ... + optional_add("5.4.121", p, ac); + } else if purva.has_text_in(&["a", "dus", "su"]) && uttara.has_text_in(&["prajA", "meDas"]) + { + // aprajAH, ... + add("5.4.122", p, asic); + } else if uttara.has_text("Darma") { + // kalyARaDarmA, ... + // TODO: kevala + add("5.4.124", p, anic); + } else if purva.has_text_in(&["su", "harita", "tfRa", "soma"]) && uttara.has_text("jamBa") { + // sujamBA, ... + p.run_at("5.4.125", i_uttara, |t| t.set_text("jamBan")); + } else if uttara.has_text("jAnu") { + if purva.has_text_in(&["pra", "sam"]) { + // prajYuH, samYjuH + p.run_at("5.4.129", i_uttara, |t| t.set_text("jYu")); + } else if purva.has_text("UrDva") { + // UrDvajAnuH, UrDvajYuH + p.optional_run_at("5.4.130", i_uttara, |t| t.set_text("jYu")); + } + } else if uttara.has_text("Danus") { // SArNgaDanvA, ... p.run_at("5.4.132", i_uttara, |t| t.set_antya("an")); } else if uttara.has_text("jAyA") { @@ -107,6 +151,9 @@ pub fn run(p: &mut Prakriya) -> Option<()> { } else if purva.has_text_in(&["ud", "pUti", "su", "suraBi"]) && uttara.has_text("ganDa") { // udganDi, ... p.run_at("5.4.135", i_uttara, |t| t.set_antya("i")); + } else if (purva.is_sankhya() || purva.has_text("su")) && uttara.has_text("pAda") { + // dvipAt, ... + p.run_at("5.4.140", i_uttara, |t| t.set_text("pAd")); } else if uttara.has_text("kAkuda") { if purva.has_text_in(&["ud", "vi"]) { // utkAkut, ... diff --git a/vidyut-prakriya/src/taddhita/svarthika_prakarana.rs b/vidyut-prakriya/src/taddhita/svarthika_prakarana.rs index 3a13c0f..f258d97 100644 --- a/vidyut-prakriya/src/taddhita/svarthika_prakarana.rs +++ b/vidyut-prakriya/src/taddhita/svarthika_prakarana.rs @@ -10,19 +10,25 @@ pub fn run(tp: &mut TaddhitaPrakriya) { tp.with_context(IvePratikrtau, |tp| { let prati = tp.prati(); if prati.has_text("vasti") { + // vAsteya tp.try_add("5.3.101", QaY); } else if prati.has_text("SilA") { tp.try_add("5.3.102", Qa); } else if prati.has_text_in(gana::SHAKHA_ADI) { + // SAKya, ... tp.try_add("5.3.103", yat); } else if prati.has_text("kuSAgra") { + // kuSAgrIya tp.try_add("5.3.105", Ca); } else if prati.has_text_in(gana::SHARKARA_ADI) { tp.try_add("5.3.107", aR); } else if prati.has_text_in(gana::ANGULI_ADI) { tp.try_add("5.3.108", Wak); } else if prati.has_text("ekaSAlA") { - tp.optional_try_add("5.3.109", Wac); + // ekaSAlikaH, EkaSAlikaH + let code = "5.3.109"; + tp.try_add(code, Wac); + tp.try_add(code, Wak); } else if prati.has_text_in(&["karka", "lohita"]) { tp.try_add("5.3.110", Ikak); } else if tp.p.is_chandasi() && prati.has_text_in(&["pratna", "pUrva", "viSva", "ima"]) { @@ -32,6 +38,27 @@ pub fn run(tp: &mut TaddhitaPrakriya) { } }); + tp.with_context(AyudhaJiviSangha, |tp| { + let prati = tp.prati(); + if prati.has_text("vfka") { + // vArkeRya + tp.try_add("5.3.115", weRyaR); + } else if prati.has_text_in(gana::DAMANI_ADI) + || prati.has_text_in(&[ + "kORqoparaTa", + "dARqaki", + "kOzWika", + "jAlamAni", + "brahmagupta", + "jAnaki", + ]) + { + tp.try_add("5.3.116", Ca); + } else { + tp.try_add("5.3.114", Yyaw); + } + }); + tp.with_context(Svarthe, |tp| { let prati = tp.prati(); if prati.has_text_in(gana::DAMANI_ADI) { @@ -55,14 +82,34 @@ pub fn run(tp: &mut TaddhitaPrakriya) { let prati = tp.prati(); if prati.has_text_in(gana::STHULA_ADI) { tp.try_add("5.4.3", kan); - } else if prati.has_text_in(&["caYcut", "bfhat"]) { + } else if prati.has_text_in(&["caYcat", "bfhat"]) { tp.try_add("5.4.3.v1", kan); + } else { + // 5.4.3 is an apavAda to 5.3.69. + tp.try_add("5.3.69", jAtIyar); + } + }); + + tp.with_context(AnatyantaGati, |tp| { + let prati = tp.prati(); + if prati.has_u("kta") { + tp.try_add("5.4.4", kan); + } + }); + + tp.with_context(Acchadana, |tp| { + let prati = tp.prati(); + if prati.has_text("bfhatI") { + tp.try_add("5.4.6", kan); } }); tp.with_context(Svarthe, |tp| { let prati = tp.prati(); - if prati.has_text("anugAdin") { + if prati.has_text_in(&["azaqakza", "ASitaNgu", "alaNkarman", "alampuruza"]) { + // TOOD: adhy-uttara + tp.try_add("5.4.7", Ka); + } else if prati.has_text("anugAdin") { tp.try_add("5.4.13", Wak); } }); @@ -145,6 +192,22 @@ pub fn run(tp: &mut TaddhitaPrakriya) { tp.try_add("5.4.39", tikan); } + tp.with_context(Prashamsa, |tp| { + let prati = tp.prati(); + if prati.has_text("mfd") { + let code = "5.4.41"; + tp.try_add(code, sa); + tp.try_add(code, sna); + } else { + // 5.4.41 is an apavAda to 5.3.66. + tp.try_add("5.3.66", rUpap); + } + }); + + // Condition is "sankhya" or ekavacana. So, just accept everything. + tp.try_add("5.4.43", Sas); + tp.try_add("5.4.44", tasi); + tp.with_context(AbhutaTadbhava, |tp| { tp.optional_try_add("5.4.52", sAti); tp.optional_try_add("5.4.55", trA); @@ -159,8 +222,5 @@ pub fn run(tp: &mut TaddhitaPrakriya) { } }); - // Condition is "sankhya" or ekavacana. So, just accept everything. - tp.try_add("5.4.43", Sas); - tp.try_add("5.4.44", tasi); - tp.try_add("5.4.52", sAti); + // 5.4.68 starts the samAsAnta-prakarana. } diff --git a/vidyut-prakriya/src/taddhita/utils.rs b/vidyut-prakriya/src/taddhita/utils.rs index 4c6cbeb..cbd287c 100644 --- a/vidyut-prakriya/src/taddhita/utils.rs +++ b/vidyut-prakriya/src/taddhita/utils.rs @@ -1,6 +1,7 @@ use crate::args::{Artha, Taddhita, TaddhitaArtha}; use crate::core::Tag as T; use crate::core::Term; +use crate::core::TermView; use crate::core::{Prakriya, Rule}; use crate::it_samjna; @@ -51,6 +52,10 @@ impl<'a> TaddhitaPrakriya<'a> { self.p.get(self.i_prati).expect("present") } + pub fn nyap_pratipadika(&self) -> TermView { + self.p.nyapu_pratipadika(self.i_prati).expect("present") + } + /// Runs the rules in `closure` under the meaning condition defined in `artha`. /// /// Calls to `with_context` can be nested. @@ -105,12 +110,14 @@ impl<'a> TaddhitaPrakriya<'a> { let rule = rule.into(); if cfg!(debug_assertions) { + /* self.p.debug(format!( "Try {}: {} + {:?}", rule.code(), &self.prati().text, taddhita, )); + */ } self.had_match = true; diff --git a/vidyut-prakriya/src/tin_pratyaya.rs b/vidyut-prakriya/src/tin_pratyaya.rs index 4a89895..3ace1b4 100644 --- a/vidyut-prakriya/src/tin_pratyaya.rs +++ b/vidyut-prakriya/src/tin_pratyaya.rs @@ -148,7 +148,7 @@ fn maybe_do_lot_only_siddhi(p: &mut Prakriya, i: usize) -> Option<()> { t.remove_tag(T::pit); }); - if p.has_tag(T::Chandasi) { + if p.is_chandasi() { p.optional_run_at("3.4.88", i, op::add_tag(T::Pit)); } } else if tin.ends_with("mi") { @@ -162,7 +162,7 @@ fn maybe_do_lot_only_siddhi(p: &mut Prakriya, i: usize) -> Option<()> { p.run_at("3.4.93", i, op::antya("E")); } else if tin.ends_with("se") || tin.ends_with("ve") { p.run_at("3.4.91", i, |t| { - let n = t.text.len(); + let n = t.len(); if t.ends_with("se") { t.text.replace_range(n - 2.., "sva"); } else { diff --git a/vidyut-prakriya/src/tripadi/pada_8_2.rs b/vidyut-prakriya/src/tripadi/pada_8_2.rs index 2c14634..684669a 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_2.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_2.rs @@ -2,9 +2,7 @@ use crate::args::Gana; use crate::core::char_view::{get_at, get_term_and_offset_indices, xyz, CharPrakriya}; use crate::core::iterators::xy_rule; use crate::core::operators as op; -use crate::core::Prakriya; -use crate::core::Tag as T; -use crate::core::Term; +use crate::core::{Prakriya, Rule, Tag as T, Term}; use crate::dhatu_gana; use crate::sounds as al; use crate::sounds::{map, s, Map, Set}; @@ -29,7 +27,7 @@ lazy_static! { static ref HAL: Set = s("hal"); } -fn do_ru_adesha(rule: &'static str, p: &mut Prakriya, i: usize) { +fn do_ru_adesha(rule: impl Into, p: &mut Prakriya, i: usize) { p.run_at(rule, i, |t| { t.set_antya("ru~"); t.add_tag(T::Ru); @@ -64,11 +62,15 @@ fn try_na_lopa(p: &mut Prakriya) -> Option<()> { let mut blocked = false; let sup = p.pratyaya(i_prati + 1)?; - if sup.has_tag(T::Sambuddhi) || sup.has_u("Ni") { + if sup.last().is_sambuddhi() || sup.has_u("Ni") { if p.has_tag(T::Napumsaka) { // "vA napuMsakAnAm" // (nAman, nAma) blocked = p.optional_run("8.2.8.v1", |_| {}); + } else if sup.has_u("Ni") && p.find_next_where(i_prati, |t| t.is_samasa()).is_some() + { + // carmatilaH, ... + p.step(Rule::Varttika("8.2.8", "1")); } else { // sambuddhi: yogin, Atman // ni: vyoman, Sarman, etc. (vedic) @@ -77,9 +79,12 @@ fn try_na_lopa(p: &mut Prakriya) -> Option<()> { } } - if !blocked { + let prati = p.get(i_prati)?; + if !blocked && !prati.is_upasarga() { // rAjA, rAjaByAm, ... // (these can be called `pada` by 1.4.17. + // HACK to ignore upasargas for unnI, due to multiple passes of + // tripadi. The real fix is to run the tripadi exactly once. p.run_at("8.2.7", i_prati, op::antya("")); } } @@ -261,7 +266,7 @@ fn try_lopa_of_samyoganta_and_s(p: &mut Prakriya) -> Option<()> { for i in i_term..p.terms().len() { let start = if i == i_term { i_offset } else { 0 }; let cur = p.get(i).expect("ok"); - for j in start..cur.text.len() { + for j in start..cur.len() { let x = cur.text.as_bytes()[j] as char; if HAL.contains(x) { num_hals += 1; @@ -275,7 +280,7 @@ fn try_lopa_of_samyoganta_and_s(p: &mut Prakriya) -> Option<()> { { return true; } - if num_hals >= 2 && j == cur.text.len() - 1 && p.is_pada(i) { + if num_hals >= 2 && j == cur.len() - 1 && p.is_pada(i) { return true; } } @@ -469,13 +474,20 @@ fn per_term_1a(p: &mut Prakriya) -> Option<()> { Some(()) } +/// A simple for-loop that allows `?` in the loop body. +fn for_each(p: &mut Prakriya, func: impl Fn(&mut Prakriya, usize) -> Option<()>) { + for i in 0..p.terms().len() { + func(p, i); + } +} + fn per_term_1b(p: &mut Prakriya) -> Option<()> { for i in 0..p.terms().len() { let x = p.get(i)?; let if_y = match p.find_next_where(i, |t| !t.is_empty()) { Some(i_y) => { let y = p.get(i_y)?; - let is_sdhvoh = y.has_adi('s') || (y.is_pratyaya() && y.text.starts_with("Dv")); + let is_sdhvoh = y.has_adi('s') || (y.is_pratyaya() && y.starts_with("Dv")); is_sdhvoh || p.is_pada(i) } None => true, @@ -489,19 +501,22 @@ fn per_term_1b(p: &mut Prakriya) -> Option<()> { } } - // Blocks 8.2.39 so must appear first. - try_rutva(p); - // Exclude the following from 8.2.39 so that the corresponding rules aren't // vyartha: // - s for 8.2.66 (sasajuSo ruH) for i in 0..p.terms().len() { - let c = p.get(i)?; + // HACK to avoid re-processing catuzwaya when deriving catuzwayI. Likewise for catuzpAd + let c = p.get_if(i, |t| { + !(t.is_final() && p.has(i + 1, |t| t.is_taddhita() || (t.is_sup() && t.is_lupta()))) + }); + if c.is_none() { + continue; + } + let c = c.expect("ok"); + // HACK to exclude erroneous sandhi on (upa -> up -> ub) let is_pada = p.is_pada(i) && !(c.is_upasarga() && !c.has_u("ud")); - let has_exception = c.has_antya(&*JHAL_TO_JASH_EXCEPTIONS) - // HACK to exclude "z" of pipaWiz, etc. - || (c.has_u("san") && c.has_text("z")); + let has_exception = c.has_antya(&*JHAL_TO_JASH_EXCEPTIONS) || is_sa_sajush(p, i); if c.has_antya(&*JHAL) && !has_exception && is_pada { let key = c.antya()?; @@ -510,26 +525,27 @@ fn per_term_1b(p: &mut Prakriya) -> Option<()> { } } - xy_rule( - p, - |x, y| { - x.is_dhatu() - && !x.has_u("quDA\\Y") - && x.has_antya(&*JHAZ) - && (y.has_adi('t') || y.has_adi('T')) - }, - |p, _, j| { - p.run_at("8.2.40", j, op::adi("D")); - }, - ); + for_each(p, |p, i_x| { + if is_sa_sajush(p, i_x) { + return None; + } - xy_rule( - p, - |x, y| (x.has_antya('z') || x.has_antya('Q')) && y.has_adi('s'), - |p, i, _| { - p.run_at("8.2.41", i, op::antya("k")); - }, - ); + let x = p.get_if(i_x, |t| !t.is_empty())?; + let i_y = p.find_next_not_empty(i_x)?; + let y = p.get(i_y)?; + + if x.is_dhatu() + && !x.has_u("quDA\\Y") + && x.has_antya(&*JHAZ) + && (y.has_adi('t') || y.has_adi('T')) + { + p.run_at("8.2.40", i_y, op::adi("D")); + } else if (x.has_antya('z') || x.has_antya('Q')) && y.has_adi('s') { + p.run_at("8.2.41", i_x, op::antya("k")); + } + + Some(()) + }); Some(()) } @@ -564,7 +580,8 @@ fn run_rules_for_nistha_t(p: &mut Prakriya) -> Option<()> { p.run(code, op::nipatana("kzIba")); } else if dhatu.has_text("kfS") && !has_upasarga { p.run(code, op::nipatana("kfSa")); - } else if dhatu.has_text("lAG") && i_d == 1 && p.has(0, |t| t.has_u("ud")) { + } else if dhatu.has_text("lAG") && i_d == 2 && p.has_prev_non_empty(i_d, |t| t.has_u("ud")) + { p.run(code, op::nipatana("ullAGa")); } @@ -641,8 +658,9 @@ fn run_rules_for_nistha_t(p: &mut Prakriya) -> Option<()> { } else if dhatu.has_u("ancu~") { optional_to_n("8.2.48", p); } else if dhatu.has_text("dyU") { + // dyUna, dyUta optional_to_n("8.2.49", p); - } else if dhatu.has_text("vA") && i_d > 0 && p.has(i_d - 1, |t| t.has_text_in(&["nis", "nir"])) + } else if dhatu.has_text("vA") && p.has_prev_non_empty(i_d, |t| t.has_text_in(&["nis", "nir"])) { // TODO: include both "nis" and "nir" ? optional_to_n("8.2.50", p); @@ -656,7 +674,8 @@ fn run_rules_for_nistha_t(p: &mut Prakriya) -> Option<()> { } else if dhatu.has_text("kzA") { // kzAma set_adi("8.2.53", p, "m"); - } else if dhatu.has_text("stI") && i_d > 0 && p.has(i_d - 1, |t| t.has_u("pra")) { + } else if dhatu.has_text("stI") && p.has_prev_non_empty(i_d, |t| t.has_u("pra")) { + // prastIma, prastyAma p.optional_run_at("8.2.54", i_k, |t| t.set_adi("m")); } @@ -669,7 +688,11 @@ fn run_misc_rules_2(p: &mut Prakriya) -> Option<()> { let t = p.get(i)?; if t.is_dhatu() && p.has(i + 1, |t| t.has_u("kvi~n")) { // Gftaspfk, ... - let sub = if t.has_antya('n') { "N" } else { "k" }; + let sub = if t.has_antya('n') || t.has_antya('Y') { + "N" + } else { + "k" + }; p.run_at("8.2.62", i, |t| t.set_antya(sub)); } else if t.is_dhatu() && t.has_u("Ra\\Sa~") && p.has(i + 1, |t| t.has_u("kvi~p")) { // nak, naw @@ -689,61 +712,54 @@ fn run_misc_rules_2(p: &mut Prakriya) -> Option<()> { Some(()) } -// acakAs + t -> acakAt -// acakAs + s -> acakAH, acakAt -fn try_add_final_r_with_final_tin(p: &mut Prakriya) -> Option<()> { - // Exception to general rule 8.2.66 below. - let n = p.terms().len(); - if n < 2 { - return None; - } - - let i_dhatu = p.find_last_where(|t| t.is_dhatu() && !t.is_empty())?; - if p.find_next_where(i_dhatu, |t| !t.is_empty()).is_some() { - // For these rules, the dhatu must be at the end of the pada. - return None; - } - - let i_tin = n - 1; - - let dhatu = p.get(i_dhatu)?; - let tin = p.get_if(i_tin, |t| t.is_empty())?; +/// Trigger for 8.2.66. +/// +/// This is in its own function so that we can check it as part of 8.2.39. +fn is_sa_sajush(p: &Prakriya, i: usize) -> bool { + let t = p.get(i).expect("present"); + // Add extra `z` check to avoid expensive call to `has_pratipadika`. + t.has_antya('s') || (t.has_antya('z') && p.has_pratipadika(i, "sajuz")) +} - // FIXME: sloppy. Also, exclude "asti" for Vedic "AH". - if dhatu.has_antya('s') && tin.has_u("tip") { - p.run_at("8.2.73", i_dhatu, op::antya("d")); - } else if (dhatu.has_antya('s') || dhatu.has_antya('d')) && tin.has_u("sip") { - if dhatu.has_antya('s') { - // acakAs + s -> acakAH, acakAt, acakAd - p.optional_run_at("8.2.74", i_dhatu, op::antya("d")); - } else { - // aruRad + s -> aruRaH, aruRat, aruRad - if p.optional_run_at("8.2.75", i_dhatu, op::antya("ru~")) { - // Delete nasal vowel of "ru~". - p.run_at("1.3.2", i_dhatu, |t| { - t.set_antya(""); - t.set_antya(""); - }); +fn try_change_final_s(p: &mut Prakriya) -> Option<()> { + for i in 0..p.terms().len() { + let t = p.get(i)?; + + let is_pada = p.is_pada(i); + let is_tinanta = p.terms().last().map_or(false, |t| t.is_tin()); + if is_pada && t.is_dhatu() && is_tinanta { + let dhatu = t; + let tin = p.terms().last()?; + if dhatu.has_antya('s') && tin.has_u("tip") && !dhatu.has_u("asa~") { + // acakAt, ... + p.run_at("8.2.73", i, op::antya("d")); + } else if (dhatu.has_antya('s') || dhatu.has_antya('d')) && tin.has_u("sip") { + if dhatu.has_antya('s') { + // acakAs + s -> acakAH, acakAt, acakAd + p.optional_run_at("8.2.74", i, op::antya("d")); + } else { + // aruRad + s -> aruRaH, aruRat, aruRad + p.optionally("8.2.75", |rule, p| { + do_ru_adesha(rule, p, i); + }); + } } } - } - - Some(()) -} - -fn try_rutva(p: &mut Prakriya) -> Option<()> { - try_add_final_r_with_final_tin(p); - for i in 0..p.terms().len() { - let term = p.get(i)?; - - // for pipaWiz -> pipaWIH. This "z" is asiddha, but our code isn't smart enough to - // detect that. - let hacky_is_s_san = term.has_text("z") && term.has_u("san"); - let is_sa = term.has_antya('s') || hacky_is_s_san; - let is_sajush = p.has_pratipadika(i, "sajuz"); - if p.is_pada(i) && (is_sa || is_sajush) { - do_ru_adesha("8.2.66", p, i); + let t = p.get(i)?; + if is_pada { + let is_sa_sajush = is_sa_sajush(p, i); + + if (is_sa_sajush && t.has_u_in(&["kvasu~", "vasu~", "sransu~\\", "Dvansu~\\"])) + // See Kashika discussion for why we allow anaqvAn. + || (t.has_u("anaquh") && !t.has_antya('n')) + { + // vidvadByAm, uKAsradByAm, ... + p.run_at("8.2.72", i, |t| t.set_antya("d")); + } else if is_sa_sajush { + // agnir atra, sajUr ftuBiH, ... + do_ru_adesha("8.2.66", p, i); + } } } @@ -751,8 +767,6 @@ fn try_rutva(p: &mut Prakriya) -> Option<()> { } fn try_add_final_r(p: &mut Prakriya) -> Option<()> { - try_add_final_r_with_final_tin(p); - // 6.1.113 and 6.1.114 are not part of the tripAdi, but they have no scope to apply otherwise. xy_rule( p, @@ -782,56 +796,60 @@ fn try_add_final_r(p: &mut Prakriya) -> Option<()> { } /// (8.2.76 - 8.2.79) -fn try_lengthen_dhatu_vowel(p: &mut Prakriya) -> Option<()> { - let i = p.find_first_where(|t| t.is_dhatu())?; - let i_last = p.find_last_where(|t| t.is_dhatu())?; - let i_n = p.find_next_where(i, |t| !t.is_empty()); - - let is_rv = |opt| match opt { - Some(c) => c == 'r' || c == 'v', - None => false, - }; - let is_ik = |opt| match opt { - Some(c) => al::is_hrasva(c) && IK.contains(c), - None => false, - }; - let is_hal = |opt| match opt { - Some(c) => al::is_hal(c), - None => false, - }; - let before_upadha = |t: &Term| t.text.chars().rev().nth(2); - let dhatu = p.get(i)?; - // Use a view for pipaWiH -> pipaWIH (pi + paW + i + z) - let dhatu_view = p.custom_view(i, i_last)?; - - // karotereva tatra grahaRAd ityAhuH (SK 2536) - // TODO: bha - if dhatu.has_text("Cur") || (dhatu.has_text("kur") && dhatu.has_u("qukf\\Y")) { - p.step("8.2.79"); - } else if is_ik(dhatu_view.upadha()) && is_rv(dhatu_view.antya()) && p.is_pada(i_last) { - // pipaWIH, ... - let sub = al::to_dirgha(dhatu_view.upadha()?)?; - p.run("8.2.76", |p| { - p.set_upadha_within_range(i, i_last, &sub.to_string()); - }); - } else if is_ik(dhatu.upadha()) && is_rv(dhatu.antya()) { - let sub = al::to_dirgha(dhatu.upadha()?)?; - if p.has(i_n?, |t| t.has_adi(&*HAL)) { - p.run_at("8.2.77", i, op::upadha(&sub.to_string())); - } - } else if is_ik(before_upadha(dhatu)) && is_rv(dhatu.upadha()) && is_hal(dhatu.antya()) { - let pre_upadha = before_upadha(dhatu)?; - let sub = al::to_dirgha(pre_upadha)?.to_string(); - p.run("8.2.78", |p| { - let dhatu = &p.terms()[i]; - let n = dhatu.text.len(); - p.set(i, |t| { - t.text = CompactString::from(&t.text[..n - 3]) + &sub + &t.text[n - 2..] +fn try_lengthen_dhatu_vowel(p: &mut Prakriya) { + iter_terms(p, |p, i| { + let dhatu = p.get_if(i, |t| t.is_dhatu())?; + let i_n = p.find_next_where(i, |t| !t.is_empty()); + + let is_rv = |opt| match opt { + Some(c) => c == 'r' || c == 'v', + None => false, + }; + let is_ik = |opt| match opt { + Some(c) => al::is_hrasva(c) && IK.contains(c), + None => false, + }; + let is_hal = |opt| match opt { + Some(c) => al::is_hal(c), + None => false, + }; + let before_upadha = |t: &Term| t.chars().rev().nth(2); + // Use a view for pipaWiH -> pipaWIH (pi + paW + i + z) + let dhatu_view = if dhatu.is_pratyaya() { + p.custom_view(0, i)? + } else { + p.custom_view(i, i)? + }; + + // karotereva tatra grahaRAd ityAhuH (SK 2536) + // TODO: bha + if dhatu.has_text("Cur") || (dhatu.has_text("kur") && dhatu.has_u("qukf\\Y")) { + p.step("8.2.79"); + } else if is_ik(dhatu_view.upadha()) && is_rv(dhatu_view.antya()) { + if p.is_pada(i) { + // pipaWIH, ... + let sub = al::to_dirgha(dhatu_view.upadha()?)?; + p.run("8.2.76", |p| { + p.set_upadha_within_range(0, i, &sub.to_string()); + }); + } else if p.has(i_n?, |t| t.has_adi(&*HAL)) { + let sub = al::to_dirgha(dhatu.upadha()?)?; + p.run_at("8.2.77", i, op::upadha(&sub.to_string())); + } + } else if is_ik(before_upadha(dhatu)) && is_rv(dhatu.upadha()) && is_hal(dhatu.antya()) { + let pre_upadha = before_upadha(dhatu)?; + let sub = al::to_dirgha(pre_upadha)?.to_string(); + p.run("8.2.78", |p| { + let dhatu = &p.terms()[i]; + let n = dhatu.len(); + p.set(i, |t| { + t.text = CompactString::from(&t.text[..n - 3]) + &sub + &t.text[n - 2..] + }); }); - }); - } + } - Some(()) + Some(()) + }); } /// (8.2.80) @@ -912,6 +930,7 @@ pub fn run(p: &mut Prakriya) { run_misc_rules_2(p); // 8.2.66 -- 8.2.75 + try_change_final_s(p); try_add_final_r(p); // 8.2.77 - 8.2.79 try_lengthen_dhatu_vowel(p); diff --git a/vidyut-prakriya/src/tripadi/pada_8_3.rs b/vidyut-prakriya/src/tripadi/pada_8_3.rs index 1ff4be8..a0be01b 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_3.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_3.rs @@ -12,6 +12,7 @@ use crate::sounds::{s, Set}; use lazy_static::lazy_static; lazy_static! { + static ref IN1: Set = s("iR"); static ref IN2: Set = s("iR2"); static ref IN_KU: Set = s("iR2 ku~"); static ref KU_PU: Set = s("ku~ pu~"); @@ -43,7 +44,7 @@ fn try_ra_lopa(p: &mut Prakriya) -> Option<()> { continue; } - if p.has(i + 1, |t| t.has_adi('r')) { + if p.has_next_non_empty(i, |t| t.has_adi('r')) { p.run_at("8.3.14", i, op::antya("")); let c = p.get(i)?; if c.is_hrasva() { @@ -71,7 +72,7 @@ fn try_ra_lopa(p: &mut Prakriya) -> Option<()> { |x, y| { x.has_antya('r') && x.has_tag(T::Ru) - && (x.has_text_in(&["Bo", "Bago", "aGo"]) || x.has_upadha(&*AA)) + && (x.has_u_in(&["Bos", "Bagos", "aGos"]) || x.has_upadha(&*AA)) && y.has_adi(&*ASH) }, |p, i, j| { @@ -117,7 +118,7 @@ fn try_mn_to_anusvara(p: &mut Prakriya) -> Option<()> { |p, _, i| { if let Some((i_term, i_offset)) = get_term_and_offset_indices(p, i) { let t = p.get(i_term).expect("ok"); - if t.is_pada() && i_offset + 1 == t.text.len() { + if t.is_pada() && i_offset + 1 == t.len() { false } else if t.has_text("pums") && !p.has(i_term + 1, |t| t.is_pada()) { // Don't make this change for "m" in a pratipadika, so that we can derive @@ -173,21 +174,26 @@ fn try_visarjaniyasya(p: &mut Prakriya) -> Option<()> { } else if y.has_at(1, &*SHAR) { p.run_at("8.3.35", i_x, |_| {}); } else if y.has_adi(&*KU_PU) { - if x.has_text_in(&["namas", "puras"]) && x.has_tag(T::Gati) { + if x.has_text_in(&["namas", "puras"]) && x.is_gati() { p.run_at("8.3.40", i_x, |t| t.set_antya("s")); } else if is_it_ut_upadha(x) && !x.is_pratyaya() { p.run_at("8.3.41", i_x, |t| t.set_antya("z")); - } else if x.has_text("tiras") && x.has_tag(T::Gati) { + } else if x.has_u("tiras") && x.is_gati() { p.optional_run_at("8.3.42", i_x, |t| t.set_antya("s")); - } else if x.text.ends_with("aH") - && is_samasa(p, i_x) - && !x.is_avyaya() - && y.has_u("qukf\\Y") + } else if x.ends_with("aH") && is_samasa(p, i_x) && !x.is_avyaya() && y.has_u("qukf\\Y") { p.run_at("8.3.46", i_x, |t| t.set_antya("s")); } else if x.has_text("BAH") && y.has_text("kar") { // TODO: rest of kaskAdi p.run_at("8.3.48", i_x, |t| t.set_antya("s")); + } else if x.has_tag(T::Ru) && y.is_pratyaya() { + if x.has_antya(&*IN1) { + // sarpizpASam, ... + p.run_at("8.3.39", i_x, |t| t.set_antya("z")); + } else { + // yaSaskAmyati, svaHkAmyati, + p.run_at("8.3.38", i_x, |t| t.set_antya("s")); + } } else { // TODO: jihvamuliya and upadhmaniya p.run_at("8.3.37", i_x, |t| t.set_antya("H")); @@ -229,8 +235,16 @@ impl<'a> ShaPrakriya<'a> { self.p.get(self.i_term).expect("ok") } + fn i_prev(&self) -> Option { + self.p.find_prev_where(self.i_term, |t| !t.is_empty()) + } + fn has_upasarga_in(&self, text: &[&str]) -> bool { - self.i_term > 0 && self.p.has(self.i_term - 1, |t| t.has_text_in(text)) + if let Some(i_prev) = self.i_prev() { + self.p.has(i_prev, |t| t.has_text_in(text)) + } else { + false + } } fn try_block(&mut self, rule: Code) { @@ -356,12 +370,12 @@ fn run_shatva_rules_at_char_index(sp: &mut ShaPrakriya, text: &str) -> Option<() let i_upasarga = maybe_i_upasarga?; // No gap between upasarga and dhatu. - let no_vyavaya = i_upasarga + 1 == sp.i_term; + let no_vyavaya = i_upasarga + 2 == sp.i_term; // Gap between upasarga and dhatu is just an abhyasa. - let at_vyavaya = i_upasarga + 2 == sp.i_term - && sp.p.has(i_upasarga + 1, |t| t.is_agama() && t.has_u("aw")); + let at_vyavaya = i_upasarga + 3 == sp.i_term + && sp.p.has(i_upasarga + 2, |t| t.is_agama() && t.has_u("aw")); let abhyasa_vyavaya = - i_upasarga + 2 == sp.i_term && sp.p.has(i_upasarga + 1, |t| t.is_abhyasa()); + i_upasarga + 3 == sp.i_term && sp.p.has(i_upasarga + 2, |t| t.is_abhyasa()); // Check both upadesha and gana to avoid matching dhatus in other ganas. const SU_TO_STUBH: &[(&str, Gana)] = &[ @@ -567,7 +581,8 @@ fn run_shatva_rules_at_char_index(sp: &mut ShaPrakriya, text: &str) -> Option<() let shan = sp.p.find_next_where(sp.i_term, |t| t.has_u("san") && t.has_adi('z')); - if shan.is_some() { + // Check !is_pratyaya to allow "titik[z]izate" + if shan.is_some() && !term.is_pratyaya() { let nau = sp.p.has(sp.i_term + 1, |t| t.is_ni_pratyaya()); // Prefer `has_u_in` over `has_text_in` because `has_u_in` is more reliable and doesn't @@ -617,8 +632,7 @@ fn run_shatva_rules_at_char_index(sp: &mut ShaPrakriya, text: &str) -> Option<() let is_first_s_of_term = if sp.i_term == 0 { sp.i_char == 0 } else { - let num_chars_before: usize = - sp.p.terms()[..sp.i_term].iter().map(|t| t.text.len()).sum(); + let num_chars_before: usize = sp.p.terms()[..sp.i_term].iter().map(|t| t.len()).sum(); num_chars_before == sp.i_char }; let t = sp.p.get(sp.i_term)?; @@ -668,7 +682,7 @@ fn run_shatva_rules(p: &mut Prakriya) -> Option<()> { // 8.3.61. // // Use a `bytes()` iterator because `chars()` doesn't support `.enumerate().rev()` - let text = p.text(); + let text = p.compact_text(); for (i, c) in text.bytes().enumerate().rev() { if (c as char) == 's' { let mut sp = ShaPrakriya::new(p, i); diff --git a/vidyut-prakriya/src/tripadi/pada_8_4.rs b/vidyut-prakriya/src/tripadi/pada_8_4.rs index f00fcc5..f81d178 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_4.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_4.rs @@ -3,9 +3,7 @@ use crate::core::char_view::{ get_term_and_offset_indices, get_term_index_at, xy, xyz, CharPrakriya, }; use crate::core::operators as op; -use crate::core::Prakriya; -use crate::core::Tag as T; -use crate::core::Term; +use crate::core::{Prakriya, Rule, Tag as T, Term}; use crate::sounds as al; use crate::sounds::{map, s, Map, Set}; use lazy_static::lazy_static; @@ -97,7 +95,7 @@ fn try_natva_for_span(p: &mut Prakriya, text: &str, i_rs: usize, i_n: usize) -> } */ - if i_x != i_y && x.is_pada() && x.has_antya('z') { + if i_x != i_y && p.is_pada(i_x) && x.has_antya('z') { // nizpAna, ... p.step("8.4.35"); } else if y.has_u("Ra\\Sa~") && (y.has_antya('z') || y.has_antya('k')) { @@ -197,10 +195,13 @@ fn try_natva_for_span(p: &mut Prakriya, text: &str, i_rs: usize, i_n: usize) -> || (t.has_tag(T::Pada) && !t.is_pratipadika() && !t.is_nyap_pratyaya()) }); // Allow "carman -> carmaRA" but disallow "sruGna -> *sruGRa" - let is_exempt_pratipadika = p.has(i_x, |t| t.text.starts_with("srOGn")); + let is_exempt_pratipadika = p.has(i_x, |t| t.starts_with("srOGn")); if is_samana_pada && !is_exempt_pratipadika { // TODO: track loctaion of rzfF for better rule logging. p.run("8.4.2", |p| p.set_char_at(i_n, "R")); + } else if x.has_text_in(&["grAma", "agra"]) && y.has_u("RI\\Y") { + // See Kashika on 3.2.61 and SK 2975. + p.run(Rule::Kaumudi("2975"), |p| p.set_char_at(i_n, "R")); } } @@ -215,7 +216,7 @@ fn try_natva_for_span(p: &mut Prakriya, text: &str, i_rs: usize, i_n: usize) -> /// (8.4.1 - 8.4.39) fn run_natva_rules(p: &mut Prakriya) { - let text = p.text(); + let text = p.compact_text(); for (i_rs, i_n) in find_natva_spans(&text) { try_natva_for_span(p, &text, i_rs, i_n); } @@ -278,14 +279,19 @@ fn try_change_stu_to_parasavarna(cp: &mut CharPrakriya) { } }, ); + + const WU: Set = Set::from("wWqQR"); cp.for_chars( xy(|x, y| (STU.contains(x) && SWU.contains(y)) || (SWU.contains(x) && STU.contains(y))), |p, text, i| { let x = text.as_bytes()[i] as char; let y = text.as_bytes()[i + 1] as char; let i_term = get_term_index_at(p, i).expect("defined"); - let prev = p.get(i_term).expect("defined"); - if p.is_pada(i_term) && prev.has_antya(&*SWU) { + let t_x = p.get(i_term).expect("defined"); + if p.is_pada(i_term) + && t_x.has_antya(WU) + && !p.has(i_term + 2, |t| t.is_vibhakti() && t.has_u("Am")) + { p.step("8.4.42"); false } else if TU.contains(x) && y == 'z' { @@ -310,7 +316,7 @@ fn try_change_stu_to_parasavarna(cp: &mut CharPrakriya) { /// /// This rule is in section 8.3, but it has scope to apply only if it follows 8.4.41. fn try_dha_lopa(cp: &mut CharPrakriya) { - cp.for_terms( + cp.for_non_empty_terms( |x, y| x.has_antya('Q') && y.has_adi('Q'), |p, i, _| { p.run_at("8.3.13", i, op::antya("")); @@ -332,9 +338,12 @@ fn try_dha_lopa(cp: &mut CharPrakriya) { } fn try_to_anunasika(cp: &mut CharPrakriya) { - cp.for_terms( - |x, y| x.is_pada() && x.has_antya(&*YAR) && y.has_adi(&*ANUNASIKA), - |p, i, _| { + cp.for_terms(|p, i| { + let j = p.find_next_where(i, |t| !t.is_empty())?; + let x = p.get_if(i, |t| !t.is_empty())?; + let y = p.get(j)?; + + if p.is_pada(i) && x.has_antya(&*YAR) && y.has_adi(&*ANUNASIKA) { let x = p.get(i).expect("defined"); // For now, apply the rule to just these sounds. let sub = match x.antya().expect("ok") { @@ -350,8 +359,10 @@ fn try_to_anunasika(cp: &mut CharPrakriya) { // By convention, this rule is always applied in classical Sanskrit. p.run_at("8.4.45", i, |t| t.set_antya(sub)); } - }, - ); + } + + Some(()) + }); } fn try_jhal_adesha(cp: &mut CharPrakriya) -> Option<()> { @@ -369,7 +380,7 @@ fn try_jhal_adesha(cp: &mut CharPrakriya) -> Option<()> { }, ); - cp.for_terms( + cp.for_non_empty_terms( // Check for jaz-car to avoid applying a rule that causes no changee. |x, _| x.is_abhyasa() && x.has_adi(&*JHAL) && !x.has_adi(&*JASH_CAR), |p, i, _| { @@ -383,18 +394,18 @@ fn try_jhal_adesha(cp: &mut CharPrakriya) -> Option<()> { ); // 8.2.38, but indicated here by use of "dadhas" in the rule. - cp.for_terms( + cp.for_non_empty_terms( |x, y| { x.has_u("quDA\\Y") && x.has_text_in(&["D", "d"]) && (y.has_adi('t') || y.has_adi('T') || y.has_adi('s') - || (y.is_pratyaya() && y.text.starts_with("Dv"))) + || (y.is_pratyaya() && y.starts_with("Dv"))) }, |p, i, _| { - p.set(i - 1, |t| t.text.replace_range(.., "Da")); - p.set(i, |t| t.text.replace_range(.., "d")); + p.set(i - 1, |t| t.set_text("Da")); + p.set(i, |t| t.set_text("d")); p.step("8.2.38") }, ); @@ -463,7 +474,7 @@ fn try_to_savarna(cp: &mut CharPrakriya) { true }); - cp.for_terms( + cp.for_non_empty_terms( // TODO: which stanbh-dhAtus should we include? |x, y| { x.is_upasarga() diff --git a/vidyut-prakriya/src/uttarapade.rs b/vidyut-prakriya/src/uttarapade.rs index d4287df..0f75e0d 100644 --- a/vidyut-prakriya/src/uttarapade.rs +++ b/vidyut-prakriya/src/uttarapade.rs @@ -5,6 +5,7 @@ use crate::args::Artha; use crate::args::TaddhitaArtha; use crate::core::operators as op; use crate::core::Prakriya; +use crate::core::Rule::Varttika; use crate::core::Tag as T; use crate::core::Term; use crate::sounds as al; @@ -35,11 +36,48 @@ pub fn run(p: &mut Prakriya) -> Option<()> { // TODO: calculate this properly. let i_purva = 0; - let i_uttara = p.find_next_where(i_purva, |t| !t.is_empty())?; + let i_purva_sup = i_purva + 1; + let i_uttara = p.find_next_where(i_purva, |t| !t.is_sup() && !t.is_empty())?; let purva = p.get(i_purva)?; let uttara = p.get(i_uttara)?; - if purva.has_text("mahat") + if p.is_panchami_tatpurusha() { + // kta-pratyaya is generally available in panchami-tatpurusha only in the sense of "stokAntika" etc., so check for kta. + if p.find_next_where(i_uttara, |t| t.has_u("kta")).is_some() { + // stokAnmukta, ... + p.add_tag_at("6.3.2", i_purva_sup, T::Aluk); + } + } else if p.is_trtiya_tatpurusha() { + if purva.has_text_in(&["ojas", "sahas", "amBas", "tamas"]) { + // ojasAkfta, ... + p.add_tag_at("6.3.3", i_purva_sup, T::Aluk); + } + } else if p.is_caturthi_tatpurusha() { + if purva.has_text("Atman") && uttara.has_text("pada") { + // Atmanepada + p.add_tag_at("6.3.7", i_purva_sup, T::Aluk); + } else if purva.has_text("para") && uttara.has_text("pada") { + // parasmEpada + p.add_tag_at("6.3.8", i_purva_sup, T::Aluk); + } + } else if p.is_saptami_tatpurusha() { + if purva.has_text("maDya") && uttara.has_text("guru") { + // maDyeguru + p.add_tag_at("6.3.11", i_purva_sup, T::Aluk); + } else if purva.has_text("anta") && uttara.has_text("guru") { + // anteguru + p.add_tag_at("6.3.11.v1", i_purva_sup, T::Aluk); + } else if purva.has_text_in(&["prAvfz", "Sarad", "kAla", "div"]) && uttara.has_text("ja") { + // prAvfzija, ... + p.add_tag_at("6.3.15", i_purva_sup, T::Aluk); + } else if purva.has_text_in(&["varza", "kzara", "Sara", "vara"]) && uttara.has_text("ja") { + // varzeja, varzaja + p.optional_add_tag_at("6.3.16", i_purva_sup, T::Aluk); + } else if uttara.has_text("sTa") && !p.is_chandasi() { + // kUwasTa, ... + p.step("6.3.20"); + } + } else if purva.has_text("mahat") && (p.has_tag_in(&[T::Karmadharaya, T::Bahuvrihi]) || uttara.has_text("jAtIya")) { p.run_at("6.3.46", i_purva, |t| t.set_antya("A")); @@ -57,8 +95,66 @@ pub fn run(p: &mut Prakriya) -> Option<()> { let purva = p.get(i_purva)?; let uttara = p.get(i_uttara)?; - if purva.is_sarvanama() && uttara.has_text_in(&["dfS"]) { + let is_drk_drsha_vatu = || uttara.has_text_in(&["dfS"]) || uttara.has_u("vatu~p"); + + if purva.has_u("naY") { + p.run_at("6.3.73", i_purva, |t| t.set_text("a")); + + let uttara = p.get(i_uttara)?; + if uttara.has_adi(&*AC) { + p.run_at("6.3.74", i_uttara, |t| t.text.insert(0, 'n')); + } + } else if purva.has_text("samAna") { + if uttara.has_text_in(&[ + "jyotis", "janapada", "rAtri", "nABi", "nAman", "gotra", "rUpa", "sTAna", "varRa", + "vayas", "vacana", "banDu", + ]) { + // sajyotiH, ... + p.run_at("6.3.85", i_purva, |t| t.set_text("sa")); + } else if uttara.has_text("tIrTa") && p.has(i_uttara + 1, |t| t.has_u("yat")) { + // satIrTya, ... + p.run_at("6.3.87", i_purva, |t| t.set_text("sa")); + } else if uttara.has_text("udara") && p.has(i_uttara + 1, |t| t.has_u("yat")) { + // sodarya, samAnodarya + p.run_at("6.3.88", i_purva, |t| t.set_text("sa")); + } else if is_drk_drsha_vatu() { + // sadfS, sadfSa + p.run_at("6.3.89", i_purva, |t| t.set_text("sa")); + } + } else if purva.has_text_in(&["idam", "kim"]) && is_drk_drsha_vatu() { + // kIdfk, Idfk, ... + let sub = if purva.has_text("idam") { "I" } else { "kI" }; + p.run_at("6.3.90", i_purva, |t| t.set_text(sub)); + } else if purva.is_sarvanama() && is_drk_drsha_vatu() { + // tAdfk, ... p.run_at("6.3.91", i_purva, |t| t.set_antya("A")); + } else if purva.has_text("ku") && p.is_tatpurusha() { + if uttara.has_text_in(&["paTin", "akza"]) { + // kApaTa, kAkza + p.run_at("6.3.104", i_purva, |t| t.set_text("kA")); + } else if uttara.has_text_in(&["raTa", "vada"]) { + // kadraTa, ... + p.run_at("6.3.102", i_purva, |t| t.set_text("kat")); + } else if uttara.has_adi(&*AC) { + // kadajaH, ... + p.run_at("6.3.101", i_purva, |t| t.set_text("kat")); + } + } else if uttara.has_u("valac") { + if purva.has_text_in(&["utsAha", "BrAtf", "pitf", "putra"]) { + // utsAhavala, ... + // TODO: "putra" not part of the varttika, but then how do we derive + // putravala? + p.step(Varttika("6.3.118", "1")); + } else { + // AsutIvala, ... + let antya = purva.antya()?; + if al::is_hrasva(antya) { + let sub = al::to_dirgha(purva.antya()?)?; + p.run_at("6.3.118", i_purva, |t| { + t.set_antya(&sub.to_string()); + }); + } + } } else if !purva.is_avyaya() && p.find_last(T::Kit).is_some() { let ajanta = al::is_ac(purva.antya()?); let i_khit = p.find_last_where(|t| t.has_tag(T::Kit))?; @@ -97,7 +193,7 @@ pub fn run(p: &mut Prakriya) -> Option<()> { Some(()) } -pub fn run_after_guna(p: &mut Prakriya) -> Option<()> { +pub fn run_after_guna_and_bhasya(p: &mut Prakriya) -> Option<()> { let i_purva = 0; let i_uttara = p.find_next_where(i_purva, |t| !t.is_empty())?; let purva = p.get(i_purva)?; @@ -121,6 +217,9 @@ pub fn run_after_guna(p: &mut Prakriya) -> Option<()> { p.run_at("6.3.124", i_purva, |t| t.set_antya(&sub.to_string())); } } + } else if uttara.has_text("c") && uttara.has_u("ancu~") { + let dirgha = al::to_dirgha(purva.antya()?)?.to_string(); + p.run_at("6.3.138", i_purva, |t| t.set_antya(&dirgha)); } else if uttara.has_text("citi") && p.has(i_uttara + 1, |t| t.has_u("kap")) { // citIka p.run_at("6.3.125", i_uttara, |t| t.set_antya("I")); diff --git a/vidyut-prakriya/src/vikarana.rs b/vidyut-prakriya/src/vikarana.rs index 04e80d9..8a9d0bc 100644 --- a/vidyut-prakriya/src/vikarana.rs +++ b/vidyut-prakriya/src/vikarana.rs @@ -419,7 +419,8 @@ fn add_sarvadhatuka_vikarana(p: &mut Prakriya) -> Option<()> { } let dhatu = p.get(i)?; - let has_upasarga = p.find_prev_where(i, |t| t.is_upasarga()).is_some(); + let i_upasarga = p.find_prev_where(i, |t| t.is_upasarga()); + let has_upasarga = i_upasarga.is_some(); // Optional cases let stanbhu_stunbhu = ["stanBu~", "stunBu~", "skanBu~", "skunBu~", "sku\\Y"]; @@ -437,7 +438,7 @@ fn add_sarvadhatuka_vikarana(p: &mut Prakriya) -> Option<()> { if !has_upasarga { // yasyati, yasati divadi_declined = !p.optional_run("3.1.71", add_vikarana("Syan")); - } else if i > 0 && p.has(i - 1, |t| t.has_u("sam")) { + } else if i > 0 && p.has(i_upasarga?, |t| t.has_u("sam")) { // saMyasyati, saMyasati divadi_declined = !p.optional_run("3.1.72", add_vikarana("Syan")); } @@ -609,7 +610,7 @@ pub fn run(p: &mut Prakriya) -> Result<()> { if let Some(i_vikarana) = p.find_first(T::Vikarana) { try_pratyaya_lopa(p); // Run it-samjna-prakarana only after the lopa phase is complete. - if p.has(i_vikarana, |t| !t.text.is_empty()) { + if p.has(i_vikarana, |t| !t.is_empty()) { it_samjna::run(p, i_vikarana)?; } } diff --git a/vidyut-prakriya/src/wasm.rs b/vidyut-prakriya/src/wasm.rs index d06a750..2948ab6 100644 --- a/vidyut-prakriya/src/wasm.rs +++ b/vidyut-prakriya/src/wasm.rs @@ -52,11 +52,13 @@ impl Rule { fn as_web_string(&self) -> String { match self { Self::Ashtadhyayi(s) => s.to_string(), - Self::Dhatupatha(s) => format!("DAtupATa {s}"), - Self::Kashika(s) => format!("kAzikA {s}"), + Self::Varttika(s, v) => format!("vArttika {s} ({v})"), + Self::Dhatupatha(s) => format!("DAtupAWa {s}"), + Self::Kashika(s) => format!("kASikA {s}"), Self::Linganushasana(s) => format!("liNgA {s}"), Self::Kaumudi(s) => format!("kOmudI {s}"), Self::Unadipatha(s) => format!("uRAdi {s}"), + Self::Phit(s) => format!("Piw {s}"), } } } @@ -67,7 +69,7 @@ fn to_web_history(history: &[Step]) -> Vec { .iter() .map(|x| WebStep { rule: x.rule().as_web_string(), - result: x.result().clone(), + result: x.result().join(" + "), }) .collect() } @@ -139,7 +141,8 @@ impl Vidyut { ) -> JsValue { if let Some(raw_dhatu) = self.dhatupatha.get(code) { let dhatu = try_expand_dhatu(raw_dhatu, sanadi, upasarga); - let mut args = TinantaArgs::builder() + let mut args = Tinanta::builder() + .dhatu(dhatu) .lakara(lakara) .prayoga(prayoga) .purusha(purusha) @@ -150,7 +153,7 @@ impl Vidyut { let args = args.build().expect("should be well-formed"); let a = Ashtadhyayi::new(); - let prakriyas = a.derive_tinantas(&dhatu, &args); + let prakriyas = a.derive_tinantas(&args); let web_prakriyas = to_web_prakriyas(&prakriyas); serde_wasm_bindgen::to_value(&web_prakriyas).expect("wasm") @@ -169,7 +172,8 @@ impl Vidyut { vacana: Vacana, vibhakti: Vibhakti, ) -> JsValue { - let args = SubantaArgs::builder() + let args = Subanta::builder() + .pratipadika(Pratipadika::basic(pratipadika)) .linga(linga) .vacana(vacana) .vibhakti(vibhakti) @@ -177,8 +181,7 @@ impl Vidyut { .expect("should be well-formed"); let a = Ashtadhyayi::new(); - let pratipadika = Pratipadika::from(pratipadika); - let prakriyas = a.derive_subantas(&pratipadika, &args); + let prakriyas = a.derive_subantas(&args); let web_prakriyas = to_web_prakriyas(&prakriyas); serde_wasm_bindgen::to_value(&web_prakriyas).expect("wasm") @@ -194,14 +197,15 @@ impl Vidyut { upasarga: Option, ) -> JsValue { if let Some(raw_dhatu) = self.dhatupatha.get(code) { - let args = KrdantaArgs::builder() + let dhatu = try_expand_dhatu(raw_dhatu, sanadi, upasarga); + let args = Krdanta::builder() + .dhatu(dhatu) .krt(krt) .build() .expect("should be well-formed"); let a = Ashtadhyayi::new(); - let dhatu = try_expand_dhatu(raw_dhatu, sanadi, upasarga); - let prakriyas = a.derive_krdantas(&dhatu, &args); + let prakriyas = a.derive_krdantas(&args); let web_prakriyas = to_web_prakriyas(&prakriyas); serde_wasm_bindgen::to_value(&web_prakriyas).expect("wasm") diff --git a/vidyut-prakriya/temp.txt b/vidyut-prakriya/temp.txt deleted file mode 100644 index 104942f..0000000 --- a/vidyut-prakriya/temp.txt +++ /dev/null @@ -1,13 +0,0 @@ -1.4.18 --> SrI + e -7.3.112 --> SrI + Aw + e -1.3.3 --> SrI + Aw + e -1.3.9 --> SrI + A + e -6.4.77 --> Sriy + A + e -6.1.90 --> Sriy + + E -debug --> ==== Tripadi ==== -[Accept(Ashtadhyayi("1.4.6")), Accept(Ashtadhyayi("1.4.6"))] - -1.4.18 --> SrI + e -6.4.77 --> Sriy + e -debug --> ==== Tripadi ==== -[Decline(Ashtadhyayi("1.4.6")), Decline(Ashtadhyayi("1.4.6"))] diff --git a/vidyut-prakriya/test_utils/src/lib.rs b/vidyut-prakriya/test_utils/src/lib.rs index 7117ec9..6f6fa02 100644 --- a/vidyut-prakriya/test_utils/src/lib.rs +++ b/vidyut-prakriya/test_utils/src/lib.rs @@ -7,8 +7,9 @@ manage the boilerplate required for these assertions. extern crate vidyut_prakriya; use vidyut_prakriya::args::Antargana; +use vidyut_prakriya::args::DhatuPada::*; +use vidyut_prakriya::args::Prayoga::*; use vidyut_prakriya::args::Purusha as P; -use vidyut_prakriya::args::SamasaPada; use vidyut_prakriya::args::SamasaType::*; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti::*; @@ -17,6 +18,10 @@ use vidyut_prakriya::Ashtadhyayi; use vidyut_prakriya::Prakriya; use vidyut_prakriya::Rule; +fn pum_s(pratipadika: Pratipadika, vibhakti: Vibhakti) -> Subanta { + Subanta::new(pratipadika, Linga::Pum, vibhakti, Vacana::Eka) +} + /// A handy way to manage various assertions. /// /// `Ashtadhyayi` with its default settings will ignore certain rules. Some of these rules are @@ -26,6 +31,7 @@ use vidyut_prakriya::Rule; /// To test these ignored rules, we can create a new `Tester` that uses the `Ashtadhyayi` settings we /// specify. For convenience, all of these methods have wrapper functions that assume the /// default settings for `Ashtadhyayi`. +#[derive(Debug)] pub struct Tester { ashtadhyayi: Ashtadhyayi, } @@ -39,126 +45,129 @@ impl Tester { /// Creates a tester that enables chAndasa rules. pub fn with_chaandasa() -> Self { Self { - ashtadhyayi: Ashtadhyayi::builder().is_chandasa(true).build(), + ashtadhyayi: Ashtadhyayi::builder().is_chandasi(true).build(), } } - /// Core derivation methods - /// ----------------------- - - /// Derives tinantas from the given initial conditions. - fn derive_tinantas(&self, dhatu: &Dhatu, args: &TinantaArgs) -> Vec { - self.ashtadhyayi.derive_tinantas(dhatu, args) + /// Creates a tester that enables svara rules. + pub fn with_svara_rules() -> Self { + Self { + ashtadhyayi: Ashtadhyayi::builder().use_svaras(true).build(), + } } +} - /// Derives tinantas from the given initial conditions. - fn derive_subantas(&self, p: &Pratipadika, args: &SubantaArgs) -> Vec { - self.ashtadhyayi.derive_subantas(p, args) +impl Default for Tester { + fn default() -> Self { + Self::new(Ashtadhyayi::new()) } +} - fn derive_krdantas(&self, dhatu: &Dhatu, args: &KrdantaArgs) -> Vec { - self.ashtadhyayi.derive_krdantas(dhatu, args) - } +// Shorthand +// --------- - /// Derives taddhitantas from the given initial conditions. - fn derive_taddhitantas(&self, p: &Pratipadika, args: &TaddhitantaArgs) -> Vec { - self.ashtadhyayi.derive_taddhitantas(p, args) - } +pub fn d(u: &str, g: Gana) -> Dhatu { + Dhatu::mula(u, g) +} - /// Derives samasas from the given initial conditions. - fn derive_stryantas(&self, p: &Pratipadika) -> Vec { - self.ashtadhyayi.derive_stryantas(p) - } +pub fn d_kutadi(u: &str, g: Gana) -> Dhatu { + let mula = Muladhatu::new(u, g).with_antargana(Antargana::Kutadi); + Dhatu::Mula(mula) +} - /// Derives samasas from the given initial conditions. - fn derive_samasas(&self, args: &SamasaArgs) -> Vec { - self.ashtadhyayi.derive_samasas(args) - } +pub fn san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::san]) +} - /// Derives vakyas from the given initial conditions. - fn derive_vakyas(&self, padas: &[Pada]) -> Vec { - self.ashtadhyayi.derive_vakyas(padas) - } +pub fn yan(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::yaN]) +} - /// Creation methods - /// ---------------- +pub fn nic(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Ric]) +} - pub fn create_sup( - &self, - expected: &str, - prati: &Pratipadika, - linga: Linga, - vibhakti: Vibhakti, - vacana: Vacana, - ) -> Pada { - let args = SubantaArgs::builder() - .linga(linga) - .vibhakti(vibhakti) - .vacana(vacana) - .build() - .unwrap(); - let prakriyas = self.derive_subantas(prati, &args); - for p in prakriyas.iter() { - if p.text() == expected { - let pada: Option = p.into(); - return pada.unwrap(); - } - } - print_all_prakriyas(&prakriyas); - let alts: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - panic!("Could not create \"{}\". Alternatives: {alts:?}", expected); - } +pub fn san_nic(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::san, Sanadi::Ric]) +} - /// Core assertion methods - /// ---------------------- +pub fn nic_san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Ric, Sanadi::san]) +} - /// Asserts that the given input conditions produce the tinantas `expected`. - fn assert_has_tin( - &self, - prefixes: &[&str], - dhatu: &Dhatu, - lakara: Lakara, - purusha: Purusha, - vacana: Vacana, - expected: &[&str], - ) { - let args = TinantaArgs::builder() - .prayoga(Prayoga::Kartari) - .purusha(purusha) - .vacana(vacana) - .lakara(lakara) - .build() - .unwrap(); - let actual = self.derive_tinantas(&dhatu.clone().with_prefixes(prefixes), &args); - let actual = sanitize_results(actual); - assert_padas(actual, expected); - } +pub fn yan_nic(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::yaN, Sanadi::Ric]) +} - /// Asserts that the given input conditions produce the parasmaipada tinantas in `expected`. - fn assert_has_parasmai_tin( - &self, - prefixes: &[&str], - dhatu: &Dhatu, - lakara: Lakara, - purusha: Purusha, - vacana: Vacana, - expected: &[&str], - ) { - let args = TinantaArgs::builder() - .prayoga(Prayoga::Kartari) - .purusha(purusha) - .vacana(vacana) - .lakara(lakara) - .pada(DhatuPada::Parasmai) - .build() - .unwrap(); - let actual = self.derive_tinantas(&dhatu.clone().with_prefixes(prefixes), &args); - let actual = sanitize_results(actual); - assert_padas(actual, expected); +/// Marks a dhatu as taking yaN-pratyaya with luk. +pub fn yan_luk(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::yaNLuk]) +} + +pub fn krdanta(prefixes: &[&str], d: &Dhatu, krt: impl Into) -> Krdanta { + Krdanta::builder() + .dhatu(d.clone().with_prefixes(prefixes)) + .krt(krt) + .build() + .unwrap() +} + +pub fn taddhitanta(prati: impl Into, taddhita: Taddhita) -> Taddhitanta { + Taddhitanta::builder() + .pratipadika(prati.into()) + .taddhita(taddhita) + .build() + .unwrap() +} + +/// Shorthand for building a pratipadika that ends with NI/Ap. +pub fn nyap(text: &str) -> Pratipadika { + Pratipadika::nyap(text) +} + +pub fn karmadharaya(x: impl Into, y: impl Into) -> Samasa { + use Vibhakti::*; + Samasa::builder() + .padas(vec![pum_s(x.into(), Prathama), pum_s(y.into(), Prathama)]) + .samasa_type(SamasaType::Karmadharaya) + .build() + .unwrap() +} + +pub fn tatpurusha( + x: impl Into, + y: impl Into, + vibhakti: Vibhakti, +) -> Samasa { + use Vibhakti::*; + Samasa::builder() + .padas(vec![pum_s(x.into(), vibhakti), pum_s(y.into(), Prathama)]) + .samasa_type(SamasaType::Tatpurusha) + .build() + .unwrap() +} + +pub fn bahuvrihi(x: impl Into, y: impl Into) -> Samasa { + use Vibhakti::*; + Samasa::builder() + .padas(vec![pum_s(x.into(), Prathama), pum_s(y.into(), Prathama)]) + .samasa_type(SamasaType::Bahuvrihi) + .build() + .unwrap() +} + +/// ------------------------------------------------------------------------------------ +/// Tinantas +/// ------------------------------------------------------------------------------------ + +impl Tester { + /// Derives tinantas from the given initial conditions. + fn derive_tinantas(&self, args: &Tinanta) -> Vec { + self.ashtadhyayi.derive_tinantas(args) } - /// Asserts that the given input conditions produce the Atmanepada tinantas in `expected`. - fn assert_has_atmane_tin( + /// Asserts that the given input conditions produce the tinantas `expected`. + fn assert_has_tinantas( &self, prefixes: &[&str], dhatu: &Dhatu, @@ -167,42 +176,136 @@ impl Tester { vacana: Vacana, expected: &[&str], ) { - let args = TinantaArgs::builder() + let args = Tinanta::builder() + .dhatu(dhatu.clone().with_prefixes(prefixes)) .prayoga(Prayoga::Kartari) .purusha(purusha) .vacana(vacana) .lakara(lakara) - .pada(DhatuPada::Atmane) .build() .unwrap(); - let actual = self.derive_tinantas(&dhatu.clone().with_prefixes(prefixes), &args); + let actual = self.derive_tinantas(&args); let actual = sanitize_results(actual); assert_padas(actual, expected); } +} - /// Asserts that the given input conditions produce the karmaNi-prayoga tinantas in `expected`. - pub fn assert_has_karmani_tin( - &self, - prefixes: &[&str], - dhatu: &Dhatu, - lakara: Lakara, - purusha: Purusha, - vacana: Vacana, - expected: &[&str], - ) { - let args = TinantaArgs::builder() - .prayoga(Prayoga::Karmani) - .purusha(purusha) - .vacana(vacana) - .lakara(lakara) - .build() - .unwrap(); - let actual = self.derive_tinantas(&dhatu.clone().with_prefixes(prefixes), &args); - let actual = sanitize_results(actual); - assert_padas(actual, expected); +/// Checks the given combination of `dhatu` and `prefixes` produces the `expected` results given +/// this `lakara`/`purusha`/`vacana` combination. +pub fn assert_has_tinantas( + prefixes: &[&str], + dhatu: &Dhatu, + lakara: Lakara, + purusha: Purusha, + vacana: Vacana, + expected: &[&str], +) { + let t = Tester::default(); + t.assert_has_tinantas(prefixes, dhatu, lakara, purusha, vacana, expected); +} + +/// Creates a function alias `fn_name` that points to the method of the same name on a default +/// `Tester` instance. +macro_rules! test_tin { + ($fn_name:ident, $prayoga:expr, $purusha:expr, $vacana:expr, $pada:expr) => { + impl Tester { + pub fn $fn_name( + &self, + prefixes: &[&str], + dhatu: &Dhatu, + la: Lakara, + expected: &[&str], + ) { + let args = Tinanta::builder() + .dhatu(dhatu.clone().with_prefixes(prefixes)) + .prayoga($prayoga) + .purusha($purusha) + .vacana($vacana) + .lakara(la) + .pada($pada) + .build() + .unwrap(); + let actual = self.derive_tinantas(&args); + let actual = sanitize_results(actual); + assert_padas(actual, expected); + } + } + + pub fn $fn_name(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + let t = Tester::default(); + t.$fn_name(prefixes, dhatu, la, expected); + } + }; +} + +test_tin!(assert_has_tip, Kartari, P::Prathama, Eka, Parasmai); +test_tin!(assert_has_tas, Kartari, P::Prathama, Dvi, Parasmai); +test_tin!(assert_has_jhi, Kartari, P::Prathama, Bahu, Parasmai); +test_tin!(assert_has_sip, Kartari, P::Madhyama, Eka, Parasmai); +test_tin!(assert_has_thas, Kartari, P::Madhyama, Dvi, Parasmai); +test_tin!(assert_has_tha, Kartari, P::Madhyama, Bahu, Parasmai); +test_tin!(assert_has_mip, Kartari, P::Uttama, Eka, Parasmai); +test_tin!(assert_has_vas, Kartari, P::Uttama, Dvi, Parasmai); +test_tin!(assert_has_mas, Kartari, P::Uttama, Bahu, Parasmai); + +test_tin!(assert_has_ta, Kartari, P::Prathama, Eka, Atmane); +test_tin!(assert_has_aataam, Kartari, P::Prathama, Dvi, Atmane); +test_tin!(assert_has_jha, Kartari, P::Prathama, Bahu, Atmane); +test_tin!(assert_has_thaas, Kartari, P::Madhyama, Eka, Atmane); +test_tin!(assert_has_aathaam, Kartari, P::Madhyama, Dvi, Atmane); +test_tin!(assert_has_dhvam, Kartari, P::Madhyama, Bahu, Atmane); +test_tin!(assert_has_iw, Kartari, P::Uttama, Eka, Atmane); +test_tin!(assert_has_vahi, Kartari, P::Uttama, Dvi, Atmane); +test_tin!(assert_has_mahin, Kartari, P::Uttama, Bahu, Atmane); + +test_tin!(assert_has_ta_k, Karmani, P::Prathama, Eka, Atmane); +test_tin!(assert_has_aataam_k, Karmani, P::Prathama, Dvi, Atmane); +test_tin!(assert_has_jha_k, Karmani, P::Prathama, Bahu, Atmane); +test_tin!(assert_has_thaas_k, Karmani, P::Madhyama, Eka, Atmane); +test_tin!(assert_has_aathaam_k, Karmani, P::Madhyama, Dvi, Atmane); +test_tin!(assert_has_dhvam_k, Karmani, P::Madhyama, Bahu, Atmane); +test_tin!(assert_has_iw_k, Karmani, P::Uttama, Eka, Atmane); +test_tin!(assert_has_vahi_k, Karmani, P::Uttama, Dvi, Atmane); +test_tin!(assert_has_mahin_k, Karmani, P::Uttama, Bahu, Atmane); + +macro_rules! test_la { + ($fn_name:ident, $la:expr) => { + pub fn $fn_name(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { + let t = Tester::default(); + t.assert_has_tinantas( + prefixes, + dhatu, + $la, + Purusha::Prathama, + Vacana::Eka, + expected, + ); + } + }; +} + +test_la!(assert_has_lat, Lakara::Lat); +test_la!(assert_has_lit, Lakara::Lit); +test_la!(assert_has_lut, Lakara::Lut); +test_la!(assert_has_lrt, Lakara::Lrt); +test_la!(assert_has_lot, Lakara::Lot); +test_la!(assert_has_lan, Lakara::Lan); +test_la!(assert_has_ashirlin, Lakara::AshirLin); +test_la!(assert_has_vidhilin, Lakara::VidhiLin); +test_la!(assert_has_lun, Lakara::Lun); +test_la!(assert_has_lrn, Lakara::Lrn); + +/// ------------------------------------------------------------------------------------ +/// Subantas +/// ------------------------------------------------------------------------------------ + +impl Tester { + /// Derives tinantas from the given initial conditions. + fn derive_subantas(&self, args: &Subanta) -> Vec { + self.ashtadhyayi.derive_subantas(args) } - fn assert_has_sup( + fn assert_has_subantas( &self, prati: &Pratipadika, linga: Linga, @@ -210,591 +313,625 @@ impl Tester { vacana: Vacana, expected: &[&str], ) { - let args = SubantaArgs::builder() + let args = Subanta::builder() + .pratipadika(prati.clone()) .linga(linga) .vacana(vacana) .vibhakti(vibhakti) .build() .unwrap(); - let prakriyas = self.derive_subantas(prati, &args); + let prakriyas = self.derive_subantas(&args); let actual = sanitize_results(prakriyas); assert_padas(actual, expected); } +} - fn assert_has_vakya(&self, padas: &[Pada], expected: &[&str]) { - let prakriyas = self.ashtadhyayi.derive_vakyas(padas); - let prakriyas = sanitize_results(prakriyas); - - let expected: Vec<_> = expected.iter().map(|text| text.replace(" ", "")).collect(); - let actuals: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - assert_results(&expected, &actuals, prakriyas); - } +macro_rules! assert_sup { + ($fn_name:ident, $vibhakti:expr, $vacana:expr) => { + impl Tester { + pub fn $fn_name(&self, prati: impl Into, linga: Linga, expected: &[&str]) { + self.assert_has_subantas(&prati.into(), linga, $vibhakti, $vacana, &expected); + } + } - /// Fine-grained assertion methods - /// ------------------------------ + pub fn $fn_name(prati: impl Into, linga: Linga, expected: &[&str]) { + let t = Tester::default(); + t.assert_has_subantas(&prati.into(), linga, $vibhakti, $vacana, &expected); + } + }; +} - /// Asserts that the given input conditions produce the prathamA-eka tinantas in `expected` - fn assert_has_lakara(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_tin(prefixes, d, la, P::Prathama, Eka, expected); - } +assert_sup!(assert_has_sup_1s, Prathama, Eka); +assert_sup!(assert_has_sup_1d, Prathama, Dvi); +assert_sup!(assert_has_sup_1p, Prathama, Bahu); +assert_sup!(assert_has_sup_2s, Dvitiya, Eka); +assert_sup!(assert_has_sup_2d, Dvitiya, Dvi); +assert_sup!(assert_has_sup_2p, Dvitiya, Bahu); +assert_sup!(assert_has_sup_3s, Trtiya, Eka); +assert_sup!(assert_has_sup_3d, Trtiya, Dvi); +assert_sup!(assert_has_sup_3p, Trtiya, Bahu); +assert_sup!(assert_has_sup_4s, Caturthi, Eka); +assert_sup!(assert_has_sup_4d, Caturthi, Dvi); +assert_sup!(assert_has_sup_4p, Caturthi, Bahu); +assert_sup!(assert_has_sup_5s, Panchami, Eka); +assert_sup!(assert_has_sup_5d, Panchami, Dvi); +assert_sup!(assert_has_sup_5p, Panchami, Bahu); +assert_sup!(assert_has_sup_6s, Sasthi, Eka); +assert_sup!(assert_has_sup_6d, Sasthi, Dvi); +assert_sup!(assert_has_sup_6p, Sasthi, Bahu); +assert_sup!(assert_has_sup_7s, Saptami, Eka); +assert_sup!(assert_has_sup_7d, Saptami, Dvi); +assert_sup!(assert_has_sup_7p, Saptami, Bahu); +assert_sup!(assert_has_sup_ss, Sambodhana, Eka); +assert_sup!(assert_has_sup_sd, Sambodhana, Dvi); +assert_sup!(assert_has_sup_sp, Sambodhana, Bahu); - pub fn assert_has_tip(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Prathama, Eka, expected); - } +macro_rules! create_sup { + ($fn_name:ident, $vibhakti:expr, $vacana:expr) => { + pub fn $fn_name(_expected: &str, prati: impl Into, linga: Linga) -> Pada { + Subanta::builder() + .pratipadika(prati.into()) + .linga(linga) + .vibhakti($vibhakti) + .vacana($vacana) + .build() + .unwrap() + .into() + } + }; +} - pub fn assert_has_tas(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Prathama, Dvi, expected); - } +create_sup!(sup_1s, Prathama, Eka); +create_sup!(sup_1d, Prathama, Dvi); +create_sup!(sup_1p, Prathama, Bahu); +create_sup!(sup_2s, Dvitiya, Eka); +create_sup!(sup_2d, Dvitiya, Dvi); +create_sup!(sup_2p, Dvitiya, Bahu); +create_sup!(sup_3s, Trtiya, Eka); +create_sup!(sup_3d, Trtiya, Dvi); +create_sup!(sup_3p, Trtiya, Bahu); +create_sup!(sup_4s, Caturthi, Eka); +create_sup!(sup_4d, Caturthi, Dvi); +create_sup!(sup_4p, Caturthi, Bahu); +create_sup!(sup_5s, Panchami, Eka); +create_sup!(sup_5d, Panchami, Dvi); +create_sup!(sup_5p, Panchami, Bahu); +create_sup!(sup_6s, Sasthi, Eka); +create_sup!(sup_6d, Sasthi, Dvi); +create_sup!(sup_6p, Sasthi, Bahu); +create_sup!(sup_7s, Saptami, Eka); +create_sup!(sup_7d, Saptami, Dvi); +create_sup!(sup_7p, Saptami, Bahu); +create_sup!(sup_ss, Sambodhana, Eka); +create_sup!(sup_sd, Sambodhana, Dvi); +create_sup!(sup_sp, Sambodhana, Bahu); - pub fn assert_has_jhi(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Prathama, Bahu, expected); - } +/// Like `assert_has_subantas_p` but without any filtering on the last sound. +/// (Needed for 8.4.56.) +pub fn assert_has_subantas_raw( + pratipadika_text: &str, + linga: Linga, + vibhakti: Vibhakti, + vacana: Vacana, + expected: &[&str], +) { + let pratipadika = Pratipadika::basic(pratipadika_text); + let a = Ashtadhyayi::new(); + let args = Subanta::builder() + .pratipadika(pratipadika) + .linga(linga) + .vacana(vacana) + .vibhakti(vibhakti) + .build() + .unwrap(); - pub fn assert_has_sip(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Madhyama, Eka, expected); - } + let mut results = a.derive_subantas(&args); + results.sort_by_key(|p| p.text()); + results.dedup_by_key(|p| p.text()); + let actual: Vec<_> = results.into_iter().collect(); + assert_padas(actual, expected); +} - pub fn assert_has_thas(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Madhyama, Dvi, expected); - } +/// ------------------------------------------------------------------------------------ +/// Krdantas +/// ------------------------------------------------------------------------------------ - pub fn assert_has_tha(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Madhyama, Bahu, expected); +impl Tester { + fn derive_krdantas(&self, args: &Krdanta) -> Vec { + self.ashtadhyayi.derive_krdantas(args) } - pub fn assert_has_mip(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Uttama, Eka, expected); - } - - pub fn assert_has_vas(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Uttama, Dvi, expected); - } - - pub fn assert_has_mas(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_parasmai_tin(prefixes, d, la, P::Uttama, Bahu, expected); - } - - pub fn assert_has_ta(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Prathama, Eka, expected); - } + pub fn assert_has_krt( + &self, + prefixes: &[&str], + dhatu: &Dhatu, + krt: impl Into, + expected: &[&str], + ) { + let spec = Krdanta::builder() + .dhatu(dhatu.clone().with_prefixes(prefixes)) + .krt(krt.into()) + .build() + .unwrap(); + let mut prakriyas = self.derive_krdantas(&spec); + prakriyas.sort_by_key(|p| p.text()); + prakriyas.dedup_by_key(|p| p.text()); + // Allowed in pada sandhi, but noisy here. + prakriyas.retain(|p| !p.text().contains("cS")); - pub fn assert_has_aataam(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Prathama, Dvi, expected); + assert_padas(prakriyas, expected); } +} - pub fn assert_has_jha(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Prathama, Bahu, expected); - } +pub fn assert_has_krdanta( + prefixes: &[&str], + dhatu: &Dhatu, + krt: impl Into, + expected: &[&str], +) { + let t = Tester::default(); + t.assert_has_krt(prefixes, dhatu, krt, expected); +} - pub fn assert_has_thaas(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Madhyama, Eka, expected); - } +pub fn assert_has_artha_krdanta( + upapadas: &[&str], + dhatu: &Dhatu, + requested_artha: KrtArtha, + krt: impl Into, + expected: &[&str], +) { + let a = Ashtadhyayi::new(); + let krdanta = Krdanta::builder() + .dhatu(dhatu.clone().with_prefixes(upapadas)) + .krt(krt.into()) + .artha(requested_artha) + .build() + .unwrap(); + let mut prakriyas = derive_krdantas(&a, &krdanta); - pub fn assert_has_aathaam(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Madhyama, Dvi, expected); - } + prakriyas.retain(|p| { + if let Some(Artha::Krt(prakriya_artha)) = p.artha() { + requested_artha == prakriya_artha + } else { + false + } + }); + assert_padas(prakriyas, expected); +} - pub fn assert_has_dhvam(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Madhyama, Bahu, expected); - } +pub fn assert_has_upapada_krdanta( + upapada: &str, + prefixes: &[&str], + dhatu: &Dhatu, + krt: impl Into, + expected: &[&str], +) { + let a = Ashtadhyayi::new(); + let args = Krdanta::builder() + .dhatu(dhatu.clone().with_prefixes(prefixes)) + .krt(krt.into()) + .upapada(Upapada::make_subanta(upapada)) + .build() + .unwrap(); + assert_padas(derive_krdantas(&a, &args), expected); +} - pub fn assert_has_iw(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Uttama, Eka, expected); - } +pub fn assert_has_upapada_krdanta_raw( + upapada: Upapada, + prefixes: &[&str], + dhatu: &Dhatu, + krt: impl Into, + expected: &[&str], +) { + let a = Ashtadhyayi::new(); + let args = Krdanta::builder() + .dhatu(dhatu.clone().with_prefixes(prefixes)) + .krt(krt.into()) + .upapada(upapada) + .build() + .unwrap(); + assert_padas(derive_krdantas(&a, &args), expected); +} - pub fn assert_has_vahi(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Uttama, Dvi, expected); - } +/// Creates a krdanta as a pratipadika. +/// +/// This function is a shorthand that lets us test certain subanta forms more easily. +pub fn create_krdanta(text: &str, prefixes: &[&str], d: &Dhatu, krt: impl Into) -> Krdanta { + Krdanta::builder() + .dhatu(d.clone().with_prefixes(prefixes)) + .krt(krt) + .require(text) + .build() + .unwrap() +} - pub fn assert_has_mahin(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_atmane_tin(prefixes, d, la, P::Uttama, Bahu, expected); - } +/// Creates a krdanta as a pratipadika. +/// +/// This function is a shorthand that lets us test certain subanta forms more easily. +pub fn create_upapada_krdanta( + text: &str, + upapada: &str, + prefixes: &[&str], + d: &Dhatu, + krt: impl Into, +) -> Krdanta { + Krdanta::builder() + .dhatu(d.clone().with_prefixes(prefixes)) + .krt(krt) + .upapada(Upapada::make_subanta(upapada)) + .require(text) + .build() + .unwrap() +} - pub fn assert_has_ta_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Prathama, Eka, expected); - } +/// Derives krdantas from the given initial conditions. +fn derive_krdantas(a: &Ashtadhyayi, krdanta: &Krdanta) -> Vec { + let mut results = a.derive_krdantas(krdanta); + results.sort_by_key(|p| p.text()); + results.dedup_by_key(|p| p.text()); + // Allowed in pada sandhi, but noisy here. + results.retain(|p| !p.text().contains("cS")); + results +} - pub fn assert_has_aataam_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Prathama, Dvi, expected); - } +/// ------------------------------------------------------------------------------------ +/// Taddhitantas +/// ------------------------------------------------------------------------------------ - pub fn assert_has_jha_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Prathama, Bahu, expected); +impl Tester { + /// Derives taddhitantas from the given initial conditions. + fn derive_taddhitantas(&self, args: &Taddhitanta) -> Vec { + self.ashtadhyayi.derive_taddhitantas(args) } - pub fn assert_has_thaas_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Madhyama, Eka, expected); + /// Derives taddhitantas from the given initial conditions. + fn derive_artha_taddhitantas( + &self, + p: impl Into, + t: Taddhita, + a: Option, + ) -> Vec { + let args = if let Some(a) = a { + Taddhitanta::builder() + .pratipadika(p.into()) + .taddhita(t) + .artha(a) + .build() + .unwrap() + } else { + taddhitanta(p.into(), t) + }; + let results = self.derive_taddhitantas(&args); + sanitize_results(results) } - pub fn assert_has_aathaam_k( + pub fn assert_has_artha_taddhita( &self, - prefixes: &[&str], - d: &Dhatu, - la: Lakara, + prati: impl Into, + requested_artha: TaddhitaArtha, + t: Taddhita, expected: &[&str], ) { - self.assert_has_karmani_tin(prefixes, d, la, P::Madhyama, Dvi, expected); + let mut prakriyas = self.derive_artha_taddhitantas(prati.into(), t, Some(requested_artha)); + prakriyas.retain(|p| { + if let Some(Artha::Taddhita(prakriya_artha)) = p.artha() { + requested_artha.is_type_of(prakriya_artha) + } else { + false + } + }); + assert_padas(prakriyas, expected); } - pub fn assert_has_dhvam_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Madhyama, Bahu, expected); + pub fn assert_has_taddhita(&self, prati: &str, t: Taddhita, expected: &[&str]) { + let pratipadika = Pratipadika::Basic(prati.to_string(), false); + let prakriyas = self.derive_artha_taddhitantas(pratipadika.clone(), t, None); + assert_padas(prakriyas, expected); } +} - pub fn assert_has_iw_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Uttama, Eka, expected); - } +/// Creates a krdanta as a pratipadika. +/// +/// This function is a shorthand that lets us test certain subanta forms more easily. +pub fn create_taddhitanta( + text: &str, + base: impl Into, + taddhita: Taddhita, +) -> Taddhitanta { + taddhitanta(base, taddhita).with_require(text) +} - pub fn assert_has_vahi_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Uttama, Dvi, expected); - } +/// Creates a krdanta as a pratipadika. +/// +/// This function is a shorthand that lets us test certain subanta forms more easily. +pub fn create_artha_taddhita( + _text: &str, + base: impl Into, + artha: TaddhitaArtha, + taddhita: Taddhita, +) -> Taddhitanta { + Taddhitanta::builder() + .pratipadika(base.into()) + .taddhita(taddhita) + .artha(artha) + .build() + .unwrap() +} - pub fn assert_has_mahin_k(&self, prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - self.assert_has_karmani_tin(prefixes, d, la, P::Uttama, Bahu, expected); - } +pub fn assert_has_taddhita(prati: impl Into, t: Taddhita, expected: &[&str]) { + let tester = Tester::default(); + let results = tester.derive_artha_taddhitantas(prati.into(), t, None); + let results = sanitize_results(results); + assert_padas(results, expected); +} - pub fn assert_has_krt( - &self, - prefixes: &[&str], - dhatu: &Dhatu, - krt: impl Into, - expected: &[&str], - ) { - let args = KrdantaArgs::builder().krt(krt.into()).build().unwrap(); - let mut prakriyas = self.derive_krdantas(&dhatu.clone().with_prefixes(prefixes), &args); - prakriyas.sort_by_key(|p| p.text()); - prakriyas.dedup_by_key(|p| p.text()); - // Allowed in pada sandhi, but noisy here. - prakriyas.retain(|p| !p.text().contains("cS")); +pub fn assert_has_artha_taddhita( + prati: impl Into, + requested_artha: TaddhitaArtha, + taddhita: Taddhita, + expected: &[&str], +) { + let t = Tester::default(); + t.assert_has_artha_taddhita(prati, requested_artha, taddhita, expected); +} - assert_padas(prakriyas, expected); - } +/// ------------------------------------------------------------------------------------ +/// Samasas +/// ------------------------------------------------------------------------------------ - pub fn assert_has_samasas(&self, args: &SamasaArgs, expected: &[&str]) { - let mut prakriyas = self.derive_samasas(&args); +impl Tester { + pub fn assert_has_samasas(&self, args: &Samasa, expected: &[&str]) { + let mut prakriyas = self.ashtadhyayi.derive_samasas(&args); prakriyas.sort_by_key(|p| p.text()); prakriyas.dedup_by_key(|p| p.text()); assert_padas(prakriyas, expected); } /// A simpler interface to `assert_has_samasas` that accepts exactly two items. - fn assert_samasa_of_type( - &self, - padas: &[SamasaPada], - samasa_type: SamasaType, - expected: &[&str], - ) { - let args = SamasaArgs::builder() + fn assert_samasa_of_type(&self, padas: &[Subanta], samasa_type: SamasaType, expected: &[&str]) { + let args = Samasa::builder() .padas(Vec::from(padas)) .samasa_type(samasa_type) .build() .unwrap(); - let t = Tester::default(); - t.assert_has_samasas(&args, expected); + self.assert_has_samasas(&args, expected); } - fn assert_has_bahuvrihi( + pub fn assert_has_bahuvrihi( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Prathama), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Bahuvrihi, - expected, - ); + self.assert_has_samasas(&bahuvrihi(a, b), expected); } fn assert_has_avyayibhava( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::avyaya(a.to_p()), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Avyayibhava, - expected, - ); + let padas = vec![ + Subanta::avyaya(a.into()), + Subanta::new(b.into(), Linga::Pum, Vibhakti::Prathama, Vacana::Eka), + ]; + let args = Samasa::builder() + .padas(padas) + .samasa_type(Avyayibhava) + .build() + .unwrap(); + + let mut prakriyas = self.ashtadhyayi.derive_samasas(&args); + prakriyas.sort_by_key(|p| p.text()); + prakriyas.dedup_by_key(|p| p.text()); + let prakriyas: Vec<_> = prakriyas + .into_iter() + .filter(|p| { + let text = p.text(); + !text.ends_with("d") + }) + .collect(); + assert_padas(prakriyas, expected); } - fn assert_has_karmadharaya( + pub fn assert_has_karmadharaya( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Prathama), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Karmadharaya, - expected, - ); + self.assert_has_samasas(&karmadharaya(a, b), expected); } - fn assert_has_dvitiya_tatpurusha( + pub fn assert_has_dvitiya_tatpurusha( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Dvitiya), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); + self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Dvitiya), expected); } - fn assert_has_trtiya_tatpurusha( + pub fn assert_has_trtiya_tatpurusha( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Trtiya), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); + self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Trtiya), expected); } fn assert_has_caturthi_tatpurusha( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Caturthi), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); + self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Caturthi), expected); } fn assert_has_panchami_tatpurusha( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Panchami), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); + self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Panchami), expected); } fn assert_has_sasthi_tatpurusha( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, + a: impl Into, + b: impl Into, expected: &[&str], ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Sasthi), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); + self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Sasthi), expected); } fn assert_has_saptami_tatpurusha( &self, - a: impl IntoPratipadika, - b: impl IntoPratipadika, - expected: &[&str], - ) { - self.assert_samasa_of_type( - &[ - SamasaPada::new(a.to_p(), Vibhakti::Saptami), - SamasaPada::new(b.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); - } - - /// Derives taddhitantas from the given initial conditions. - fn derive_artha_taddhitantas( - &self, - p: &Pratipadika, - t: Taddhita, - a: Option, - ) -> Vec { - let args = if let Some(a) = a { - TaddhitantaArgs::builder() - .taddhita(t) - .artha(a) - .build() - .unwrap() - } else { - TaddhitantaArgs::builder().taddhita(t).build().unwrap() - }; - let results = self.derive_taddhitantas(p, &args); - sanitize_results(results) - } - - pub fn assert_has_artha_taddhita( - &self, - prati: &str, - requested_artha: TaddhitaArtha, - t: Taddhita, + a: impl Into, + b: impl Into, expected: &[&str], ) { - let pratipadika = Pratipadika::from(prati); - let mut prakriyas = self.derive_artha_taddhitantas(&pratipadika, t, Some(requested_artha)); - prakriyas.retain(|p| { - if let Some(Artha::Taddhita(prakriya_artha)) = p.artha() { - requested_artha.is_type_of(prakriya_artha) - } else { - false - } - }); - assert_padas(prakriyas, expected); + self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Saptami), expected); } } -impl Default for Tester { - fn default() -> Self { - Self::new(Ashtadhyayi::new()) - } +macro_rules! assert_samasa { + ($fn_name:ident) => { + pub fn $fn_name( + purva: impl Into, + uttara: impl Into, + expected: &[&str], + ) { + let t = Tester::default(); + t.$fn_name(purva, uttara, expected); + } + }; } -// Derivation helpers -// ------------------ - -/// Sanitizes our test results by making them deterministic and predictable. -fn sanitize_results(mut results: Vec) -> Vec { - results.sort_by_key(|p| p.text()); - results.dedup_by_key(|p| p.text()); - - results - .into_iter() - .filter(|p| { - let text = p.text(); - !text.ends_with('d') - && !text.ends_with('q') - && !text.ends_with('g') - && !text.ends_with('b') - }) - .collect() -} - -pub fn create_pratipadika(text: &str, prakriyas: &[Prakriya]) -> Pratipadika { - for p in prakriyas.iter() { - if p.text() == text { - let prati: Option = p.into(); - return prati.unwrap(); - } - } - print_all_prakriyas(&prakriyas); - let alts: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - panic!("Could not create \"{}\". Alternatives: {alts:?}", text); -} - -pub fn create_pada(text: &str, prakriyas: &[Prakriya]) -> Pada { - for p in prakriyas.iter() { - if p.text() == text { - let pada: Option = p.into(); - return pada.unwrap(); - } - } - print_all_prakriyas(&prakriyas); - let alts: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - panic!("Could not create \"{}\". Alternatives: {alts:?}", text); -} - -/// Creates a krdanta as a pratipadika. -/// -/// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_krdanta( - text: &str, - prefixes: &[&str], - d: &Dhatu, - krt: impl Into, -) -> Pratipadika { - let args = KrdantaArgs::builder().krt(krt).build().unwrap(); - let d = d.clone().with_prefixes(prefixes); +assert_samasa!(assert_has_bahuvrihi); +assert_samasa!(assert_has_avyayibhava); +assert_samasa!(assert_has_karmadharaya); +assert_samasa!(assert_has_dvitiya_tatpurusha); +assert_samasa!(assert_has_trtiya_tatpurusha); +assert_samasa!(assert_has_caturthi_tatpurusha); +assert_samasa!(assert_has_panchami_tatpurusha); +assert_samasa!(assert_has_sasthi_tatpurusha); +assert_samasa!(assert_has_saptami_tatpurusha); - let tester = Tester::default(); - let prakriyas = tester.derive_krdantas(&d, &args); - create_pratipadika(text, &prakriyas) +pub fn assert_has_avyaya_tatpurusha( + first: impl Into, + second: impl Into, + expected: &[&str], +) { + let t = Tester::default(); + t.assert_samasa_of_type( + &[ + Subanta::avyaya(first.into()), + pum_s(second.into(), Prathama), + ], + Tatpurusha, + expected, + ); } -/// Creates a krdanta as a pratipadika. -/// -/// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_upapada_krdanta( - text: &str, - upapada: &str, - prefixes: &[&str], - d: &Dhatu, - krt: impl Into, -) -> Pratipadika { - let args = KrdantaArgs::builder() - .krt(krt) - .upapada(Upapada::make_subanta(upapada)) - .build() - .unwrap(); - let d = d.clone().with_prefixes(prefixes); - - let tester = Tester::default(); - let prakriyas = tester.derive_krdantas(&d, &args); - create_pratipadika(text, &prakriyas) +pub fn assert_has_misc_tatpurusha( + first: impl Into, + second: impl Into, + expected: &[&str], +) { + assert_has_sasthi_tatpurusha(first, second, expected); } -/// Creates a krdanta as a pratipadika. -/// -/// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_taddhitanta( - text: &str, - base: impl IntoPratipadika, - taddhita: Taddhita, -) -> Pratipadika { - let args = TaddhitantaArgs::builder() - .taddhita(taddhita) +pub fn assert_has_dvandva(items: &[&str], expected: &[&str]) { + let args = Samasa::builder() + .padas( + items + .iter() + .map(|s| pum_s(Pratipadika::basic(s), Vibhakti::Prathama)) + .collect(), + ) + .samasa_type(Dvandva) .build() .unwrap(); - - let tester = Tester::default(); - let prakriyas = tester.derive_taddhitantas(&base.to_p(), &args); - create_pratipadika(text, &prakriyas) -} - -/// Creates a krdanta as a pratipadika. -/// -/// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_stryanta(text: &str, base: &str) -> Pratipadika { - let tester = Tester::default(); - let prakriyas = tester.derive_stryantas(&Pratipadika::from(base)); - create_pratipadika(text, &prakriyas) + let t = Tester::default(); + t.assert_has_samasas(&args, expected); } -/// Creates a samasa as a pratipadika. -/// -/// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_samasa(text: &str, items: &[&str], samasa_type: SamasaType) -> Pratipadika { - let padas: Vec<_> = items - .iter() - .map(|s| { - let prati = s.to_p(); - SamasaPada::new(prati, Vibhakti::Prathama) - }) - .collect(); - let args = SamasaArgs::builder() - .padas(padas) - .samasa_type(samasa_type) +pub fn assert_has_samahara_dvandva(items: &[&str], expected: &[&str]) { + let args = Samasa::builder() + .padas( + items + .iter() + .map(|s| pum_s(Pratipadika::basic(s), Vibhakti::Prathama)) + .collect(), + ) + .samasa_type(SamaharaDvandva) .build() .unwrap(); - - let tester = Tester::default(); - let prakriyas = tester.derive_samasas(&args); - create_pratipadika(text, &prakriyas) + let t = Tester::default(); + t.assert_has_samasas(&args, expected); } /// Creates a samasa as a pratipadika. /// /// This function is a shorthand that lets us test certain subanta forms more easily. pub fn create_avyaya_tatpurusha( - text: &str, - first: impl IntoPratipadika, - second: impl IntoPratipadika, -) -> Pratipadika { + _text: &str, + first: impl Into, + second: impl Into, +) -> Samasa { let padas = vec![ - SamasaPada::avyaya(first.to_p()), - SamasaPada::new(second.to_p(), Vibhakti::Prathama), + Subanta::avyaya(first.into()), + Subanta::new(second.into(), Linga::Pum, Vibhakti::Prathama, Vacana::Eka), ]; - let args = SamasaArgs::builder() + Samasa::builder() .padas(padas) .samasa_type(Tatpurusha) .build() - .unwrap(); - - let tester = Tester::default(); - let prakriyas = tester.derive_samasas(&args); - create_pratipadika(text, &prakriyas) + .unwrap() } /// Creates a samasa as a pratipadika. /// /// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_tatpurusha(text: &str, items: &[&str], vibhakti: Vibhakti) -> Pratipadika { - debug_assert!(items.len() == 2); - - let padas = vec![ - SamasaPada::new(Pratipadika::from(items[0]), vibhakti), - SamasaPada::new(Pratipadika::from(items[1]), Vibhakti::Prathama), - ]; - let args = SamasaArgs::builder() - .padas(padas) - .samasa_type(Tatpurusha) - .build() - .unwrap(); +pub fn create_bahuvrihi(_text: &str, first: &str, second: &str) -> Samasa { + bahuvrihi(first, second) +} - let tester = Tester::default(); - let prakriyas = tester.derive_samasas(&args); - create_pratipadika(text, &prakriyas) +pub fn assert_has_samasas(args: &Samasa, expected: &[&str]) { + let t = Tester::default(); + t.assert_has_samasas(&args, expected); } -/// Creates a samasa as a pratipadika. -/// -/// This function is a shorthand that lets us test certain subanta forms more easily. -pub fn create_samasa_p(text: &str, pratis: &[Pratipadika], samasa_type: SamasaType) -> Pratipadika { - let padas: Vec<_> = pratis - .iter() - .map(|s| { - let prati = s.to_p(); - SamasaPada::new(prati, Vibhakti::Prathama) - }) - .collect(); - let args = SamasaArgs::builder() - .padas(padas) - .samasa_type(samasa_type) - .build() - .unwrap(); +/// ------------------------------------------------------------------------------------ +/// Vakyas +/// ------------------------------------------------------------------------------------ - let tester = Tester::default(); - let prakriyas = tester.derive_samasas(&args); - create_pratipadika(text, &prakriyas) +impl Tester { + /// Derives vakyas from the given initial conditions. + fn derive_vakyas(&self, padas: &[Pada]) -> Vec { + self.ashtadhyayi.derive_vakyas(padas) + } + + fn assert_has_vakya(&self, padas: &[Pada], expected: &[&str]) { + let prakriyas = self.ashtadhyayi.derive_vakyas(padas); + let prakriyas = sanitize_results(prakriyas); + assert_padas(prakriyas, &expected); + } } -/// Derives krdantas from the given initial conditions. -fn derive_krdantas(a: &Ashtadhyayi, dhatu: &Dhatu, args: KrdantaArgs) -> Vec { - let mut results = a.derive_krdantas(dhatu, &args); - results.sort_by_key(|p| p.text()); - results.dedup_by_key(|p| p.text()); - // Allowed in pada sandhi, but noisy here. - results.retain(|p| !p.text().contains("cS")); - results +pub fn assert_has_vakya(first: &Pada, second: &Pada, expected: &[&str]) { + let t = Tester::default(); + t.assert_has_vakya(&vec![first.to_owned(), second.to_owned()], expected); } -/// Derives taddhitantas from the given initial conditions. -fn derive_taddhitantas(p: &Pratipadika, t: Taddhita, a: Option) -> Vec { - let tester = Tester::default(); - let results = tester.derive_artha_taddhitantas(p, t, a); - sanitize_results(results) +pub fn assert_has_sandhi(first: &str, second: &str, expected: &[&str]) { + let prakriyas = derive_vakyas(&first, &second); + assert_padas(prakriyas, &expected); } /// Derives vakyas from the given initial conditions. @@ -808,13 +945,35 @@ fn derive_vakyas(first: &str, second: &str) -> Vec { results } +// Derivation helpers +// ------------------ + +/// Sanitizes our test results by making them deterministic and predictable. +fn sanitize_results(mut results: Vec) -> Vec { + results.sort_by_key(|p| p.text()); + results.dedup_by_key(|p| p.text()); + + results + .into_iter() + .filter(|p| { + let text = p.text(); + !text.ends_with('d') + && !text.ends_with('q') + && !text.ends_with('g') + && !text.ends_with('b') + }) + .collect() +} + fn debug_text(rule: Rule) -> String { match rule { Rule::Ashtadhyayi(x) => x.to_string(), + Rule::Varttika(x, y) => format!("{x} v{y}"), Rule::Dhatupatha(x) => format!("DA {x}"), Rule::Kashika(x) => format!("kA {x}"), Rule::Kaumudi(x) => format!("kO {x}"), - Rule::Linganushasana(x) => format!("Li {x}"), + Rule::Linganushasana(x) => format!("liNga {x}"), + Rule::Phit(x) => format!("Piw {x}"), Rule::Unadipatha(x) => format!("uRA {x}"), } } @@ -823,7 +982,20 @@ fn debug_text(rule: Rule) -> String { fn print_all_prakriyas(prakriyas: &[Prakriya]) { for p in prakriyas { for step in p.history() { - println!("{} --> {}", debug_text(step.rule()), step.result()); + let mut result = String::new(); + for (i, text) in step.result().iter().enumerate() { + if i != 0 { + result += " + "; + } + if step.active() == Some(i) { + result += "["; + result += text; + result += "]"; + } else { + result += text; + } + } + println!("{} --> {}", debug_text(step.rule()), result); } println!("{:?}", p.rule_choices()); println!(); @@ -834,7 +1006,11 @@ fn print_all_prakriyas(prakriyas: &[Prakriya]) { // -------------------- // These functions are too heavy for regular use. Instead, use the smaller assert functions below. -fn assert_results(expected: &[String], actuals: &[String], prakriyas: Vec) { +/// Asserts that the given `prakriyas` produce the `expected` results. +pub fn assert_padas(prakriyas: Vec, expected: &[&str]) { + let expected: Vec<_> = expected.iter().map(|text| text.replace(" ", "")).collect(); + let actuals: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); + let mut expected = Vec::from(expected); expected.sort(); expected.dedup(); @@ -863,465 +1039,7 @@ fn assert_results(expected: &[String], actuals: &[String], prakriyas: Vec, expected: &[&str]) { - let expected: Vec<_> = expected.iter().map(|t| t.to_string()).collect(); - let actuals: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - assert_results(&expected, &actuals, prakriyas); -} - -/// Checks the given combination of `dhatu` and `prefixes` produces the `expected` results given -/// this `lakara`/`purusha`/`vacana` combination. -pub fn assert_has_tinanta( - prefixes: &[&str], - dhatu: &Dhatu, - lakara: Lakara, - purusha: Purusha, - vacana: Vacana, - expected: &[&str], -) { - let t = Tester::default(); - t.assert_has_tin(prefixes, dhatu, lakara, purusha, vacana, expected); -} - -pub fn assert_has_vakya(first: &Pada, second: &Pada, expected: &[&str]) { - let t = Tester::default(); - t.assert_has_vakya(&vec![first.to_owned(), second.to_owned()], expected); -} - -pub fn assert_has_sandhi(first: &str, second: &str, expected: &[&str]) { - let prakriyas = derive_vakyas(&first, &second); - - let expected: Vec<_> = expected.iter().map(|text| text.replace(" ", "")).collect(); - let actuals: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - assert_results(&expected, &actuals, prakriyas); -} - -// Dhatu helpers -// ------------- - -/// Shorthand for `Dhatu::new`. -/// -/// Our tests create dhatus thousands of times, so we defined this function to save some typing and -/// make our tests easier to scan. -pub fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - -pub fn d_kutadi(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g).with_antargana(Some(Antargana::Kutadi)) -} - -/// Marks a dhatu as taking san-pratyaya. -pub fn san(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::San]) -} - -/// Marks a dhatu as taking yaN-pratyaya. -pub fn yan(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::Yan]) -} - -/// Marks a dhatu as taking Ric-pratyaya. -pub fn nic(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::Nic]) -} - -/// Marks a dhatu as taking san-pratyaya followed by Nic-pratyaya. -pub fn san_nic(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::San, Sanadi::Nic]) -} - -/// Marks a dhatu as taking Nic-pratyaya followed by san-pratyaya. -pub fn nic_san(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::Nic, Sanadi::San]) -} - -/// Marks a dhatu as taking yaN-pratyaya with luk. -pub fn yan_luk(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::YanLuk]) -} - -// Pratipadika helpers -// ------------------- - -/// Shorthand for building a pratipadika. -pub fn prati(text: &str) -> Pratipadika { - Pratipadika::from(text) -} - -/// Shorthand for building a pratipadika that ends with NI/Ap. -pub fn nyap(text: &str) -> Pratipadika { - Pratipadika::builder() - .text(text) - .is_nyap(true) - .build() - .unwrap() -} - -/// Shorthand for building a pratipadika from a dhatu. -pub fn dhatu_prati(text: &str) -> Pratipadika { - Pratipadika::builder() - .text(text) - .is_dhatu(true) - .build() - .unwrap() -} - -/// Creates a function alias `fn_name` that points to the method of the same name on a default -/// `Tester` instance. -macro_rules! test_tin { - ($fn_name:ident) => { - pub fn $fn_name(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { - let t = Tester::default(); - t.$fn_name(prefixes, dhatu, la, expected); - } - }; -} - -test_tin!(assert_has_tip); -test_tin!(assert_has_tas); -test_tin!(assert_has_jhi); -test_tin!(assert_has_sip); -test_tin!(assert_has_thas); -test_tin!(assert_has_tha); -test_tin!(assert_has_mip); -test_tin!(assert_has_vas); -test_tin!(assert_has_mas); - -test_tin!(assert_has_ta); -test_tin!(assert_has_aataam); -test_tin!(assert_has_jha); -test_tin!(assert_has_thaas); -test_tin!(assert_has_aathaam); -test_tin!(assert_has_dhvam); -test_tin!(assert_has_iw); -test_tin!(assert_has_vahi); -test_tin!(assert_has_mahin); - -test_tin!(assert_has_ta_k); -test_tin!(assert_has_aataam_k); -test_tin!(assert_has_jha_k); -test_tin!(assert_has_thaas_k); -test_tin!(assert_has_aathaam_k); -test_tin!(assert_has_dhvam_k); -test_tin!(assert_has_iw_k); -test_tin!(assert_has_vahi_k); -test_tin!(assert_has_mahin_k); - -macro_rules! test_la { - ($fn_name:ident, $la:expr) => { - pub fn $fn_name(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - let t = Tester::default(); - t.assert_has_lakara(prefixes, dhatu, $la, expected); - } - }; -} - -test_la!(assert_has_lat, Lakara::Lat); -test_la!(assert_has_lit, Lakara::Lit); -test_la!(assert_has_lut, Lakara::Lut); -test_la!(assert_has_lrt, Lakara::Lrt); -test_la!(assert_has_lot, Lakara::Lot); -test_la!(assert_has_lan, Lakara::Lan); -test_la!(assert_has_ashirlin, Lakara::AshirLin); -test_la!(assert_has_vidhilin, Lakara::VidhiLin); -test_la!(assert_has_lun, Lakara::Lun); -test_la!(assert_has_lrn, Lakara::Lrn); - -// Krdanta helpers -// --------------- - -pub fn assert_has_krdanta( - prefixes: &[&str], - dhatu: &Dhatu, - krt: impl Into, - expected: &[&str], -) { - let t = Tester::default(); - t.assert_has_krt(prefixes, dhatu, krt, expected); -} - -pub fn assert_has_artha_krdanta( - upapadas: &[&str], - dhatu: &Dhatu, - requested_artha: KrtArtha, - krt: impl Into, - expected: &[&str], -) { - let a = Ashtadhyayi::new(); - let args = KrdantaArgs::builder() - .krt(krt.into()) - .artha(requested_artha) - .build() - .unwrap(); - let mut prakriyas = derive_krdantas(&a, &dhatu.clone().with_prefixes(upapadas), args); - - prakriyas.retain(|p| { - if let Some(Artha::Krt(prakriya_artha)) = p.artha() { - requested_artha == prakriya_artha - } else { - false - } - }); - assert_padas(prakriyas, expected); -} - -pub fn assert_has_upapada_krdanta( - upapada: &str, - prefixes: &[&str], - dhatu: &Dhatu, - krt: impl Into, - expected: &[&str], -) { - let a = Ashtadhyayi::new(); - let args = KrdantaArgs::builder() - .krt(krt.into()) - .upapada(Upapada::make_subanta(upapada)) - .build() - .unwrap(); - assert_padas( - derive_krdantas(&a, &dhatu.clone().with_prefixes(prefixes), args), - expected, - ); -} - -pub fn assert_has_upapada_krdanta_raw( - upapada: Upapada, - prefixes: &[&str], - dhatu: &Dhatu, - krt: impl Into, - expected: &[&str], -) { - let a = Ashtadhyayi::new(); - let args = KrdantaArgs::builder() - .krt(krt.into()) - .upapada(upapada) - .build() - .unwrap(); - assert_padas( - derive_krdantas(&a, &dhatu.clone().with_prefixes(prefixes), args), - expected, - ); -} - -// Taddhitanta helpers -// ------------------- - -pub fn assert_has_taddhitanta(prati: impl IntoPratipadika, t: Taddhita, expected: &[&str]) { - assert_padas(derive_taddhitantas(&prati.to_p(), t, None), expected); -} - -pub fn assert_has_artha_taddhita( - prati: &str, - requested_artha: TaddhitaArtha, - taddhita: Taddhita, - expected: &[&str], -) { - let t = Tester::default(); - t.assert_has_artha_taddhita(prati, requested_artha, taddhita, expected); -} - -// Subanta helpers -// --------------- - -/// Like `assert_has_subantas_p` but without any filtering on the last sound. -/// (Needed for 8.4.56.) -pub fn assert_has_subantas_raw( - pratipadika_text: &str, - linga: Linga, - vibhakti: Vibhakti, - vacana: Vacana, - expected: &[&str], -) { - let pratipadika = Pratipadika::from(pratipadika_text); - let a = Ashtadhyayi::new(); - let args = SubantaArgs::builder() - .linga(linga) - .vacana(vacana) - .vibhakti(vibhakti) - .build() - .unwrap(); - - let mut results = a.derive_subantas(&pratipadika, &args); - results.sort_by_key(|p| p.text()); - results.dedup_by_key(|p| p.text()); - let actual: Vec<_> = results.into_iter().collect(); - assert_padas(actual, expected); -} - -pub trait IntoPratipadika { - fn to_p(self) -> Pratipadika; -} - -impl IntoPratipadika for &Pratipadika { - fn to_p(self) -> Pratipadika { - self.clone() - } -} - -impl IntoPratipadika for &str { - fn to_p(self) -> Pratipadika { - Pratipadika::from(self) - } -} - -macro_rules! assert_sup { - ($fn_name:ident, $vibhakti:expr, $vacana:expr) => { - pub fn $fn_name(prati: impl IntoPratipadika, linga: Linga, expected: &[&str]) { - let t = Tester::default(); - t.assert_has_sup(&prati.to_p(), linga, $vibhakti, $vacana, &expected); - } - }; -} - -assert_sup!(assert_has_sup_1s, Prathama, Eka); -assert_sup!(assert_has_sup_1d, Prathama, Dvi); -assert_sup!(assert_has_sup_1p, Prathama, Bahu); -assert_sup!(assert_has_sup_2s, Dvitiya, Eka); -assert_sup!(assert_has_sup_2d, Dvitiya, Dvi); -assert_sup!(assert_has_sup_2p, Dvitiya, Bahu); -assert_sup!(assert_has_sup_3s, Trtiya, Eka); -assert_sup!(assert_has_sup_3d, Trtiya, Dvi); -assert_sup!(assert_has_sup_3p, Trtiya, Bahu); -assert_sup!(assert_has_sup_4s, Caturthi, Eka); -assert_sup!(assert_has_sup_4d, Caturthi, Dvi); -assert_sup!(assert_has_sup_4p, Caturthi, Bahu); -assert_sup!(assert_has_sup_5s, Panchami, Eka); -assert_sup!(assert_has_sup_5d, Panchami, Dvi); -assert_sup!(assert_has_sup_5p, Panchami, Bahu); -assert_sup!(assert_has_sup_6s, Sasthi, Eka); -assert_sup!(assert_has_sup_6d, Sasthi, Dvi); -assert_sup!(assert_has_sup_6p, Sasthi, Bahu); -assert_sup!(assert_has_sup_7s, Saptami, Eka); -assert_sup!(assert_has_sup_7d, Saptami, Dvi); -assert_sup!(assert_has_sup_7p, Saptami, Bahu); -assert_sup!(assert_has_sup_ss, Sambodhana, Eka); -assert_sup!(assert_has_sup_sd, Sambodhana, Dvi); -assert_sup!(assert_has_sup_sp, Sambodhana, Bahu); - -macro_rules! create_sup { - ($fn_name:ident, $vibhakti:expr, $vacana:expr) => { - pub fn $fn_name(expected: &str, prati: impl IntoPratipadika, linga: Linga) -> Pada { - let t = Tester::default(); - t.create_sup(&expected, &prati.to_p(), linga, $vibhakti, $vacana) - } - }; -} - -create_sup!(create_sup_1s, Prathama, Eka); -create_sup!(create_sup_1d, Prathama, Dvi); -create_sup!(create_sup_1p, Prathama, Bahu); -create_sup!(create_sup_2s, Dvitiya, Eka); -create_sup!(create_sup_2d, Dvitiya, Dvi); -create_sup!(create_sup_2p, Dvitiya, Bahu); -create_sup!(create_sup_3s, Trtiya, Eka); -create_sup!(create_sup_3d, Trtiya, Dvi); -create_sup!(create_sup_3p, Trtiya, Bahu); -create_sup!(create_sup_4s, Caturthi, Eka); -create_sup!(create_sup_4d, Caturthi, Dvi); -create_sup!(create_sup_4p, Caturthi, Bahu); -create_sup!(create_sup_5s, Panchami, Eka); -create_sup!(create_sup_5d, Panchami, Dvi); -create_sup!(create_sup_5p, Panchami, Bahu); -create_sup!(create_sup_6s, Sasthi, Eka); -create_sup!(create_sup_6d, Sasthi, Dvi); -create_sup!(create_sup_6p, Sasthi, Bahu); -create_sup!(create_sup_7s, Saptami, Eka); -create_sup!(create_sup_7d, Saptami, Dvi); -create_sup!(create_sup_7p, Saptami, Bahu); -create_sup!(create_sup_ss, Sambodhana, Eka); -create_sup!(create_sup_sd, Sambodhana, Dvi); -create_sup!(create_sup_sp, Sambodhana, Bahu); - -macro_rules! assert_samasa { - ($fn_name:ident) => { - pub fn $fn_name( - purva: impl IntoPratipadika, - uttara: impl IntoPratipadika, - expected: &[&str], - ) { - let t = Tester::default(); - t.$fn_name(purva, uttara, expected); - } - }; -} - -assert_samasa!(assert_has_bahuvrihi); -assert_samasa!(assert_has_avyayibhava); -assert_samasa!(assert_has_karmadharaya); -assert_samasa!(assert_has_dvitiya_tatpurusha); -assert_samasa!(assert_has_trtiya_tatpurusha); -assert_samasa!(assert_has_caturthi_tatpurusha); -assert_samasa!(assert_has_panchami_tatpurusha); -assert_samasa!(assert_has_sasthi_tatpurusha); -assert_samasa!(assert_has_saptami_tatpurusha); - -pub fn assert_has_avyaya_tatpurusha( - first: impl IntoPratipadika, - second: impl IntoPratipadika, - expected: &[&str], -) { - let t = Tester::default(); - t.assert_samasa_of_type( - &[ - SamasaPada::avyaya(first.to_p()), - SamasaPada::new(second.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); -} - -pub fn assert_has_misc_tatpurusha( - first: impl IntoPratipadika, - second: impl IntoPratipadika, - expected: &[&str], -) { - let t = Tester::default(); - t.assert_samasa_of_type( - &[ - SamasaPada::new(first.to_p(), Vibhakti::Sasthi), - SamasaPada::new(second.to_p(), Vibhakti::Prathama), - ], - Tatpurusha, - expected, - ); -} - -pub fn assert_has_dvandva(items: &[&str], expected: &[&str]) { - let args = SamasaArgs::builder() - .padas( - items - .iter() - .map(|s| SamasaPada::new(Pratipadika::from(s), Vibhakti::Prathama)) - .collect(), - ) - .samasa_type(Dvandva) - .build() - .unwrap(); - let t = Tester::default(); - t.assert_has_samasas(&args, expected); -} - -pub fn assert_has_samahara_dvandva(items: &[&str], expected: &[&str]) { - let args = SamasaArgs::builder() - .padas( - items - .iter() - .map(|s| SamasaPada::new(Pratipadika::from(s), Vibhakti::Prathama)) - .collect(), - ) - .samasa_type(SamaharaDvandva) - .build() - .unwrap(); - let t = Tester::default(); - t.assert_has_samasas(&args, expected); -} diff --git a/vidyut-prakriya/tests/api.rs b/vidyut-prakriya/tests/api.rs index b753d3a..60dd6e0 100644 --- a/vidyut-prakriya/tests/api.rs +++ b/vidyut-prakriya/tests/api.rs @@ -18,20 +18,22 @@ fn derive_tinantas() { .unwrap(); // Should get 2 results. - let args_ubhaya = TinantaArgs::builder() + let args_ubhaya = Tinanta::builder() + .dhatu(kr.clone()) .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) .vacana(Vacana::Eka) .lakara(Lakara::Lat) .build() .unwrap(); - let prakriyas = a.derive_tinantas(&kr, &args_ubhaya); + let prakriyas = a.derive_tinantas(&args_ubhaya); let results: Vec<_> = prakriyas.iter().map(|x| x.text()).collect(); assert!(results.iter().any(|x| x == "karoti")); assert!(results.iter().any(|x| x == "kurute")); // Should get 1 parasmaipada result. - let args_parasmai = TinantaArgs::builder() + let args_parasmai = Tinanta::builder() + .dhatu(kr.clone()) .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) .vacana(Vacana::Eka) @@ -39,12 +41,13 @@ fn derive_tinantas() { .pada(DhatuPada::Parasmai) .build() .unwrap(); - let prakriyas = a.derive_tinantas(&kr, &args_parasmai); + let prakriyas = a.derive_tinantas(&args_parasmai); assert_eq!(prakriyas.len(), 1); assert!(prakriyas[0].text() == "karoti"); // Should get 1 Atmanepada result. - let args_atmane = TinantaArgs::builder() + let args_atmane = Tinanta::builder() + .dhatu(kr.clone()) .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) .vacana(Vacana::Eka) @@ -52,7 +55,7 @@ fn derive_tinantas() { .pada(DhatuPada::Atmane) .build() .unwrap(); - let prakriyas = a.derive_tinantas(&kr, &args_atmane); + let prakriyas = a.derive_tinantas(&args_atmane); assert_eq!(prakriyas.len(), 1); assert!(prakriyas[0].text() == "kurute"); } @@ -60,13 +63,6 @@ fn derive_tinantas() { #[test] fn derive_tinantas_with_invalid_dhatu() { let a = Ashtadhyayi::new(); - let args = TinantaArgs::builder() - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lat) - .build() - .unwrap(); let empty_dhatu = Dhatu::builder() .upadesha("") @@ -74,8 +70,17 @@ fn derive_tinantas_with_invalid_dhatu() { .build() .unwrap(); + let args = Tinanta::builder() + .dhatu(empty_dhatu) + .prayoga(Prayoga::Kartari) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .lakara(Lakara::Lat) + .build() + .unwrap(); + // The current API contract returns an empty vec if there's a severe error. - let prakriyas = a.derive_tinantas(&empty_dhatu, &args); + let prakriyas = a.derive_tinantas(&args); assert_eq!(prakriyas.len(), 0); let invalid_dhatu = Dhatu::builder() @@ -84,31 +89,38 @@ fn derive_tinantas_with_invalid_dhatu() { .build() .unwrap(); - let prakriyas = a.derive_tinantas(&invalid_dhatu, &args); + let args = args.with_dhatu(invalid_dhatu); + let prakriyas = a.derive_tinantas(&args); assert_eq!(prakriyas.len(), 0); } #[test] fn derive_krdantas() { let a = Ashtadhyayi::new(); - let args = KrdantaArgs::builder().krt(Krt::ktvA).build().unwrap(); let kr = Dhatu::builder() .upadesha("qukf\\Y") .gana(Gana::Tanadi) .build() .unwrap(); - let prakriyas = a.derive_krdantas(&kr, &args); + + let args = Krdanta::builder().dhatu(kr).krt(Krt::ktvA).build().unwrap(); + let prakriyas = a.derive_krdantas(&args); let results: Vec<_> = prakriyas.iter().map(|x| x.text()).collect(); assert!(results.iter().any(|x| x == "kftvA")); - let kr = Dhatu::builder() + let kr_san = Dhatu::builder() .upadesha("qukf\\Y") .gana(Gana::Tanadi) - .sanadi(&[Sanadi::Nic]) + .sanadi(&[Sanadi::Ric]) + .build() + .unwrap(); + let args = Krdanta::builder() + .dhatu(kr_san) + .krt(Krt::ktvA) .build() .unwrap(); - let prakriyas = a.derive_krdantas(&kr, &args); + let prakriyas = a.derive_krdantas(&args); let results: Vec<_> = prakriyas.iter().map(|x| x.text()).collect(); assert!(results.iter().any(|x| x == "kArayitvA")); } diff --git a/vidyut-prakriya/tests/basic_krdantas.rs b/vidyut-prakriya/tests/basic_krdantas.rs index 28ebaab..6f65e89 100644 --- a/vidyut-prakriya/tests/basic_krdantas.rs +++ b/vidyut-prakriya/tests/basic_krdantas.rs @@ -13,10 +13,10 @@ use vidyut_prakriya::Ashtadhyayi; /// Creates a krdanta with the given args. fn create_krdanta(dhatu: &str, gana: &str, krt: BaseKrt) -> Vec { let a = Ashtadhyayi::new(); - let dhatu = Dhatu::new(dhatu, gana.parse().expect("ok")); - let args = KrdantaArgs::builder().krt(krt).build().unwrap(); + let dhatu = Dhatu::mula(dhatu, gana.parse().expect("ok")); + let args = Krdanta::builder().dhatu(dhatu).krt(krt).build().unwrap(); - let prakriyas = a.derive_krdantas(&dhatu, &args); + let prakriyas = a.derive_krdantas(&args); prakriyas.iter().map(|p| p.text()).collect() } diff --git a/vidyut-prakriya/tests/basic_tinantas.rs b/vidyut-prakriya/tests/basic_tinantas.rs index 497b5b7..9c7e8e9 100644 --- a/vidyut-prakriya/tests/basic_tinantas.rs +++ b/vidyut-prakriya/tests/basic_tinantas.rs @@ -1,5 +1,4 @@ use vidyut_prakriya::args::*; -use vidyut_prakriya::dhatupatha; use vidyut_prakriya::Ashtadhyayi; fn derive(upadesha: &str, gana: &str, prayoga: Prayoga) -> Vec { @@ -10,7 +9,8 @@ fn derive(upadesha: &str, gana: &str, prayoga: Prayoga) -> Vec { .build() .unwrap(); - let args = TinantaArgs::builder() + let args = Tinanta::builder() + .dhatu(dhatu) .prayoga(prayoga) .purusha(Purusha::Prathama) .vacana(Vacana::Eka) @@ -18,15 +18,10 @@ fn derive(upadesha: &str, gana: &str, prayoga: Prayoga) -> Vec { .build() .unwrap(); - let prakriyas = a.derive_tinantas(&dhatu, &args); + let prakriyas = a.derive_tinantas(&args); prakriyas.iter().map(|p| p.text()).collect() } -fn assert_contains(words: &[String], needle: &str) { - let found = words.iter().any(|w| w == needle); - assert!(found, "Could not find item `{needle}` in {words:?}"); -} - fn run_test_cases(cases: &[(&str, u8, &str)], prayoga: Prayoga) { let mut num_failed = 0; for (dhatu, gana, expected) in cases { @@ -53,52 +48,6 @@ fn run_test_cases(cases: &[(&str, u8, &str)], prayoga: Prayoga) { assert_eq!(num_failed, 0); } -#[test] -fn with_upasargas() { - let a = Ashtadhyayi::new(); - - let lat = TinantaArgs::builder() - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lat) - .build() - .unwrap(); - - let lan = TinantaArgs::builder() - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lan) - .build() - .unwrap(); - - let derive = |dhatu, args| { - let prakriyas = a.derive_tinantas(dhatu, args); - let results: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - results - }; - - // Default upasarga - let adhi_i = dhatupatha::create_dhatu("i\\N", Gana::Adadi, 41).unwrap(); - let results = derive(&adhi_i, &lat); - assert_contains(&results, "aDIte"); - - // Optional upasarga - let anu_bhu = Dhatu::builder() - .upadesha("BU") - .gana(Gana::Bhvadi) - .prefixes(&["anu"]) - .build() - .unwrap(); - - let results = derive(&anu_bhu, &lat); - assert_contains(&results, "anuBavati"); - - let results = derive(&anu_bhu, &lan); - assert_contains(&results, "anvaBavat"); -} - #[test] fn karmani() { let cases = &[ diff --git a/vidyut-prakriya/tests/kashika_1_1.rs b/vidyut-prakriya/tests/kashika_1_1.rs index 5bbe673..703e909 100644 --- a/vidyut-prakriya/tests/kashika_1_1.rs +++ b/vidyut-prakriya/tests/kashika_1_1.rs @@ -1,4 +1,5 @@ extern crate test_utils; +use lazy_static::lazy_static; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; @@ -11,14 +12,18 @@ use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; use vidyut_prakriya::args::Vacana::*; +lazy_static! { + static ref S: Tester = Tester::with_svara_rules(); +} + #[test] fn sutra_1_1_1() { - assert_has_taddhitanta(&prati("aSvala"), T::Pak, &["ASvalAyana"]); - assert_has_taddhitanta(&prati("itika"), T::Pak, &["EtikAyana"]); - assert_has_taddhitanta(&prati("upagu"), T::aR, &["Opagava"]); - assert_has_taddhitanta(&prati("upamanyu"), T::aR, &["Opamanyava"]); - assert_has_taddhitanta(&prati("SAlA"), T::Ca, &["SAlIya"]); - assert_has_taddhitanta(&prati("mAlA"), T::Ca, &["mAlIya"]); + assert_has_taddhita("aSvala", T::Pak, &["ASvalAyana"]); + assert_has_taddhita("itika", T::Pak, &["EtikAyana"]); + assert_has_taddhita("upagu", T::aR, &["Opagava"]); + assert_has_taddhita("upamanyu", T::aR, &["Opamanyava"]); + assert_has_taddhita("SAlA", T::Ca, &["SAlIya"]); + assert_has_taddhita("mAlA", T::Ca, &["mAlIya"]); } #[test] @@ -106,8 +111,8 @@ fn sutra_1_1_5() { // Niti assert_has_tas(&[], &ci, Lat, &["cinutaH"]); assert_has_jhi(&[], &ci, Lat, &["cinvanti"]); - assert_has_tinanta(&[], &mfj, Lat, P::Prathama, Dvi, &["mfzwaH"]); - assert_has_tinanta(&[], &mfj, Lat, P::Prathama, Bahu, &["mfjanti"]); + assert_has_tinantas(&[], &mfj, Lat, P::Prathama, Dvi, &["mfzwaH"]); + assert_has_tinantas(&[], &mfj, Lat, P::Prathama, Bahu, &["mfjanti"]); // git assert_has_krdanta(&[], &d("ji\\", Bhvadi), Krt::ksnu, &["jizRu"]); @@ -115,7 +120,7 @@ fn sutra_1_1_5() { // ikaH assert_has_lat(&[], &d("kamu~\\", Bhvadi), &["kAmayate"]); - assert_has_taddhitanta(&prati("ligu"), T::Pak, &["lEgavAyana"]); + assert_has_taddhita("ligu", T::Pak, &["lEgavAyana"]); // lakAra-Nit assert_has_mip(&[], &ci, Lan, &["acinavam"]); @@ -151,21 +156,21 @@ fn sutra_1_1_9() { fn sutra_1_1_10() { assert_has_sandhi("daRqa", "hasta", &["daRqahasta"]); assert_has_sandhi("daDi", "SItam", &["daDiSItam"]); - assert_has_taddhitanta(&prati("vipASa"), T::aR, &["vEpASa"]); + assert_has_taddhita("vipASa", T::aR, &["vEpASa"]); // TODO: anaquham } #[test] fn sutra_1_1_11() { - let hari = create_sup_1d("harI", "hari", Pum); - let etau = create_sup_1d("etO", "etad", Pum); + let hari = sup_1d("harI", "hari", Pum); + let etau = sup_1d("etO", "etad", Pum); assert_has_vakya(&hari, &etau, &["harI etO"]); } #[test] fn sutra_1_1_12() { - let ami = create_sup_1p("amI", "adas", Pum); - let amu = create_sup_1d("amU", "adas", Pum); + let ami = sup_1p("amI", "adas", Pum); + let amu = sup_1d("amU", "adas", Pum); let atra = Pada::from_text("atra"); let asate = Pada::from_text("Asate"); @@ -183,6 +188,43 @@ fn sutra_1_1_12() { // TODO: amuke } +#[test] +fn sutra_1_1_14() { + let a = Pada::nipata("a"); + let apehi = Pada::from_text("apehi"); + assert_has_vakya(&a, &apehi, &["a apehi"]); + + let i = Pada::nipata("i"); + let indra = Pada::from_text("indram"); + assert_has_vakya(&i, &indra, &["i indram"]); + + let u = Pada::nipata("u"); + let uttistha = Pada::from_text("uttizWa"); + assert_has_vakya(&u, &uttistha, &["u uttizWa"]); + + let aa = Pada::nipata("A"); + let evam = Pada::from_text("evam"); + assert_has_vakya(&aa, &evam, &["A evam"]); + + // nipAta? + let cakara = Pada::from_text("cakAra"); + let jahara = Pada::from_text("jahAra"); + let atra = Pada::from_text("atra"); + assert_has_vakya(&cakara, &atra, &["cakArAtra"]); + assert_has_vakya(&jahara, &atra, &["jahArAtra"]); + + // ekAc? + let pra = Pada::nipata("pra"); + let agnaye = Pada::from_text("agnaye"); + assert_has_vakya(&pra, &agnaye, &["prAgnaye"]); + + // anAN? + let aan = Pada::nipata("AN"); + let udakantat = Pada::from_text("udakAntAt"); + assert_has_vakya(&aa, &udakantat, &["A udakAntAt"]); + assert_has_vakya(&aan, &udakantat, &["odakAntAt"]); +} + #[test] fn sutra_1_1_15() { let aho = Pada::nipata("Aho"); @@ -228,27 +270,32 @@ fn sutra_1_1_20() { assert_has_krdanta(&["ava"], &d("dE\\p", Bhvadi), Krt::kta, &["avadAta"]); } +#[test] +fn sutra_1_1_21() { + S.assert_has_krt(&[], &d("qukf\\Y", Tanadi), Krt::tavya, &["karta/vya"]); + S.assert_has_taddhita("upagu", T::aR, &["Opagava/"]); + assert_has_sup_3d("vfkza", Pum, &["vfkzAByAm"]); +} + #[test] fn sutra_1_1_22() { - assert_has_taddhitanta(&prati("kumArI"), T::tarap, &["kumAritara"]); - assert_has_taddhitanta(&prati("kumArI"), T::tamap, &["kumAritama"]); - assert_has_taddhitanta(&prati("brAhmaRI"), T::tarap, &["brAhmaRitara"]); - assert_has_taddhitanta(&prati("brAhmaRI"), T::tamap, &["brAhmaRitama"]); + assert_has_taddhita("kumArI", T::tarap, &["kumAritara"]); + assert_has_taddhita("kumArI", T::tamap, &["kumAritama"]); + assert_has_taddhita("brAhmaRI", T::tarap, &["brAhmaRitara"]); + assert_has_taddhita("brAhmaRI", T::tamap, &["brAhmaRitama"]); } #[test] fn sutra_1_1_23() { // TODO: others - let bahu = prati("bahu"); - assert_has_taddhitanta(&bahu, T::kftvasuc, &["bahukftvas"]); - assert_has_taddhitanta(&bahu, T::DA, &["bahuDA"]); - assert_has_taddhitanta(&bahu, T::kan, &["bahuka"]); + assert_has_taddhita("bahu", T::kftvasuc, &["bahukftvas"]); + assert_has_taddhita("bahu", T::DA, &["bahuDA"]); + assert_has_taddhita("bahu", T::kan, &["bahuka"]); // TODO: assert_has_taddhitanta(&bahu, T::Sas, &["bahuSas"]); - let gana = prati("gaRa"); - assert_has_taddhitanta(&gana, T::kftvasuc, &["gaRakftvas"]); - assert_has_taddhitanta(&gana, T::DA, &["gaRaDA"]); - assert_has_taddhitanta(&gana, T::kan, &["gaRaka"]); + assert_has_taddhita("gaRa", T::kftvasuc, &["gaRakftvas"]); + assert_has_taddhita("gaRa", T::DA, &["gaRaDA"]); + assert_has_taddhita("gaRa", T::kan, &["gaRaka"]); // TODO: assert_has_taddhitanta(&gana, T::Sas, &["gaRaSas"]); // TODO: @@ -277,6 +324,11 @@ fn sutra_1_1_24() { assert_has_sup_1p("sahasra", Napumsaka, &["sahasrARi"]); } +#[test] +fn sutra_1_1_25() { + assert_has_taddhita("kim", T::qati, &["kati"]); +} + #[test] fn sutra_1_1_26() { let kf = d("qukf\\Y", Tanadi); @@ -298,7 +350,7 @@ fn sutra_1_1_27() { assert_has_sup_5s("sarva", Pum, &["sarvasmAt"]); assert_has_sup_6p("sarva", Pum, &["sarvezAm"]); assert_has_sup_7s("sarva", Pum, &["sarvasmin"]); - // assert_has_taddhitanta(&prati("sarva"), T::akac, &["sarvaka"]); + // assert_has_taddhitanta("sarva", T::akac, &["sarvaka"]); assert_has_sup_1s("viSva", Pum, &["viSvaH"]); assert_has_sup_1d("viSva", Pum, &["viSvO"]); @@ -307,7 +359,7 @@ fn sutra_1_1_27() { assert_has_sup_5s("viSva", Pum, &["viSvasmAt"]); assert_has_sup_6p("viSva", Pum, &["viSvezAm"]); assert_has_sup_7s("viSva", Pum, &["viSvasmin"]); - // assert_has_taddhitanta(&prati("viSva"), T::akac, &["viSvaka"]); + // assert_has_taddhitanta("viSva", T::akac, &["viSvaka"]); assert_has_sup_1p("uBaya", Pum, &["uBaye"]); assert_has_sup_4s("uBaya", Pum, &["uBayasmE"]); @@ -590,6 +642,19 @@ fn sutra_1_1_61() { // TODO: lup } +#[test] +fn sutra_1_1_62() { + assert_has_upapada_krdanta("agni", &[], &d("ci\\Y", Svadi), Krt::kvip, &["agnicit"]); + assert_has_upapada_krdanta("soma", &[], &d("zu\\Y", Svadi), Krt::kvip, &["somasut"]); + let duh = d("du\\ha~^", Adadi); + assert_has_tip(&[], &duh, Lan, &["aDok"]); + + // TODO: how to derive AGnIya, AgmIya? + + assert_has_sasthi_tatpurusha("rE", "kula", &["rEkula"]); + assert_has_caturthi_tatpurusha("go", "hita", &["gohita"]); +} + #[test] fn sutra_1_1_64() { assert_has_upapada_krdanta("agni", &[], &d("ci\\Y", Svadi), Krt::kvip, &["agnicit"]); @@ -600,6 +665,9 @@ fn sutra_1_1_64() { assert_has_aathaam(&[], &pac, Lat, &["paceTe"]); } +#[test] +fn skip_sutra_1_1_65() {} + #[test] fn sutra_1_1_66() { assert_has_sandhi("daDi", "udakam", &["daDyudakam"]); @@ -608,29 +676,45 @@ fn sutra_1_1_66() { assert_has_sandhi("agnicit", "atra", &["agnicid atra"]); } +#[test] +fn sutra_1_1_70() { + assert_has_sup_3p("vfkza", Pum, &["vfkzEH"]); + assert_has_sup_3p("plakza", Pum, &["plakzEH"]); + + let jan = d("janI~\\", Divadi); + let abja = create_upapada_krdanta("abjA", "ap", &[], &jan, Krt::viw); + let goja = create_upapada_krdanta("gojA", "go", &[], &jan, Krt::viw); + assert_has_sup_1s(&abja, Pum, &["abjAH"]); + assert_has_sup_1s(&goja, Pum, &["gojAH"]); + + // tatkAlasya? + assert_has_sup_3p("KawvA", Stri, &["KawvABiH"]); + assert_has_sup_3p("mAlA", Stri, &["mAlABiH"]); +} + #[test] fn skip_sutra_1_1_71() {} #[test] fn sutra_1_1_73() { - assert_has_taddhitanta(&nyap("SAlA"), T::Ca, &["SAlIya"]); - assert_has_taddhitanta(&nyap("mAlA"), T::Ca, &["mAlIya"]); - assert_has_taddhitanta("Opagava", T::Ca, &["OpagavIya"]); - assert_has_taddhitanta("kApawava", T::Ca, &["kApawavIya"]); + assert_has_taddhita(&nyap("SAlA"), T::Ca, &["SAlIya"]); + assert_has_taddhita(&nyap("mAlA"), T::Ca, &["mAlIya"]); + assert_has_taddhita("Opagava", T::Ca, &["OpagavIya"]); + assert_has_taddhita("kApawava", T::Ca, &["kApawavIya"]); } #[test] fn sutra_1_1_74() { - assert_has_taddhitanta("tyad", T::Ca, &["tyadIya"]); - assert_has_taddhitanta("tad", T::Ca, &["tadIya"]); - assert_has_taddhitanta("etad", T::Ca, &["etadIya"]); - assert_has_taddhitanta("idam", T::Ca, &["idamIya"]); - assert_has_taddhitanta("adas", T::Ca, &["adasIya"]); + assert_has_taddhita("tyad", T::Ca, &["tyadIya"]); + assert_has_taddhita("tad", T::Ca, &["tadIya"]); + assert_has_taddhita("etad", T::Ca, &["etadIya"]); + assert_has_taddhita("idam", T::Ca, &["idamIya"]); + assert_has_taddhita("adas", T::Ca, &["adasIya"]); // TODO: enable these. // assert_has_taddhitanta("yuzmad", T::Ca, &["tvadIya"]); // assert_has_taddhitanta("yuzmad", T::PiY, &["tvAdAyani"]); // assert_has_taddhitanta("asmad", T::Ca, &["madIya"]); // assert_has_taddhitanta("asmad", T::PiY, &["mAdAyani"]); // assert_has_taddhitanta("Bavatu~", T::Ca, &["BavadIya"]); - assert_has_taddhitanta("kim", T::Ca, &["kimIya"]); + assert_has_taddhita("kim", T::Ca, &["kimIya"]); } diff --git a/vidyut-prakriya/tests/kashika_1_2.rs b/vidyut-prakriya/tests/kashika_1_2.rs index 7fe9200..5708697 100644 --- a/vidyut-prakriya/tests/kashika_1_2.rs +++ b/vidyut-prakriya/tests/kashika_1_2.rs @@ -11,12 +11,12 @@ use vidyut_prakriya::args::*; fn sutra_1_2_1() { assert_has_ta(&["aDi"], &d("i\\N", Adadi), Lun, &["aDyagIzwa", "aDyEzwa"]); - let kuw = d("kuwa~", Tudadi).with_antargana(Some(Antargana::Kutadi)); + let kuw = d_kutadi("kuwa~", Tudadi); assert_has_krdanta(&[], &kuw, Krt::tfc, &["kuwitf"]); assert_has_krdanta(&[], &kuw, Krt::tumun, &["kuwitum"]); assert_has_krdanta(&[], &kuw, Krt::tavya, &["kuwitavya"]); - let puw = d("puwa~", Tudadi).with_antargana(Some(Antargana::Kutadi)); + let puw = d_kutadi("puwa~", Tudadi); assert_has_krdanta(&["ud"], &puw, Krt::tfc, &["utpuwitf"]); assert_has_krdanta(&["ud"], &puw, Krt::tumun, &["utpuwitum"]); assert_has_krdanta(&["ud"], &puw, Krt::tavya, &["utpuwitavya"]); @@ -182,7 +182,6 @@ fn sutra_1_2_9() { assert_has_tip(&[], &san(&d("jYapa~", Curadi)), Lat, &["jYIpsati"]); } -#[ignore] #[test] fn sutra_1_2_10() { assert_has_tip(&[], &san(&d("Bi\\di~^r", Rudhadi)), Lat, &["biBitsati"]); @@ -191,8 +190,13 @@ fn sutra_1_2_10() { assert_has_ta(&[], &san(&d("ya\\ja~^", Bhvadi)), Lat, &["yiyakzate"]); // Jal assert_has_ta(&[], &san(&d("vftu~\\", Bhvadi)), Lat, &["vivartizate"]); - // danB also in scope - assert_has_tip(&[], &san(&d("danBu~", Svadi)), Lat, &["DIpsati", "Dipsati"]); + // danB also in scope. + assert_has_tip( + &[], + &san(&d("danBu~", Svadi)), + Lat, + &["DIpsati", "Dipsati", "didamBizati"], + ); } #[test] @@ -504,13 +508,9 @@ fn sutra_1_2_46() { assert_has_sup_1s(&kapatava, Pum, &["kApawavaH"]); // samasa - let rajapurusha = create_tatpurusha("rAjapuruza", &["rAjan", "puruza"], Vibhakti::Sasthi); + let rajapurusha = tatpurusha("rAjan", "puruza", Vibhakti::Sasthi); assert_has_sup_1s(&rajapurusha, Pum, &["rAjapuruzaH"]); - let brahmanakambala = create_tatpurusha( - "brAhmaRakambala", - &["brAhmaRa", "kambala"], - Vibhakti::Sasthi, - ); + let brahmanakambala = tatpurusha("brAhmaRa", "kambala", Vibhakti::Sasthi); assert_has_sup_1s(&brahmanakambala, Pum, &["brAhmaRakambalaH"]); } diff --git a/vidyut-prakriya/tests/kashika_1_3.rs b/vidyut-prakriya/tests/kashika_1_3.rs index bbf4a60..d37bca9 100644 --- a/vidyut-prakriya/tests/kashika_1_3.rs +++ b/vidyut-prakriya/tests/kashika_1_3.rs @@ -70,11 +70,11 @@ fn sutra_1_3_6() { #[test] fn sutra_1_3_7() { // ca - assert_has_taddhitanta(&prati("kuYja"), T::cPaY, &["kOYjAyana"]); + assert_has_taddhita("kuYja", T::cPaY, &["kOYjAyana"]); // ja assert_has_sup_1p("brAhmaRa", Pum, &["brAhmaRAH"]); // Ya - assert_has_taddhitanta(&prati("SaRqika"), T::Yya, &["SARqikya"]); + assert_has_taddhita("SaRqika", T::Yya, &["SARqikya"]); // wa let car = &d("cara~", Bhvadi); assert_has_upapada_krdanta("kuru", &[], &car, Krt::wa, &["kurucara"]); @@ -113,10 +113,10 @@ fn sutra_1_3_8() { assert_has_sup_5s("vfkza", Pum, &["vfkzAt"]); assert_has_sup_6s("vfkza", Pum, &["vfkzasya"]); // ataddhite? - assert_has_taddhitanta(&prati("cUqA"), T::lac, &["cUqAla"]); - assert_has_taddhitanta(&prati("loman"), T::Sa, &["lomaSa"]); + assert_has_taddhita("cUqA", T::lac, &["cUqAla"]); + assert_has_taddhita("loman", T::Sa, &["lomaSa"]); // TODO: support kan-pratyaya here - // assert_has_taddhitanta(&prati("vfkza"), T::kan, &["vfkzaka"]); + // assert_has_taddhitanta("vfkza", T::kan, &["vfkzaka"]); } #[test] @@ -493,7 +493,7 @@ fn sutra_1_3_61() { #[test] fn sutra_1_3_62() { - let san = |u, gana| d(u, gana).with_sanadi(&[Sanadi::San]); + let san = |u, gana| d(u, gana).with_sanadi(&[Sanadi::san]); assert_has_lat(&[], &san("Asa~\\", Adadi), &["Asisizate"]); assert_has_lat(&[], &san("SIN", Adadi), &["SiSayizate"]); @@ -698,6 +698,13 @@ fn sutra_1_3_84_and_sutra_1_3_85() { assert_has_lat(&["upa"], &ram, &["uparamati", "uparamate"]); } +#[ignore] +#[test] +fn sutra_3_1_90() { + let kyas = |prati| Dhatu::nama(Pratipadika::basic(prati), None); + assert_has_lat(&[], &kyas("lohita"), &["lohitAyati", "lohitAyate"]); +} + #[test] fn sutra_1_3_91() { let dyut = &d("dyuta~\\", Bhvadi); diff --git a/vidyut-prakriya/tests/kashika_1_4.rs b/vidyut-prakriya/tests/kashika_1_4.rs index 2f9abd1..e625926 100644 --- a/vidyut-prakriya/tests/kashika_1_4.rs +++ b/vidyut-prakriya/tests/kashika_1_4.rs @@ -5,7 +5,6 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; -use vidyut_prakriya::args::*; #[test] fn sutra_1_4_3() { @@ -28,11 +27,7 @@ fn sutra_1_4_3() { #[test] fn sutra_1_4_4() { - let shri = Pratipadika::builder() - .text("SrI") - .is_dhatu(true) - .build() - .unwrap(); + let shri = krdanta(&[], &d("SriY", Bhvadi), Krt::kvip); assert_has_sup_ss(&shri, Stri, &["SrIH"]); assert_has_sup_ss("BrU", Stri, &["BrUH"]); // astrI @@ -112,8 +107,8 @@ fn sutra_1_4_13() { assert_has_tip(&[], &kf, Lrt, &["karizyati"]); assert_has_tip(&[], &hf, Lrt, &["harizyati"]); assert_has_tip(&[], &kf, Lrn, &["akarizyat"]); - assert_has_taddhitanta(&prati("upagu"), T::aR, &["Opagava"]); - assert_has_taddhitanta(&prati("kapawu"), T::aR, &["kApawava"]); + assert_has_taddhita("upagu", T::aR, &["Opagava"]); + assert_has_taddhita("kapawu", T::aR, &["kApawava"]); // pratyayagrahana assert_has_lan(&["ni"], &d("vi\\Sa~", Tudadi), &["nyaviSata"]); @@ -132,9 +127,9 @@ fn sutra_1_4_14() { #[test] fn sutra_1_4_16() { - assert_has_taddhitanta(&prati("Bavat"), T::Cas, &["BavadIya"]); - assert_has_taddhitanta(&prati("UrRA"), T::yus, &["UrRAyu"]); - assert_has_taddhitanta(&prati("ftu"), T::Gas, &["ftviya"]); + assert_has_taddhita("Bavat", T::Cas, &["BavadIya"]); + assert_has_taddhita("UrRA", T::yus, &["UrRAyu"]); + assert_has_taddhita("ftu", T::Gas, &["ftviya"]); } #[test] @@ -145,12 +140,12 @@ fn skip_sutra_1_4_18() {} #[test] fn sutra_1_4_19() { - assert_has_taddhitanta(&prati("udaSvit"), T::matup, &["udaSvitvat"]); - assert_has_taddhitanta(&prati("vidyut"), T::matup, &["vidyutvat"]); - assert_has_taddhitanta(&prati("payas"), T::vini, &["payasvin"]); - assert_has_taddhitanta(&prati("yaSas"), T::vini, &["yaSasvin"]); + assert_has_taddhita("udaSvit", T::matup, &["udaSvitvat"]); + assert_has_taddhita("vidyut", T::matup, &["vidyutvat"]); + assert_has_taddhita("payas", T::vini, &["payasvin"]); + assert_has_taddhita("yaSas", T::vini, &["yaSasvin"]); // tasau - assert_has_taddhitanta(&prati("takzan"), T::matup, &["takzavat"]); + assert_has_taddhita("takzan", T::matup, &["takzavat"]); } #[test] @@ -169,6 +164,9 @@ fn sutra_1_4_22() { assert_has_tip(&[], &path, Lat, &["paWati"]); } +#[test] +fn skip_sutra_1_4_58() {} + #[test] fn sutra_1_4_59() { let ni = d("RI\\Y", Bhvadi); @@ -178,10 +176,89 @@ fn sutra_1_4_59() { assert_has_krdanta(&["pari"], &ni, Krt::Rvul, &["pariRAyaka"]); } +#[ignore] +#[test] +fn sutra_1_4_63() { + let kr = d("qukf\\Y", Tanadi); + assert_has_upapada_krdanta("sat", &[], &kr, Krt::ktvA, &["satkftya", "sat kftvA"]); + assert_has_upapada_krdanta("sat", &[], &kr, Krt::kta, &["satkfta"]); + assert_has_tip(&["sat"], &kr, Lit, &["satkaroti"]); + assert_has_upapada_krdanta("asat", &[], &kr, Krt::ktvA, &["asatkftya", "asat kftvA"]); + assert_has_upapada_krdanta("asat", &[], &kr, Krt::kta, &["asatkfta"]); + assert_has_tip(&["asat"], &kr, Lit, &["asatkaroti"]); +} + +#[test] +fn sutra_1_4_60() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&["pra"], &kr, Krt::ktvA, &["prakftya"]); + assert_has_krdanta(&["pra"], &kr, Krt::kta, &["prakfta"]); + assert_has_tip(&["pra"], &kr, Lat, &["prakaroti"]); + + assert_has_krdanta(&["pra"], &d("RI\\Y", Bhvadi), Krt::kta, &["praRIta"]); + assert_has_krdanta(&["aBi"], &d("zi\\ca~^", Tudadi), Krt::kta, &["aBizikta"]); +} + +#[test] +fn sutra_1_4_67() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&["puras"], &kr, Krt::ktvA, &["puraskftya"]); + assert_has_krdanta(&["puras"], &kr, Krt::kta, &["puraskfta"]); +} + +#[test] +fn sutra_1_4_68() { + let gam = d("ga\\mx~", Bhvadi); + assert_has_krdanta(&["astam"], &gam, Krt::ktvA, &["astaNgatya", "astaNgamya"]); + assert_has_krdanta(&["astam"], &gam, Krt::kta, &["astaNgata"]); +} + +#[ignore] +#[test] +fn sutra_1_4_69() { + let gam = d("ga\\mx~", Bhvadi); + assert_has_krdanta(&["acCa"], &gam, Krt::ktvA, &["acCagatya", "acCagamya"]); + assert_has_krdanta(&["acCa"], &gam, Krt::kta, &["acCagata"]); + assert_has_tip(&["acCa"], &gam, Lat, &["acCagacCati"]); + + let vad = d("vada~", Bhvadi); + assert_has_krdanta(&["acCa"], &vad, Krt::ktvA, &["acCodya"]); + assert_has_krdanta(&["acCa"], &vad, Krt::kta, &["acCodita"]); + assert_has_tip(&["acCa"], &vad, Lat, &["acCavadati"]); +} + +#[ignore] +#[test] +fn sutra_1_4_70() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&["adas"], &kr, Krt::ktvA, &["adaHkftya"]); + assert_has_krdanta(&["adas"], &kr, Krt::kta, &["adaHkfta"]); + assert_has_tip(&["adas"], &kr, Lat, &["adaHkaroti"]); +} + +#[ignore] +#[test] +fn sutra_1_4_74() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&["maDye"], &kr, Krt::ktvA, &["maDyekftya", "maDyekftvA"]); + assert_has_krdanta(&["pade"], &kr, Krt::ktvA, &["padekftya", "padekftvA"]); + assert_has_krdanta( + &["nivacane"], + &kr, + Krt::ktvA, + &["nivacanekftya", "nivacanekftvA"], + ); +} + #[test] fn sutra_1_4_80() { assert_has_lat(&["vi"], &d("liKa~", Tudadi), &["viliKati"]); - assert_has_tip(&["tiras"], &d("qukf\\Y", Tanadi), Lat, &["tiraskaroti"]); + assert_has_tip( + &["tiras"], + &d("qukf\\Y", Tanadi), + Lat, + &["tiraskaroti", "tiraHkaroti"], + ); } #[test] diff --git a/vidyut-prakriya/tests/kashika_2_1.rs b/vidyut-prakriya/tests/kashika_2_1.rs index f79d2d8..576ef29 100644 --- a/vidyut-prakriya/tests/kashika_2_1.rs +++ b/vidyut-prakriya/tests/kashika_2_1.rs @@ -3,10 +3,10 @@ use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Dhatu; use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Krdanta; use vidyut_prakriya::args::Lakara::*; -use vidyut_prakriya::args::Pratipadika; -pub fn create_kta(text: &str, prefixes: &[&str], d: &Dhatu) -> Pratipadika { +pub fn create_kta(text: &str, prefixes: &[&str], d: &Dhatu) -> Krdanta { create_krdanta(text, prefixes, d, Krt::kta) } @@ -108,6 +108,12 @@ fn sutra_2_1_15() { assert_has_avyayibhava("anu", "vana", &["anuvanam"]); } +#[test] +fn sutra_2_1_19() { + assert_has_avyayibhava("dvi", "muni", &["dvimuni"]); + assert_has_avyayibhava("tri", "muni", &["trimuni"]); +} + #[test] fn sutra_2_1_24() { assert_has_dvitiya_tatpurusha("kazwa", "Srita", &["kazwaSrita"]); @@ -148,6 +154,13 @@ fn sutra_2_1_27() { assert_has_avyaya_tatpurusha("sAmi", &bhukta, &["sAmiBukta"]); } +#[test] +fn sutra_2_1_30() { + assert_has_trtiya_tatpurusha("SaNkulA", "KaRqa", &["SaNkulAKaRqa"]); + assert_has_trtiya_tatpurusha("kiri", "kARa", &["kirikARa"]); + assert_has_trtiya_tatpurusha("DAnya", "arTa", &["DAnyArTa"]); +} + #[test] fn sutra_2_1_31() { assert_has_trtiya_tatpurusha("mAsa", "pUrva", &["mAsapUrva"]); @@ -167,6 +180,14 @@ fn sutra_2_1_31() { assert_has_trtiya_tatpurusha("AcAra", "SlakzRa", &["AcAraSlakzRa"]); } +#[ignore] +#[test] +fn sutra_2_1_32() { + assert_has_trtiya_tatpurusha("ahi", "hata", &["ahihata"]); + assert_has_trtiya_tatpurusha("naKa", "nirBinna", &["naKanirBinna"]); + assert_has_trtiya_tatpurusha("paraSu", "Cinna", &["paraSucCinna"]); +} + #[test] fn sutra_2_1_33() { let peya = create_krdanta("peya", &[], &d("pA\\", Bhvadi), Krt::yat); @@ -250,6 +271,17 @@ fn sutra_2_1_42() { // TODO: others } +#[ignore] +#[test] +fn sutra_2_1_47() { + let bhukta = create_kta("Bukta", &[], &d("Bu\\ja~", Rudhadi)); + let krta = create_kta("kfta", &[], &d("qukf\\Y", Tanadi)); + let pita = create_kta("pIta", &[], &d("pA\\", Bhvadi)); + assert_has_saptami_tatpurusha("tatra", &bhukta, &["tatraBukta"]); + assert_has_saptami_tatpurusha("tatra", &krta, &["tatrakfta"]); + assert_has_saptami_tatpurusha("tatra", &pita, &["tatrapIta"]); +} + #[test] fn sutra_2_1_58() { assert_has_karmadharaya("pUrva", "puruza", &["pUrvapuruza"]); diff --git a/vidyut-prakriya/tests/kashika_2_2.rs b/vidyut-prakriya/tests/kashika_2_2.rs index 07d61b7..a5b21f3 100644 --- a/vidyut-prakriya/tests/kashika_2_2.rs +++ b/vidyut-prakriya/tests/kashika_2_2.rs @@ -1,6 +1,12 @@ extern crate test_utils; use test_utils::*; +#[test] +fn sutra_2_2_6() { + assert_has_avyaya_tatpurusha("naY", "brAhmaRa", &["abrAhmaRa"]); + assert_has_avyaya_tatpurusha("naY", "vfzala", &["avfzala"]); +} + #[test] fn sutra_2_2_8() { assert_has_sasthi_tatpurusha("rAjan", "puruza", &["rAjapuruza"]); diff --git a/vidyut-prakriya/tests/kashika_2_4.rs b/vidyut-prakriya/tests/kashika_2_4.rs index 4025c6a..c2f9668 100644 --- a/vidyut-prakriya/tests/kashika_2_4.rs +++ b/vidyut-prakriya/tests/kashika_2_4.rs @@ -134,79 +134,50 @@ fn sutra_2_4_46() { fn sutra_2_4_47() { let i_san = san(&d("i\\R", Adadi)); assert_has_tip(&[], &i_san, Lat, &["jigamizati", "Izizati"]); - assert_has_tip(&[], &i_san, Lat, &["jigamizataH", "IzizataH"]); - assert_has_tip(&[], &i_san, Lat, &["jigamizanti", "Izizanti"]); + assert_has_tas(&[], &i_san, Lat, &["jigamizataH", "IzizataH"]); + assert_has_jhi(&[], &i_san, Lat, &["jigamizanti", "Izizanti"]); // TODO: others } #[test] fn sutra_2_4_48() { let i_san = san(&d("i\\N", Adadi)); - assert_has_tinanta(&["aDi"], &i_san, Lat, Prathama, Eka, &["aDijigAMsate"]); - assert_has_tinanta(&["aDi"], &i_san, Lat, Prathama, Dvi, &["aDijigAMsete"]); - assert_has_tinanta(&["aDi"], &i_san, Lat, Prathama, Bahu, &["aDijigAMsante"]); + assert_has_ta(&["aDi"], &i_san, Lat, &["aDijigAMsate"]); + assert_has_aataam(&["aDi"], &i_san, Lat, &["aDijigAMsete"]); + assert_has_jha(&["aDi"], &i_san, Lat, &["aDijigAMsante"]); } #[test] fn sutra_2_4_49() { let i = d("i\\N", Adadi); - assert_has_tinanta(&["aDi"], &i, Lit, Prathama, Eka, &["aDijage"]); - assert_has_tinanta(&["aDi"], &i, Lit, Prathama, Dvi, &["aDijagAte"]); - assert_has_tinanta(&["aDi"], &i, Lit, Prathama, Bahu, &["aDijagire"]); + assert_has_ta(&["aDi"], &i, Lit, &["aDijage"]); + assert_has_aataam(&["aDi"], &i, Lit, &["aDijagAte"]); + assert_has_jha(&["aDi"], &i, Lit, &["aDijagire"]); } #[test] fn sutra_2_4_50() { let i = d("i\\N", Adadi); - assert_has_tinanta(&["aDi"], &i, Lun, Prathama, Eka, &["aDyagIzwa", "aDyEzwa"]); - assert_has_tinanta( - &["aDi"], - &i, - Lun, - Prathama, - Dvi, - &["aDyagIzAtAm", "aDyEzAtAm"], - ); - assert_has_tinanta( - &["aDi"], - &i, - Lun, - Prathama, - Bahu, - &["aDyagIzata", "aDyEzata"], - ); - assert_has_tinanta( - &["aDi"], - &i, - Lrn, - Prathama, - Eka, - &["aDyagIzyata", "aDyEzyata"], - ); - assert_has_tinanta( - &["aDi"], - &i, - Lrn, - Prathama, - Dvi, - &["aDyagIzyetAm", "aDyEzyetAm"], - ); - assert_has_tinanta( - &["aDi"], - &i, - Lrn, - Prathama, - Bahu, - &["aDyagIzyanta", "aDyEzyanta"], - ); + assert_has_ta(&["aDi"], &i, Lun, &["aDyagIzwa", "aDyEzwa"]); + assert_has_aataam(&["aDi"], &i, Lun, &["aDyagIzAtAm", "aDyEzAtAm"]); + assert_has_jha(&["aDi"], &i, Lun, &["aDyagIzata", "aDyEzata"]); + + assert_has_ta(&["aDi"], &i, Lrn, &["aDyagIzyata", "aDyEzyata"]); + assert_has_aataam(&["aDi"], &i, Lrn, &["aDyagIzyetAm", "aDyEzyetAm"]); + assert_has_jha(&["aDi"], &i, Lrn, &["aDyagIzyanta", "aDyEzyanta"]); } #[ignore] #[test] fn sutra_2_4_51() { let i = d("i\\N", Adadi); - let i_nic_san = i.clone().with_sanadi(&[Sanadi::Nic, Sanadi::San]); - assert_has_lat(&["aDi"], &i_nic_san, &["aDijigApayizati", "aDyApipayizati"]); + let i_nic_san = i.clone().with_sanadi(&[Sanadi::Ric, Sanadi::san]); + assert_has_tip( + &["aDi"], + &i_nic_san, + Lat, + &["aDijigApayizati", "aDyApipayizati"], + ); assert_has_lun(&["aDi"], &nic(&i), &["aDyajIgapat", "aDyApipat"]); } @@ -243,7 +214,7 @@ fn sutra_2_4_54() { #[test] fn sutra_2_4_55() { let cakz = d("ca\\kzi~\\N", Adadi); - assert_has_tinanta( + assert_has_tinantas( &["AN"], &cakz, Lit, @@ -251,7 +222,7 @@ fn sutra_2_4_55() { Eka, &["AcaKyO", "AcaKye", "Acacakze"], ); - assert_has_tinanta( + assert_has_tinantas( &["AN"], &cakz, Lit, @@ -259,7 +230,7 @@ fn sutra_2_4_55() { Dvi, &["AcaKyatuH", "AcaKyAte", "AcacakzAte"], ); - assert_has_tinanta( + assert_has_tinantas( &["AN"], &cakz, Lit, @@ -389,11 +360,11 @@ fn sutra_2_4_85() { assert_has_jhi(&[], &kf, Lut, &["kartAraH"]); let i = d("i\\N", Adadi); - assert_has_tinanta(&["aDi"], &i, Lut, Prathama, Eka, &["aDyetA"]); - assert_has_tinanta(&["aDi"], &i, Lut, Prathama, Dvi, &["aDyetArO"]); - assert_has_tinanta(&["aDi"], &i, Lut, Prathama, Bahu, &["aDyetAraH"]); + assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Eka, &["aDyetA"]); + assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Dvi, &["aDyetArO"]); + assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Bahu, &["aDyetAraH"]); // praTamasya assert_has_sip(&[], &kf, Lut, &["kartAsi"]); - assert_has_tinanta(&["aDi"], &i, Lut, Madhyama, Eka, &["aDyetAse"]); + assert_has_tinantas(&["aDi"], &i, Lut, Madhyama, Eka, &["aDyetAse"]); } diff --git a/vidyut-prakriya/tests/kashika_3_1.rs b/vidyut-prakriya/tests/kashika_3_1.rs index 1996462..5da9fe5 100644 --- a/vidyut-prakriya/tests/kashika_3_1.rs +++ b/vidyut-prakriya/tests/kashika_3_1.rs @@ -1,10 +1,26 @@ extern crate test_utils; +use lazy_static::lazy_static; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; +use vidyut_prakriya::args::Linga::*; +use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha as TA; use vidyut_prakriya::args::*; +lazy_static! { + static ref S: Tester = Tester::with_svara_rules(); +} + +fn sanadi(p: Pratipadika, s: Sanadi) -> Dhatu { + Dhatu::nama(p, Some(s)) +} + +fn p(text: &str) -> Pratipadika { + Pratipadika::Basic(text.to_string(), false) +} + #[test] fn sutra_3_1_1() { let kf = d("qukf\\Y", Tanadi); @@ -16,7 +32,25 @@ fn sutra_3_1_1() { fn sutra_3_1_2() { let kf = d("qukf\\Y", Tanadi); assert_has_krdanta(&[], &kf, Krt::tavyat, &["kartavya"]); - // TODO: tEtttirIya + assert_has_artha_taddhita("tittiri", TA::TenaProktam, T::CaR, &["tEttirIya"]); +} + +#[test] +fn sutra_3_1_3() { + let kf = d("qukf\\Y", Tanadi); + S.assert_has_krt(&[], &kf, Krt::tavyat, &["kartavya^"]); + S.assert_has_artha_taddhita("tittiri", TA::TenaProktam, T::CaR, &["tEttirI/ya"]); +} + +#[test] +fn sutra_3_1_4() { + // sup + S.assert_has_sup_1d("dfzad", Pum, &["dfza/dO"]); + S.assert_has_sup_1p("dfzad", Pum, &["dfza/daH"]); + + // pit + S.assert_has_tip(&[], &d("qupa\\ca~^z", Bhvadi), Lat, &["pa/cati"]); + S.assert_has_tip(&[], &d("paWa~", Bhvadi), Lat, &["pa/Wati"]); } #[test] @@ -55,6 +89,177 @@ fn sutra_3_1_7() { assert_has_tip(&[], &san_d("mf\\N", Tudadi), Lat, &["mumUrzati"]); } +#[test] +fn sutra_3_1_8() { + let putriya = Dhatu::nama(p("putra"), Some(Sanadi::kyac)); + assert_has_tip(&[], &putriya, Lat, &["putrIyati"]); +} + +#[test] +fn sutra_3_1_9() { + let kamyac = |prati| Dhatu::nama(prati, Some(Sanadi::kAmyac)); + assert_has_tip(&[], &kamyac(p("putra")), Lat, &["putrakAmyati"]); + assert_has_tip(&[], &kamyac(p("yaSas")), Lat, &["yaSaskAmyati"]); + + assert_has_tip(&[], &kamyac(p("sarpis")), Lat, &["sarpizkAmyati"]); + assert_has_tip(&[], &kamyac(p("kim")), Lat, &["kiNkAmyati"]); + assert_has_tip(&[], &kamyac(p("svar")), Lat, &["svaHkAmyati"]); +} + +#[test] +fn sutra_3_1_10() { + let kyac = |prati| sanadi(prati, Sanadi::kyac); + assert_has_tip(&[], &kyac(p("putra")), Lat, &["putrIyati"]); + assert_has_tip(&[], &kyac(p("prAvAra")), Lat, &["prAvArIyati"]); +} + +#[test] +fn sutra_3_1_10_v1() { + let kyac = |prati| sanadi(prati, Sanadi::kyac); + assert_has_tip(&[], &kyac(p("prAsAda")), Lat, &["prAsAdIyati"]); + assert_has_tip(&[], &kyac(p("paryaNka")), Lat, &["paryaNkIyati"]); +} + +#[ignore] +#[test] +fn sutra_3_1_11() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("Syena")), Lat, &["SyenAyate"]); + assert_has_ta(&[], &kyan(p("puzkara")), Lat, &["puzkarAyate"]); + assert_has_ta(&[], &kyan(p("ojas")), Lat, &["ojAyate"]); + // TODO: ojAyamAna + assert_has_ta(&[], &kyan(p("apsaras")), Lat, &["apsarAyate"]); + assert_has_ta(&[], &kyan(p("payas")), Lat, &["payAyate", "payasyate"]); + + assert_has_ta(&[], &kyan(p("sArasa")), Lat, &["sArasAyate"]); + assert_has_ta(&[], &kyan(p("haMsa")), Lat, &["haMsAyate"]); +} + +#[test] +fn sutra_3_1_12() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("BfSa")), Lat, &["BfSAyate"]); + assert_has_ta(&[], &kyan(p("SIGra")), Lat, &["SIGrAyate"]); +} + +#[ignore] +#[test] +fn sutra_3_1_13() { + let kyas = |prati| Dhatu::nama(prati, None); + assert_has_lat(&[], &kyas(p("lohita")), &["lohitAyati", "lohitAyate"]); +} + +#[test] +fn sutra_3_1_14() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("kazwa")), Lat, &["kazwAyate"]); +} + +#[test] +fn sutra_3_1_14_v1() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("satra")), Lat, &["satrAyate"]); + assert_has_ta(&[], &kyan(p("kazwa")), Lat, &["kazwAyate"]); + assert_has_ta(&[], &kyan(p("kakza")), Lat, &["kakzAyate"]); + assert_has_ta(&[], &kyan(p("kfcCra")), Lat, &["kfcCrAyate"]); + assert_has_ta(&[], &kyan(p("gahana")), Lat, &["gahanAyate"]); +} + +#[test] +fn sutra_3_1_15() { + let nama = |prati| Dhatu::nama(prati, None); + assert_has_ta(&[], &nama(p("romanTa")), Lat, &["romanTAyate"]); + assert_has_tip(&[], &nama(p("tapas")), Lat, &["tapasyati"]); +} + +#[test] +fn sutra_3_1_16() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("bAzpa")), Lat, &["bAzpAyate"]); + assert_has_ta(&[], &kyan(p("uzma")), Lat, &["uzmAyate"]); +} + +#[test] +fn sutra_3_1_16_v1() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("Pena")), Lat, &["PenAyate"]); +} + +#[test] +fn sutra_3_1_17() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("Sabda")), Lat, &["SabdAyate"]); + assert_has_ta(&[], &kyan(p("vEra")), Lat, &["vErAyate"]); + assert_has_ta(&[], &kyan(p("kalaha")), Lat, &["kalahAyate"]); + assert_has_ta(&[], &kyan(p("aBra")), Lat, &["aBrAyate"]); + assert_has_ta(&[], &kyan(p("kaRva")), Lat, &["kaRvAyate"]); + assert_has_ta(&[], &kyan(p("meGa")), Lat, &["meGAyate"]); +} + +#[test] +fn sutra_3_1_17_v1() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("sudina")), Lat, &["sudinAyate"]); + assert_has_ta(&[], &kyan(p("durdina")), Lat, &["durdinAyate"]); + assert_has_ta(&[], &kyan(p("nIhAra")), Lat, &["nIhArAyate"]); +} + +#[test] +fn sutra_3_1_17_v2() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("awA")), Lat, &["awAyate"]); + assert_has_ta(&[], &kyan(p("awwA")), Lat, &["awwAyate"]); + assert_has_ta(&[], &kyan(p("SIkA")), Lat, &["SIkAyate"]); + assert_has_ta(&[], &kyan(p("kowA")), Lat, &["kowAyate"]); + assert_has_ta(&[], &kyan(p("powA")), Lat, &["powAyate"]); + assert_has_ta(&[], &kyan(p("sowA")), Lat, &["sowAyate"]); + assert_has_ta(&[], &kyan(p("pruzwA")), Lat, &["pruzwAyate"]); + assert_has_ta(&[], &kyan(p("pluzwA")), Lat, &["pluzwAyate"]); +} + +#[test] +fn sutra_3_1_18() { + let kyan = |prati| sanadi(prati, Sanadi::kyaN); + assert_has_ta(&[], &kyan(p("suKa")), Lat, &["suKAyate"]); + assert_has_ta(&[], &kyan(p("duHKa")), Lat, &["duHKAyate"]); +} + +#[test] +fn sutra_3_1_19() { + let nama = |prati| Dhatu::nama(p(prati), None); + assert_has_tip(&[], &nama("namas"), Lat, &["namasyati"]); + assert_has_tip(&[], &nama("varivas"), Lat, &["varivasyati"]); + assert_has_ta(&[], &nama("citra"), Lat, &["citrIyate"]); +} + +#[ignore] +#[test] +fn sutra_3_1_20() { + let nama = |prati| Dhatu::nama(p(prati), None); + assert_has_ta(&["ud"], &nama("pucCa"), Lat, &["utpucCayate"]); + assert_has_ta(&["pari"], &nama("pucCa"), Lat, &["paripucCayate"]); + assert_has_ta(&["sam"], &nama("BARqa"), Lat, &["samBARqayate"]); + assert_has_ta(&["sam"], &nama("cIvara"), Lat, &["saYcIvarayAte"]); +} + +#[ignore] +#[test] +fn sutra_3_1_21() { + let nama = |prati| Dhatu::nama(p(prati), None); + assert_has_tip(&[], &nama("muRqa"), Lat, &["muRqayati"]); + assert_has_tip(&[], &nama("miSra"), Lat, &["miSrayati"]); + assert_has_tip(&[], &nama("SlakzRa"), Lat, &["SlakzRayati"]); + assert_has_tip(&[], &nama("lavaRa"), Lat, &["lavaRayati"]); + assert_has_tip(&[], &nama("vrata"), Lat, &["vratayati"]); + assert_has_tip(&["sam"], &nama("vastra"), Lat, &["saMvastrayati"]); + assert_has_tip(&[], &nama("hali"), Lat, &["halayati"]); + assert_has_tip(&[], &nama("kali"), Lat, &["kalayati"]); + assert_has_tip(&[], &nama("hali"), Lun, &["ajahalat"]); + assert_has_tip(&[], &nama("kali"), Lun, &["acakalat"]); + assert_has_tip(&[], &nama("kft"), Lat, &["kftayati"]); + assert_has_tip(&["vi"], &nama("tUsta"), Lat, &["tUstayati"]); +} + #[test] fn sutra_3_1_22() { assert_has_lat(&[], &yan(&d("qupa\\ca~^z", Bhvadi)), &["pApacyate"]); @@ -92,15 +297,38 @@ fn sutra_3_1_24() { assert_has_lat(&["ni"], &yan(&d("gF", Tudadi)), &["nijegilyate"]); } +#[ignore] #[test] fn sutra_3_1_25() { + let nama = |prati| Dhatu::nama(p(prati), None); + assert_has_tip(&[], &nama("satya"), Lat, &["satyApayati"]); + assert_has_tip(&["vi"], &nama("pASa"), Lat, &["vipASayati"]); + assert_has_tip(&[], &nama("rUpa"), Lat, &["rUpayati"]); + assert_has_tip(&["upa"], &nama("vIRA"), Lat, &["upavIRayati"]); + assert_has_tip(&["anu"], &nama("tUla"), Lat, &["anutUlayati"]); + assert_has_tip(&["upa"], &nama("Sloka"), Lat, &["upaSlokayati"]); + assert_has_tip(&["aBi"], &nama("senA"), Lat, &["aBizeRayati"]); + assert_has_tip(&["anu"], &nama("loman"), Lat, &["anulomayati"]); + assert_has_tip(&[], &nama("tvaca"), Lat, &["tvacayati"]); + assert_has_tip(&["sam"], &nama("varman"), Lat, &["saMvarmayati"]); + assert_has_tip(&[], &nama("varRa"), Lat, &["varRayati"]); + assert_has_tip(&["ava"], &nama("cUrRa"), Lat, &["avacUrRayati"]); + assert_has_tip(&[], &d("cura~", Curadi), Lat, &["corayati"]); assert_has_tip(&[], &d("citi~", Curadi), Lat, &["cintayati"]); } +#[test] +fn sutra_3_1_25_v1() { + let nama = |prati| Dhatu::nama(p(prati), None); + assert_has_tip(&[], &nama("satya"), Lat, &["satyApayati"]); + assert_has_tip(&[], &nama("arTa"), Lat, &["arTApayati"]); + assert_has_tip(&[], &nama("veda"), Lat, &["vedApayati"]); +} + #[test] fn sutra_3_1_26() { - let san = |u, gana| d(u, gana).with_sanadi(&[Sanadi::Nic]); + let san = |u, gana| d(u, gana).with_sanadi(&[Sanadi::Ric]); assert_has_tip(&[], &san("qukf\\Y", Tanadi), Lat, &["kArayati"]); assert_has_tip(&[], &san("qupa\\ca~^z", Bhvadi), Lat, &["pAcayati"]); @@ -138,6 +366,13 @@ fn sutra_3_1_31() { assert_has_tfc("kamu~\\", Bhvadi, &["kamitf", "kAmayitf"]); } +#[test] +fn sutra_3_1_32() { + use Sanadi::*; + assert_has_tip(&[], &sanadi(p("putra"), kyac), Lat, &["putrIyati"]); + assert_has_tip(&[], &sanadi(p("putra"), kAmyac), Lat, &["putrakAmyati"]); +} + #[test] fn sutra_3_1_33() { let kf = d("qukf\\Y", Tanadi); diff --git a/vidyut-prakriya/tests/kashika_3_2.rs b/vidyut-prakriya/tests/kashika_3_2.rs index 60178ae..593f4f5 100644 --- a/vidyut-prakriya/tests/kashika_3_2.rs +++ b/vidyut-prakriya/tests/kashika_3_2.rs @@ -5,6 +5,19 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::*; +use vidyut_prakriya::Ashtadhyayi; + +fn assert_has_lrt_sat(dhatu: &Dhatu, krt: BaseKrt, expected: &[&str]) { + let a = Ashtadhyayi::new(); + let args = Krdanta::builder() + .lakara(Lrt) + .dhatu(dhatu.clone()) + .krt(krt) + .build() + .unwrap(); + let prakriyas = a.derive_krdantas(&args); + assert_padas(prakriyas, expected) +} #[test] fn sutra_3_2_1() { @@ -625,9 +638,9 @@ fn sutra_3_2_59() { assert_has_krdanta(&["ud"], &d("zRi\\ha~", Divadi), kvin, &["uzRih"]); let anc = d("ancu~", Bhvadi); - assert_has_upapada_krdanta("pra", &[], &anc, Krt::kvin, &["prAYc"]); - assert_has_upapada_krdanta("prati", &[], &anc, Krt::kvin, &["pratyaYc"]); - assert_has_upapada_krdanta("ud", &[], &anc, Krt::kvin, &["udaYc"]); + assert_has_upapada_krdanta("pra", &[], &anc, Krt::kvin, &["prAc"]); + assert_has_upapada_krdanta("prati", &[], &anc, Krt::kvin, &["pratyac"]); + assert_has_upapada_krdanta("ud", &[], &anc, Krt::kvin, &["udac"]); assert_has_krdanta(&[], &d("yu\\ji~^r", Rudhadi), Krt::kvin, &["yuj"]); assert_has_krdanta(&[], &d("krunca~", Bhvadi), Krt::kvin, &["kruYc"]); } @@ -704,7 +717,16 @@ fn sutra_3_2_62() { assert_has_krdanta(&["pra"], &d("Ba\\ja~^", Bhvadi), Krt::Rvi, &["praBAj"]); } -// 3.2.63 - 3.2.67 are chAndasa. +// 3.2.63 is chAndasa. + +#[test] +fn sutra_3_2_64() { + let vah = d("va\\ha~^", Bhvadi); + assert_has_upapada_krdanta("prazWa", &[], &vah, Krt::Rvi, &["prazWavAh"]); + assert_has_upapada_krdanta("ditya", &[], &vah, Krt::Rvi, &["dityavAh"]); +} + +// 3.2.65 - 3.2.67 are chAndasa. #[test] fn sutra_3_2_68() { @@ -1044,6 +1066,15 @@ fn sutra_3_2_124() { // TODO: more } +#[test] +fn sutra_3_2_127() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&[], &kr, Krt::Satf, &["kurvat"]); + assert_has_krdanta(&[], &kr, Krt::SAnac, &["kurvARa"]); + assert_has_lrt_sat(&kr, Krt::Satf, &["karizyat"]); + assert_has_lrt_sat(&kr, Krt::SAnac, &["karizyamARa"]); +} + #[test] fn sutra_3_2_128() { assert_has_krdanta(&[], &d("pUN", Bhvadi), Krt::SAnan, &["pavamAna"]); @@ -1052,12 +1083,24 @@ fn sutra_3_2_128() { #[test] fn sutra_3_2_131() { - let dvishat = create_krdanta("dvizat", &[], &d("dvi\\za~^", Adadi), Krt::Satf); + let dvishat = krdanta(&[], &d("dvi\\za~^", Adadi), Krt::Satf); assert_has_sup_1s(&dvishat, Pum, &["dvizan"]); assert_has_sup_1d(&dvishat, Pum, &["dvizantO"]); assert_has_sup_1p(&dvishat, Pum, &["dvizantaH"]); } +#[test] +fn sutra_3_2_132() { + let su = d("zu\\Y", Svadi); + assert_has_krdanta(&[], &su, Krt::Satf, &["sunvat"]); +} + +#[test] +fn sutra_3_2_133() { + let arh = d("arha~", Bhvadi); + assert_has_krdanta(&[], &arh, Krt::Satf, &["arhat"]); +} + #[test] fn sutra_3_2_135() { assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::tfn, &["kartf"]); @@ -1199,6 +1242,35 @@ fn sutra_3_2_167() { assert_has_krdanta(&[], &d("dIpI~\\", Divadi), Krt::ra, &["dIpra"]); } +#[ignore] +#[test] +fn sutra_3_2_168() { + assert_has_krdanta(&[], &san(&d("qukf\\Y", Tanadi)), Krt::u, &["cikIrzu"]); + assert_has_krdanta(&[], &san(&d("hf\\Y", Bhvadi)), Krt::u, &["jihIrzu"]); + assert_has_krdanta(&["AN"], &d("Sasi~\\", Bhvadi), Krt::u, &["ASaMsu"]); + assert_has_krdanta(&[], &d("Bikza~\\", Bhvadi), Krt::u, &["Bikzu"]); +} + +#[ignore] +#[test] +fn sutra_3_2_173() { + assert_has_krdanta(&[], &d("SF", Kryadi), Krt::Aru, &["SarAru"]); + assert_has_krdanta(&[], &d("vadi~\\", Bhvadi), Krt::Aru, &["vandAru"]); +} + +#[test] +fn sutra_3_2_174() { + let bhi = d("YiBI\\", Juhotyadi); + assert_has_krdanta(&[], &bhi, Krt::kru, &["BIru"]); + assert_has_krdanta(&[], &bhi, Krt::klukan, &["BIluka"]); +} + +#[test] +fn sutra_3_2_174_v1() { + let bhi = d("YiBI\\", Juhotyadi); + assert_has_krdanta(&[], &bhi, Krt::kruka, &["BIruka"]); +} + #[ignore] #[test] fn sutra_3_2_175() { diff --git a/vidyut-prakriya/tests/kashika_3_3.rs b/vidyut-prakriya/tests/kashika_3_3.rs index 8d710dc..dd40580 100644 --- a/vidyut-prakriya/tests/kashika_3_3.rs +++ b/vidyut-prakriya/tests/kashika_3_3.rs @@ -6,7 +6,6 @@ use vidyut_prakriya::args::KrtArtha::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::*; -use vidyut_prakriya::Ashtadhyayi; fn assert_has_bhave_krdanta(upapadas: &[&str], dhatu: &Dhatu, krt: BaseKrt, expected: &[&str]) { assert_has_artha_krdanta(upapadas, dhatu, KrtArtha::Bhava, krt, expected); @@ -71,10 +70,13 @@ fn sutra_3_3_14() { let kr = d("qukf\\Y", Tanadi); let create_lrt_sat = |text, dhatu: &Dhatu, krt: BaseKrt| { - let a = Ashtadhyayi::new(); - let args = KrdantaArgs::builder().lakara(Lrt).krt(krt).build().unwrap(); - let prakriyas = a.derive_krdantas(&dhatu, &args); - create_pratipadika(text, &prakriyas) + Krdanta::builder() + .lakara(Lrt) + .dhatu(dhatu.clone()) + .krt(krt) + .require(text) + .build() + .unwrap() }; let karishyat = create_lrt_sat("karizyat", &kr, Krt::Satf); @@ -660,6 +662,58 @@ fn sutra_3_3_120() { assert_has_krdanta(&["ava"], &d("stFY", Kryadi), Krt::GaY, &["avastAra"]); } +#[test] +fn sutra_3_3_121() { + use Krt::GaY; + assert_has_krdanta(&[], &d("liKa~", Tudadi), GaY, &["leKa"]); + assert_has_krdanta(&[], &d("vida~", Adadi), GaY, &["veda"]); + assert_has_krdanta(&[], &d("vezwa~\\", Bhvadi), GaY, &["vezwa"]); + assert_has_krdanta(&[], &d("ba\\nDa~", Kryadi), GaY, &["banDa"]); + assert_has_krdanta(&[], &d("mfjU~", Adadi), GaY, &["mArga"]); + assert_has_krdanta(&["apa", "AN"], &d("mfjU~", Adadi), GaY, &["apAmArga"]); + assert_has_krdanta(&[], &d("ra\\ma~\\", Bhvadi), GaY, &["rAma"]); +} + +#[test] +fn sutra_3_3_125() { + let khan = d("Kanu~^", Bhvadi); + assert_has_krdanta(&["AN"], &khan, Krt::Ga, &["AKana"]); + assert_has_krdanta(&["AN"], &khan, Krt::GaY, &["AKAna"]); +} + +#[test] +fn sutra_3_3_125_v1() { + let khan = d("Kanu~^", Bhvadi); + assert_has_krdanta(&["AN"], &khan, Krt::qa, &["AKa"]); +} + +#[test] +fn sutra_3_3_125_v2() { + let khan = d("Kanu~^", Bhvadi); + assert_has_krdanta(&["AN"], &khan, Krt::qara, &["AKara"]); +} + +#[test] +fn sutra_3_3_125_v3() { + let khan = d("Kanu~^", Bhvadi); + assert_has_krdanta(&["AN"], &khan, Krt::ika, &["AKanika"]); +} + +#[test] +fn sutra_3_3_125_v4() { + let khan = d("Kanu~^", Bhvadi); + assert_has_krdanta(&["AN"], &khan, Krt::ikavaka, &["AKanikavaka"]); +} + +#[ignore] +#[test] +fn sutra_3_3_126() { + let kr = d("qukf\\Y", Tanadi); + assert_has_upapada_krdanta("Izat", &[], &kr, Krt::Kal, &["Izatkara"]); + assert_has_upapada_krdanta("dur", &[], &kr, Krt::Kal, &["duzkara"]); + assert_has_upapada_krdanta("su", &[], &kr, Krt::Kal, &["sukara"]); +} + #[test] fn sutra_3_3_137() { let jiv = d("jIva~", Bhvadi); @@ -667,3 +721,49 @@ fn sutra_3_3_137() { assert_has_tip(&[], &jiv, Lot, &["jIvatu", "jIvatAt"]); assert_has_tip(&[], &jiv, Lat, &["jIvati"]); } + +#[test] +fn sutra_3_3_139() { + assert_has_tip(&["AN"], &d("yA\\", Bhvadi), Lrn, &["AyAsyat"]); + assert_has_tip(&["pari", "AN"], &d("BU", Bhvadi), Lrn, &["paryABavizyat"]); + assert_has_tip(&["AN"], &d("hve\\Y", Bhvadi), Lrn, &["AhvAsyat"]); + assert_has_ta(&[], &d("Bu\\ja~", Rudhadi), Lrn, &["aBokzyata"]); + assert_has_tip(&["AN"], &d("ga\\mx~", Bhvadi), Lrn, &["Agamizyat"]); +} + +#[test] +fn sutra_3_3_161() { + assert_has_tip(&[], &d("qukf\\Y", Tanadi), VidhiLin, &["kuryAt"]); + assert_has_tip(&["AN"], &d("ga\\mx~", Bhvadi), VidhiLin, &["AgacCet"]); + assert_has_ta(&[], &d("Bu\\ja~", Rudhadi), VidhiLin, &["BuYjIta"]); + assert_has_ta(&[], &d("Asa~\\", Adadi), VidhiLin, &["AsIta"]); + assert_has_tip(&["upa"], &d("RI\\Y", Bhvadi), VidhiLin, &["upanayet"]); + assert_has_iw(&["aDi"], &d("i\\N", Adadi), VidhiLin, &["aDIyIya"]); +} + +#[test] +fn sutra_3_3_162() { + assert_has_tip( + &["AN"], + &d("ga\\mx~", Bhvadi), + Lot, + &["AgacCatu", "AgacCatAt"], + ); + assert_has_ta(&[], &d("Asa~\\", Adadi), Lot, &["AstAm"]); + assert_has_ta(&[], &d("Bu\\ja~", Rudhadi), Lot, &["BuNktAm"]); + + let i = d("i\\N", Adadi); + assert_has_tip(&["aDi"], &nic(&i), Lot, &["aDyApayatu", "aDyApayatAt"]); + assert_has_ta(&["upa"], &d("RI\\Y", Bhvadi), Lot, &["upanayatAm"]); + assert_has_iw(&["aDi"], &i, Lot, &["aDyayE"]); +} + +#[test] +fn sutra_3_3_173() { + let jiv = d("jIva~", Bhvadi); + assert_has_ashirlin(&[], &jiv, &["jIvyAt"]); + assert_has_lot(&[], &jiv, &["jIvatu", "jIvatAt"]); + + // ASizi? + assert_has_lat(&[], &jiv, &["jIvati"]); +} diff --git a/vidyut-prakriya/tests/kashika_3_4.rs b/vidyut-prakriya/tests/kashika_3_4.rs index d227624..11e8e5c 100644 --- a/vidyut-prakriya/tests/kashika_3_4.rs +++ b/vidyut-prakriya/tests/kashika_3_4.rs @@ -27,6 +27,16 @@ fn sutra_3_4_21() { assert_has_krdanta(&[], &d("zRA\\", Adadi), Krt::ktvA, &["snAtvA"]); } +#[test] +fn sutra_3_4_22() { + let bhuj = d("Bu\\ja~", Rudhadi); + let paa = d("pA\\", Bhvadi); + assert_has_krdanta(&[], &bhuj, Krt::Ramul, &["Bojam"]); + assert_has_krdanta(&[], &bhuj, Krt::ktvA, &["BuktvA"]); + assert_has_krdanta(&[], &paa, Krt::Ramul, &["pAyam"]); + assert_has_krdanta(&[], &paa, Krt::ktvA, &["pItvA"]); +} + #[test] fn sutra_3_4_67() { let kf = d("qukf\\Y", Tanadi); @@ -421,8 +431,8 @@ fn sutra_3_4_114() { assert_has_krdanta(&[], &lu, Krt::tavya, &["lavitavya"]); // DAtoH - assert_has_taddhitanta(&prati("vfkza"), T::tva, &["vfkzatva"]); - assert_has_taddhitanta(&prati("vfkza"), T::tal, &["vfkzatA"]); + assert_has_taddhita("vfkza", T::tva, &["vfkzatva"]); + assert_has_taddhita("vfkza", T::tal, &["vfkzatA"]); assert_has_sup_3d("lU", Pum, &["lUByAm"]); assert_has_sup_3p("lU", Pum, &["lUBiH"]); assert_has_lat(&[], &d("gupa~\\", Bhvadi), &["jugupsate"]); diff --git a/vidyut-prakriya/tests/kashika_4_1.rs b/vidyut-prakriya/tests/kashika_4_1.rs index 12fdfdf..40467e1 100644 --- a/vidyut-prakriya/tests/kashika_4_1.rs +++ b/vidyut-prakriya/tests/kashika_4_1.rs @@ -3,6 +3,7 @@ use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Linga::*; +use vidyut_prakriya::args::Pratipadika; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; @@ -12,8 +13,8 @@ fn assert_has_pum(prati: &str, expected: &[&str]) { assert_has_sup_1s(prati, Pum, expected); } -fn assert_has_stri(prati: impl IntoPratipadika, expected: &[&str]) { - assert_has_sup_1s(prati, Stri, expected); +fn assert_has_stri(prati: impl Into, expected: &[&str]) { + assert_has_sup_1s(prati.into(), Stri, expected); } fn assert_blocked(text: &str, artha: TaddhitaArtha, t: T) { @@ -166,7 +167,7 @@ fn sutra_4_1_2() { assert_has_sup_7d(&karishagandhya, Stri, &["kArIzaganDyayoH"]); assert_has_sup_7p(&karishagandhya, Stri, &["kArIzaganDyAsu"]); - let drshad = Pratipadika::from("dfzad"); + let drshad = Pratipadika::basic("dfzad"); assert_has_sup_1s(&drshad, Pum, &["dfzat"]); assert_has_sup_1d(&drshad, Pum, &["dfzadO"]); assert_has_sup_1p(&drshad, Pum, &["dfzadaH"]); @@ -190,6 +191,9 @@ fn sutra_4_1_2() { assert_has_sup_7p(&drshad, Pum, &["dfzatsu"]); } +#[test] +fn skip_sutra_4_1_3() {} + #[test] fn sutra_4_1_4() { assert_has_stri("aja", &["ajA"]); @@ -243,7 +247,7 @@ fn sutra_4_1_6() { let bhavat = create_krdanta("Bavat", &[], &d("BA\\", Adadi), Unadi::qavatu); assert_has_stri(&bhavat, &["BavatI"]); - let abhibhavat = create_avyaya_tatpurusha("atiBavat", &Pratipadika::from("ati"), &bhavat); + let abhibhavat = create_avyaya_tatpurusha("atiBavat", "ati", &bhavat); assert_has_stri(&abhibhavat, &["atiBavatI"]); let pacat = create_krdanta("pacat", &[], &d("qupa\\ca~^z", Bhvadi), Krt::Satf); @@ -260,26 +264,61 @@ fn sutra_4_1_7() { assert_has_stri("Sarvan", &["SarvarI"]); } -#[ignore] #[test] -fn sutra_4_1_9() { - assert_has_sup_1s("dAman", Stri, &["dAmA"]); - assert_has_sup_1s("dAman", Stri, &["dAmAnO"]); - assert_has_sup_1s("dAman", Stri, &["dAmAnaH"]); - - assert_has_sup_1s("pAman", Stri, &["pAmA"]); - assert_has_sup_1s("pAman", Stri, &["pAmAnO"]); - assert_has_sup_1s("pAman", Stri, &["pAmAnaH"]); +fn sutra_4_1_8_to_sutra_4_1_9() { + let dvipad = create_bahuvrihi("dvipAd", "dvi", "pAda"); + let tripad = create_bahuvrihi("tripAd", "tri", "pAda"); + let catushpad = create_bahuvrihi("catuzpAd", "catur", "pAda"); + assert_has_stri(&dvipad, &["dvipAt", "dvipadI", "dvipadA"]); + assert_has_stri(&tripad, &["tripAt", "tripadI", "tripadA"]); + assert_has_stri(&catushpad, &["catuzpAt", "catuzpadI", "catuzpadA"]); } #[test] fn sutra_4_1_10() { + // zaw + assert_has_sup_1p("paYcan", Stri, &["paYca"]); + assert_has_sup_1p("saptan", Stri, &["sapta"]); + assert_has_sup_1p("navan", Stri, &["nava"]); + assert_has_sup_1p("daSan", Stri, &["daSa"]); + + // svasrAdi assert_has_stri("svasf", &["svasA"]); assert_has_stri("duhitf", &["duhitA"]); assert_has_stri("nanAndf", &["nanAndA"]); assert_has_stri("yAtf", &["yAtA"]); assert_has_stri("mAtf", &["mAtA"]); - // TODO: others + assert_has_sup_1p("tri", Stri, &["tisraH"]); + assert_has_sup_1p("catur", Stri, &["catasraH"]); +} + +#[ignore] +#[test] +fn sutra_4_1_11() { + assert_has_sup_1s("dAman", Stri, &["dAmA"]); + assert_has_sup_1d("dAman", Stri, &["dAmAnO"]); + assert_has_sup_1p("dAman", Stri, &["dAmAnaH"]); + + assert_has_sup_1s("pAman", Stri, &["pAmA"]); + assert_has_sup_1d("pAman", Stri, &["pAmAnO"]); + assert_has_sup_1p("pAman", Stri, &["pAmAnaH"]); + + assert_has_sup_1s("sIman", Stri, &["sImA"]); + assert_has_sup_1d("sIman", Stri, &["sImAnO"]); + assert_has_sup_1p("sIman", Stri, &["sImAnaH"]); + + assert_has_sup_1s("atimahiman", Stri, &["atimahimA"]); + assert_has_sup_1d("atimahiman", Stri, &["atimahimAnO"]); + assert_has_sup_1p("atimahiman", Stri, &["atimahimAnaH"]); +} + +#[ignore] +#[test] +fn sutra_4_1_14() { + let kurucara = create_upapada_krdanta("kurucara", "kuru", &[], &d("cara~", Bhvadi), Krt::wa); + let madracara = create_upapada_krdanta("madracara", "madra", &[], &d("cara~", Bhvadi), Krt::wa); + assert_has_stri(&kurucara, &["kurucarI"]); + assert_has_stri(&madracara, &["madracarI"]); } #[ignore] @@ -347,6 +386,33 @@ fn sutra_4_1_49() { assert_has_stri("mAtula", &["mAtulAnI"]); } +#[test] +fn sutra_4_1_62() { + assert_has_stri("saKi", &["saKI"]); + assert_has_stri("aSiSu", &["aSiSvI"]); +} + +#[test] +fn sutra_4_1_68() { + assert_has_stri("paNgu", &["paNgUH"]); +} + +#[test] +fn sutra_4_1_68_v1() { + assert_has_stri("SvaSura", &["SvaSrUH"]); +} + +#[test] +fn sutra_4_1_71() { + let c = Tester::with_chaandasa(); + c.assert_has_sup_1s("kadru", Stri, &["kadrUH"]); + c.assert_has_sup_1s("kamaRqalu", Stri, &["kamaRqalUH"]); + + // BAzAyAm + assert_has_sup_1s("kadru", Stri, &["kadruH"]); + assert_has_sup_1s("kamaRqalu", Stri, &["kamaRqaluH"]); +} + #[test] fn sutra_4_1_83() { assert_has_artha_taddhita("upagu", TasyaApatyam, T::aR, &["Opagava"]); @@ -509,17 +575,17 @@ fn sutra_4_1_111() { #[test] fn sutra_4_1_112() { - assert_has_taddhitanta(&prati("Siva"), T::aR, &["SEva"]); - assert_has_taddhitanta(&prati("prOzWa"), T::aR, &["prOzWa"]); + assert_has_taddhita("Siva", T::aR, &["SEva"]); + assert_has_taddhita("prOzWa", T::aR, &["prOzWa"]); // apavAda - assert_has_taddhitanta(&prati("Siva"), T::iY, &[]); - assert_has_taddhitanta(&prati("prOzWa"), T::iY, &[]); + assert_has_taddhita("Siva", T::iY, &[]); + assert_has_taddhita("prOzWa", T::iY, &[]); } #[test] fn sutra_4_1_116() { - assert_has_taddhitanta(&prati("kanyA"), T::aR, &["kAnIna"]); + assert_has_taddhita("kanyA", T::aR, &["kAnIna"]); } #[test] @@ -534,8 +600,8 @@ fn sutra_4_1_117() { #[test] fn sutra_4_1_118() { - assert_has_taddhitanta(&nyap("pIlA"), T::aR, &["pEla"]); - assert_has_taddhitanta(&nyap("pIlA"), T::Qak, &["pEleya"]); + assert_has_taddhita(&nyap("pIlA"), T::aR, &["pEla"]); + assert_has_taddhita(&nyap("pIlA"), T::Qak, &["pEleya"]); } #[test] @@ -547,19 +613,19 @@ fn sutra_4_1_119() { #[test] fn sutra_4_1_120() { - assert_has_taddhitanta(&nyap("suparRA"), T::Qak, &["sOparReya"]); - assert_has_taddhitanta(&nyap("vinatA"), T::Qak, &["vEnateya"]); - assert_has_taddhitanta(&nyap("vAqavA"), T::Qak, &["vAqaveya"]); + assert_has_taddhita(&nyap("suparRA"), T::Qak, &["sOparReya"]); + assert_has_taddhita(&nyap("vinatA"), T::Qak, &["vEnateya"]); + assert_has_taddhita(&nyap("vAqavA"), T::Qak, &["vAqaveya"]); } #[test] fn sutra_4_1_121() { - assert_has_taddhitanta(&nyap("dattA"), T::Qak, &["dAtteya"]); - assert_has_taddhitanta(&nyap("gopI"), T::Qak, &["gOpeya"]); + assert_has_taddhita(&nyap("dattA"), T::Qak, &["dAtteya"]); + assert_has_taddhita(&nyap("gopI"), T::Qak, &["gOpeya"]); // dvi-acaH? // TODO: is yamunA nyAbanta? - assert_has_taddhitanta(&prati("yamunA"), T::Qak, &[]); - assert_has_taddhitanta(&prati("yamunA"), T::aR, &["yAmuna"]); + assert_has_taddhita("yamunA", T::Qak, &[]); + assert_has_taddhita("yamunA", T::aR, &["yAmuna"]); } #[test] @@ -608,7 +674,7 @@ fn sutra_4_1_126() { #[ignore] #[test] fn sutra_4_1_127() { - assert_has_taddhitanta(&nyap("kulawA"), T::Qak, &["kOlawineya", "kOlaweya"]); + assert_has_taddhita(&nyap("kulawA"), T::Qak, &["kOlawineya", "kOlaweya"]); // TODO: Qrak } diff --git a/vidyut-prakriya/tests/kashika_4_2.rs b/vidyut-prakriya/tests/kashika_4_2.rs index 093d636..16a31a1 100644 --- a/vidyut-prakriya/tests/kashika_4_2.rs +++ b/vidyut-prakriya/tests/kashika_4_2.rs @@ -217,93 +217,142 @@ fn sutra_4_2_50() { assert_has_artha_taddhita("raTa", TasyaSamuha, T::ya, &["raTyA"]); } +#[test] +fn sutra_4_2_52() { + let artha = TasyaVishayoDeshe; + assert_has_artha_taddhita("Sibi", artha, T::aR, &["SEba"]); + assert_has_artha_taddhita("uzwra", artha, T::aR, &["Ozwra"]); +} + +#[test] +fn sutra_4_2_53() { + let artha = TasyaVishayoDeshe; + assert_has_artha_taddhita("rAjanya", artha, T::vuY, &["rAjanyaka"]); + assert_has_artha_taddhita("devayAna", artha, T::vuY, &["dEvayAnaka"]); + assert_has_artha_taddhita("mAlava", artha, T::vuY, &["mAlavaka"]); + assert_has_artha_taddhita("virAwa", artha, T::vuY, &["vErAwaka"]); + assert_has_artha_taddhita("trigarta", artha, T::vuY, &["trEgartaka"]); + assert_blocked("rAjanya", artha, T::aR); +} + +#[test] +fn sutra_4_2_54() { + let artha = TasyaVishayoDeshe; + assert_has_artha_taddhita("BOriki", artha, T::viDal, &["BOrikiviDa"]); + assert_has_artha_taddhita("vEpeya", artha, T::viDal, &["vEpeyaviDa"]); + assert_blocked("BOriki", artha, T::aR); + assert_has_artha_taddhita("EzukAri", artha, T::Baktal, &["EzukAriBakta"]); + assert_has_artha_taddhita("sArasyAyana", artha, T::Baktal, &["sArasyAyanaBakta"]); + assert_blocked("BOriki", artha, T::aR); + assert_blocked("EzukAri", artha, T::aR); +} + +#[test] +fn sutra_4_2_59() { + let artha = TadAdhiteTadVeda; + assert_has_artha_taddhita("Candas", artha, T::aR, &["CAndasa"]); + assert_has_artha_taddhita("vyAkaraRa", artha, T::aR, &["vEyAkaraRa"]); + assert_has_artha_taddhita("nirukta", artha, T::aR, &["nErukta"]); + assert_has_artha_taddhita("nimitta", artha, T::aR, &["nEmitta"]); + assert_has_artha_taddhita("muhUrta", artha, T::aR, &["mOhUrta"]); + assert_has_artha_taddhita("utpAta", artha, T::aR, &["OtpAta"]); +} + +#[test] +fn sutra_4_2_61() { + let artha = TadAdhiteTadVeda; + assert_has_artha_taddhita("krama", artha, T::vun, &["kramaka"]); + assert_has_artha_taddhita("pada", artha, T::vun, &["padaka"]); + assert_blocked("krama", artha, T::aR) +} + #[test] fn sutra_4_2_67() { - assert_has_taddhitanta("udumbara", T::aR, &["Odumbara"]); - assert_has_taddhitanta("balbaja", T::aR, &["bAlbaja"]); - assert_has_taddhitanta("parvata", T::aR, &["pArvata"]); + assert_has_taddhita("udumbara", T::aR, &["Odumbara"]); + assert_has_taddhita("balbaja", T::aR, &["bAlbaja"]); + assert_has_taddhita("parvata", T::aR, &["pArvata"]); } #[test] fn sutra_4_2_68() { - assert_has_taddhitanta("kuSAmba", T::aR, &["kOSAmba"]); - assert_has_taddhitanta("sahasra", T::aR, &["sAhasra"]); + assert_has_taddhita("kuSAmba", T::aR, &["kOSAmba"]); + assert_has_taddhita("sahasra", T::aR, &["sAhasra"]); } #[test] fn sutra_4_2_69() { - assert_has_taddhitanta("fjunO", T::aR, &["ArjunAva"]); - assert_has_taddhitanta("Siba", T::aR, &["SEba"]); + assert_has_taddhita("fjunO", T::aR, &["ArjunAva"]); + assert_has_taddhita("Siba", T::aR, &["SEba"]); } #[test] fn sutra_4_2_70() { - assert_has_taddhitanta("vidiSA", T::aR, &["vEdiSa"]); - assert_has_taddhitanta("himavat", T::aR, &["hEmavata"]); + assert_has_taddhita("vidiSA", T::aR, &["vEdiSa"]); + assert_has_taddhita("himavat", T::aR, &["hEmavata"]); } #[test] fn sutra_4_2_71() { - assert_has_taddhitanta("araqu", T::aY, &["Araqava"]); - assert_has_taddhitanta("kakzatu", T::aY, &["kAkzatava"]); - assert_has_taddhitanta("karkawelu", T::aY, &["kArkawelava"]); + assert_has_taddhita("araqu", T::aY, &["Araqava"]); + assert_has_taddhita("kakzatu", T::aY, &["kAkzatava"]); + assert_has_taddhita("karkawelu", T::aY, &["kArkawelava"]); } #[test] fn sutra_4_2_72() { - assert_has_taddhitanta("izukAvat", T::aY, &["EzukAvata"]); - assert_has_taddhitanta("siDrAkAvat", T::aY, &["sEDrAkAvata"]); + assert_has_taddhita("izukAvat", T::aY, &["EzukAvata"]); + assert_has_taddhita("siDrAkAvat", T::aY, &["sEDrAkAvata"]); // bahu-ac? - assert_has_taddhitanta("ahimat", T::aR, &["Ahimata"]); - assert_has_taddhitanta("yavamat", T::aR, &["yAvamata"]); - assert_has_taddhitanta("mAlAvat", T::aR, &["mAlAvata"]); + assert_has_taddhita("ahimat", T::aR, &["Ahimata"]); + assert_has_taddhita("yavamat", T::aR, &["yAvamata"]); + assert_has_taddhita("mAlAvat", T::aR, &["mAlAvata"]); } #[test] fn sutra_4_2_75() { - assert_has_taddhitanta("saNkala", T::aY, &["sANkala"]); - assert_has_taddhitanta("puzkala", T::aY, &["pOzkala"]); + assert_has_taddhita("saNkala", T::aY, &["sANkala"]); + assert_has_taddhita("puzkala", T::aY, &["pOzkala"]); } #[test] fn sutra_4_2_77() { - assert_has_taddhitanta("suvAstu", T::aR, &["sOvAstava"]); - assert_has_taddhitanta("varRu", T::aR, &["vArRava"]); + assert_has_taddhita("suvAstu", T::aR, &["sOvAstava"]); + assert_has_taddhita("varRu", T::aR, &["vArRava"]); } #[test] fn sutra_4_2_78() { - assert_has_taddhitanta("roRI", T::aR, &["rORa"]); - assert_has_taddhitanta("ajakaroRI", T::aR, &["AjakaroRa"]); - assert_has_taddhitanta("sihikaroRI", T::aR, &["sEhikaroRa"]); + assert_has_taddhita("roRI", T::aR, &["rORa"]); + assert_has_taddhita("ajakaroRI", T::aR, &["AjakaroRa"]); + assert_has_taddhita("sihikaroRI", T::aR, &["sEhikaroRa"]); } #[test] fn sutra_4_2_79() { - assert_has_taddhitanta("karRacCidrika", T::aR, &["kArRacCidrika"]); - assert_has_taddhitanta("karRavezwaka", T::aR, &["kArRavezwaka"]); - assert_has_taddhitanta("triSaNku", T::aR, &["trESaNkava"]); + assert_has_taddhita("karRacCidrika", T::aR, &["kArRacCidrika"]); + assert_has_taddhita("karRavezwaka", T::aR, &["kArRavezwaka"]); + assert_has_taddhita("triSaNku", T::aR, &["trESaNkava"]); } #[test] fn sutra_4_2_84() { - assert_has_taddhitanta("SarkarA", T::Wak, &["SArkarika"]); - assert_has_taddhitanta("SarkarA", T::Ca, &["SarkarIya"]); + assert_has_taddhita("SarkarA", T::Wak, &["SArkarika"]); + assert_has_taddhita("SarkarA", T::Ca, &["SarkarIya"]); } #[test] fn sutra_4_2_86() { - assert_has_taddhitanta("maDu", T::matup, &["maDumat"]); - assert_has_taddhitanta("bisa", T::matup, &["bisavat"]); + assert_has_taddhita("maDu", T::matup, &["maDumat"]); + assert_has_taddhita("bisa", T::matup, &["bisavat"]); } #[ignore] #[test] fn sutra_4_2_87() { - assert_has_taddhitanta("kumuda", T::qmatup, &["kumudvat"]); - assert_has_taddhitanta("naqa", T::qmatup, &["maqvat"]); - assert_has_taddhitanta("vetasa", T::qmatup, &["vetasvat"]); + assert_has_taddhita("kumuda", T::qmatup, &["kumudvat"]); + assert_has_taddhita("naqa", T::qmatup, &["maqvat"]); + assert_has_taddhita("vetasa", T::qmatup, &["vetasvat"]); } // Seze @@ -313,87 +362,87 @@ fn sutra_4_2_87() { #[ignore] #[test] fn sutra_4_2_92() { - assert_has_taddhitanta("rAzwra", T::Ga, &["rAzwriya"]); - assert_has_taddhitanta("avArapAra", T::Ka, &["avArapArIRa"]); + assert_has_taddhita("rAzwra", T::Ga, &["rAzwriya"]); + assert_has_taddhita("avArapAra", T::Ka, &["avArapArIRa"]); - assert_has_taddhitanta("cakzus", T::aR, &["cAkzuza"]); - assert_has_taddhitanta("SravaRa", T::aR, &["SrAvaRa"]); - assert_has_taddhitanta("dfzad", T::aR, &["dArzada"]); - assert_has_taddhitanta("ulUkala", T::aR, &["OlUKala"]); - assert_has_taddhitanta("aSva", T::aR, &["ASva"]); - assert_has_taddhitanta("catur", T::aR, &["cAtura"]); - assert_has_taddhitanta("caturdaSI", T::aR, &["cAturdaSa"]); + assert_has_taddhita("cakzus", T::aR, &["cAkzuza"]); + assert_has_taddhita("SravaRa", T::aR, &["SrAvaRa"]); + assert_has_taddhita("dfzad", T::aR, &["dArzada"]); + assert_has_taddhita("ulUkala", T::aR, &["OlUKala"]); + assert_has_taddhita("aSva", T::aR, &["ASva"]); + assert_has_taddhita("catur", T::aR, &["cAtura"]); + assert_has_taddhita("caturdaSI", T::aR, &["cAturdaSa"]); } #[test] fn sutra_4_2_93() { - assert_has_taddhitanta("rAzwra", T::Ga, &["rAzwriya"]); - assert_has_taddhitanta("avArapAra", T::Ka, &["avArapArIRa"]); + assert_has_taddhita("rAzwra", T::Ga, &["rAzwriya"]); + assert_has_taddhita("avArapAra", T::Ka, &["avArapArIRa"]); } #[test] fn sutra_4_2_93_v1() { - assert_has_taddhitanta("avAra", T::Ka, &["avArIRa"]); - assert_has_taddhitanta("pAra", T::Ka, &["pArIRa"]); - assert_has_taddhitanta("pArAvara", T::Ka, &["pArAvarIRa"]); + assert_has_taddhita("avAra", T::Ka, &["avArIRa"]); + assert_has_taddhita("pAra", T::Ka, &["pArIRa"]); + assert_has_taddhita("pArAvara", T::Ka, &["pArAvarIRa"]); } #[test] fn sutra_4_2_94() { - assert_has_taddhitanta("grAma", T::ya, &["grAmya"]); - assert_has_taddhitanta("grAma", T::KaY, &["grAmIRa"]); + assert_has_taddhita("grAma", T::ya, &["grAmya"]); + assert_has_taddhita("grAma", T::KaY, &["grAmIRa"]); } #[test] fn sutra_4_2_95() { - assert_has_taddhitanta("katri", T::QakaY, &["kAtreyaka"]); - assert_has_taddhitanta("umBi", T::QakaY, &["OmBeyaka"]); + assert_has_taddhita("katri", T::QakaY, &["kAtreyaka"]); + assert_has_taddhita("umBi", T::QakaY, &["OmBeyaka"]); } #[test] fn sutra_4_2_97() { - assert_has_taddhitanta("nadI", T::Qak, &["nAdeya"]); - assert_has_taddhitanta("mahI", T::Qak, &["mAheya"]); + assert_has_taddhita("nadI", T::Qak, &["nAdeya"]); + assert_has_taddhita("mahI", T::Qak, &["mAheya"]); } #[test] fn sutra_4_2_98() { - assert_has_taddhitanta("dakziRA", T::tyak, &["dAkziRAtya"]); - assert_has_taddhitanta("paScAt", T::tyak, &["pAScAttya"]); - assert_has_taddhitanta("puras", T::tyak, &["pOrastya"]); + assert_has_taddhita("dakziRA", T::tyak, &["dAkziRAtya"]); + assert_has_taddhita("paScAt", T::tyak, &["pAScAttya"]); + assert_has_taddhita("puras", T::tyak, &["pOrastya"]); } #[test] fn sutra_4_2_99() { - assert_has_taddhitanta("kApiSI", T::zPak, &["kApiSAyana"]); + assert_has_taddhita("kApiSI", T::zPak, &["kApiSAyana"]); // TODO: stri } #[ignore] #[test] fn sutra_4_2_101() { - assert_has_taddhitanta("dyu", T::yat, &["divya"]); - assert_has_taddhitanta("prAc", T::yat, &["prAcya"]); - assert_has_taddhitanta("apAc", T::yat, &["apAcya"]); - assert_has_taddhitanta("udac", T::yat, &["udIcya"]); - assert_has_taddhitanta("pratyac", T::yat, &["pratIcya"]); + assert_has_taddhita("dyu", T::yat, &["divya"]); + assert_has_taddhita("prAc", T::yat, &["prAcya"]); + assert_has_taddhita("apAc", T::yat, &["apAcya"]); + assert_has_taddhita("udac", T::yat, &["udIcya"]); + assert_has_taddhita("pratyac", T::yat, &["pratIcya"]); } #[test] fn sutra_4_2_102() { - assert_has_taddhitanta("kanTA", T::Wak, &["kAnTika"]); + assert_has_taddhita("kanTA", T::Wak, &["kAnTika"]); } #[test] fn sutra_4_2_103() { - assert_has_taddhitanta("kanTA", T::vuk, &["kAnTaka"]); + assert_has_taddhita("kanTA", T::vuk, &["kAnTaka"]); } #[test] fn sutra_4_2_105() { - assert_has_taddhitanta("Ezamas", T::tyap, &["Ezamastya"]); - assert_has_taddhitanta("hyas", T::tyap, &["hyastya"]); - assert_has_taddhitanta("Svas", T::tyap, &["Svastya"]); + assert_has_taddhita("Ezamas", T::tyap, &["Ezamastya"]); + assert_has_taddhita("hyas", T::tyap, &["hyastya"]); + assert_has_taddhita("Svas", T::tyap, &["Svastya"]); // TODO: others } @@ -408,18 +457,18 @@ fn sutra_4_2_106() { #[ignore] #[test] fn sutra_4_2_114() { - assert_has_taddhitanta("gArgya", T::Ca, &["gArgIya"]); - assert_has_taddhitanta("vAtsa", T::Ca, &["vAtsIya"]); - assert_has_taddhitanta("SAla", T::Ca, &["SAlIya"]); - assert_has_taddhitanta("mAla", T::Ca, &["mAlIya"]); + assert_has_taddhita("gArgya", T::Ca, &["gArgIya"]); + assert_has_taddhita("vAtsa", T::Ca, &["vAtsIya"]); + assert_has_taddhita("SAla", T::Ca, &["SAlIya"]); + assert_has_taddhita("mAla", T::Ca, &["mAlIya"]); } #[ignore] #[test] fn sutra_4_2_115() { - assert_has_taddhitanta("Bavat", T::Wak, &["BAvatka"]); - assert_has_taddhitanta("Bavat", T::Cas, &["BavadIya"]); - assert_has_taddhitanta("Bavat", T::Ca, &[]); + assert_has_taddhita("Bavat", T::Wak, &["BAvatka"]); + assert_has_taddhita("Bavat", T::Cas, &["BavadIya"]); + assert_has_taddhita("Bavat", T::Ca, &[]); } #[test] diff --git a/vidyut-prakriya/tests/kashika_4_4.rs b/vidyut-prakriya/tests/kashika_4_4.rs index 034cf75..cce4a0b 100644 --- a/vidyut-prakriya/tests/kashika_4_4.rs +++ b/vidyut-prakriya/tests/kashika_4_4.rs @@ -233,8 +233,8 @@ fn sutra_4_4_33() { #[test] fn sutra_4_4_34() { - assert_has_taddhitanta(&prati("Sabda"), T::Wak, &["SAbdika"]); - assert_has_taddhitanta(&prati("dardura"), T::Wak, &["dArdurika"]); + assert_has_taddhita("Sabda", T::Wak, &["SAbdika"]); + assert_has_taddhita("dardura", T::Wak, &["dArdurika"]); } #[test] @@ -441,9 +441,9 @@ fn sutra_4_4_62() { #[test] fn sutra_4_4_65() { - assert_has_taddhitanta(&prati("apUpa"), T::Wak, &["ApUpika"]); - assert_has_taddhitanta(&prati("Sazkula"), T::Wak, &["SAzkulika"]); - assert_has_taddhitanta(&prati("modaka"), T::Wak, &["mOdakika"]); + assert_has_taddhita("apUpa", T::Wak, &["ApUpika"]); + assert_has_taddhita("Sazkula", T::Wak, &["SAzkulika"]); + assert_has_taddhita("modaka", T::Wak, &["mOdakika"]); } #[test] @@ -485,10 +485,10 @@ fn sutra_4_4_70() { #[test] fn sutra_4_4_71() { - assert_has_taddhitanta(&prati("SmaSAna"), T::Wak, &["SmASAnika"]); - assert_has_taddhitanta(&prati("catuzpaTa"), T::Wak, &["cAtuzpaTika"]); - assert_has_taddhitanta(&prati("caturdaSa"), T::Wak, &["cAturdaSika"]); - assert_has_taddhitanta(&prati("amAvAsyA"), T::Wak, &["AmAvAsyika"]); + assert_has_taddhita("SmaSAna", T::Wak, &["SmASAnika"]); + assert_has_taddhita("catuzpaTa", T::Wak, &["cAtuzpaTika"]); + assert_has_taddhita("caturdaSa", T::Wak, &["cAturdaSika"]); + assert_has_taddhita("amAvAsyA", T::Wak, &["AmAvAsyika"]); } #[test] @@ -585,13 +585,13 @@ fn sutra_4_4_90() { #[test] fn sutra_4_4_91() { - assert_has_taddhitanta(&prati("nO"), T::yat, &["nAvya"]); - assert_has_taddhitanta(&prati("vayas"), T::yat, &["vayasya"]); - assert_has_taddhitanta(&prati("Darma"), T::yat, &["Darmya"]); - assert_has_taddhitanta(&prati("viza"), T::yat, &["vizya"]); - assert_has_taddhitanta(&prati("mUla"), T::yat, &["mUlya"]); - assert_has_taddhitanta(&prati("sItA"), T::yat, &["sItya"]); - assert_has_taddhitanta(&prati("tulA"), T::yat, &["tulya"]); + assert_has_taddhita("nO", T::yat, &["nAvya"]); + assert_has_taddhita("vayas", T::yat, &["vayasya"]); + assert_has_taddhita("Darma", T::yat, &["Darmya"]); + assert_has_taddhita("viza", T::yat, &["vizya"]); + assert_has_taddhita("mUla", T::yat, &["mUlya"]); + assert_has_taddhita("sItA", T::yat, &["sItya"]); + assert_has_taddhita("tulA", T::yat, &["tulya"]); // TODO: others } @@ -621,9 +621,9 @@ fn sutra_4_4_95() { #[test] fn sutra_4_4_97() { - assert_has_taddhitanta("mata", T::yat, &["matya"]); - assert_has_taddhitanta("jana", T::yat, &["janya"]); - assert_has_taddhitanta("hala", T::yat, &["halya"]); + assert_has_taddhita("mata", T::yat, &["matya"]); + assert_has_taddhita("jana", T::yat, &["janya"]); + assert_has_taddhita("hala", T::yat, &["halya"]); } #[test] diff --git a/vidyut-prakriya/tests/kashika_5_1.rs b/vidyut-prakriya/tests/kashika_5_1.rs index 6ceaec1..55b2afb 100644 --- a/vidyut-prakriya/tests/kashika_5_1.rs +++ b/vidyut-prakriya/tests/kashika_5_1.rs @@ -1,8 +1,11 @@ extern crate test_utils; use test_utils::*; +use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha; use vidyut_prakriya::args::TaddhitaArtha::*; +use vidyut_prakriya::args::Unadi; fn assert_blocked(text: &str, artha: TaddhitaArtha, t: T) { assert_has_artha_taddhita(text, artha, t, &[]); @@ -18,20 +21,31 @@ fn sutra_5_1_1() { #[test] fn sutra_5_1_2() { - assert_has_taddhitanta(&prati("SaNku"), T::yat, &["SaNkavya"]); - assert_has_taddhitanta(&prati("picU"), T::yat, &["picavya"]); - assert_has_taddhitanta(&prati("kamaRqalu"), T::yat, &["kamaRqalavya"]); - assert_has_taddhitanta(&prati("go"), T::yat, &["gavya"]); + assert_has_taddhita("SaNku", T::yat, &["SaNkavya"]); + assert_has_taddhita("picU", T::yat, &["picavya"]); + assert_has_taddhita("kamaRqalu", T::yat, &["kamaRqalavya"]); + assert_has_taddhita("go", T::yat, &["gavya"]); // TODO: others } #[test] fn sutra_5_1_3() { - assert_has_taddhitanta(&prati("kambala"), T::yat, &["kambalya"]); + assert_has_taddhita("kambala", T::yat, &["kambalya"]); assert_has_artha_taddhita("kambala", TasmaiHitam, T::Ca, &["kambalIya"]); } #[ignore] +#[test] +fn sutra_5_1_5() { + assert_has_artha_taddhita("vatsa", TasmaiHitam, T::Ca, &["vatsIya"]); + assert_has_artha_taddhita("avatsa", TasmaiHitam, T::Ca, &["avatsIya"]); + assert_has_artha_taddhita("pawu", TasmaiHitam, T::yat, &["pawavya"]); + assert_has_artha_taddhita("go", TasmaiHitam, T::yat, &["gavya"]); + assert_has_artha_taddhita("havis", TasmaiHitam, T::yat, &["havizya"]); + assert_has_artha_taddhita("apUpa", TasmaiHitam, T::yat, &["apUpya"]); + assert_has_artha_taddhita("apUpa", TasmaiHitam, T::Ca, &["apUpIya"]); +} + #[test] fn sutra_5_1_7() { assert_has_artha_taddhita("Kala", TasmaiHitam, T::yat, &["Kalya"]); @@ -73,39 +87,174 @@ fn sutra_5_1_11() { assert_blocked("mARava", TasmaiHitam, T::Ca) } +#[test] +fn sutra_5_1_12() { + let artha = TadarthamVikrtehPrakrtau; + assert_has_artha_taddhita("aNgAra", artha, T::Ca, &["aNgArIya"]); + assert_has_artha_taddhita("prAkAra", artha, T::Ca, &["prAkArIya"]); + assert_has_artha_taddhita("Sanku", artha, T::yat, &["SaNkavya"]); + assert_has_artha_taddhita("picU", artha, T::yat, &["picavya"]); +} + +#[ignore] +#[test] +fn sutra_5_1_13() { + let artha = TadarthamVikrtehPrakrtau; + let chadis = create_krdanta("Cadis", &[], &d("Cada~", Curadi), Unadi::isi); + assert_has_artha_taddhita(&chadis, artha, T::QaY, &["CAdizeya"]); + assert_has_artha_taddhita("upaDi", artha, T::QaY, &["OpaDeya"]); + assert_has_artha_taddhita("bali", artha, T::QaY, &["bAleya"]); + assert_blocked("Cadis", artha, T::Ca); +} + +#[test] +fn sutra_5_1_14() { + let artha = TadarthamVikrtehPrakrtau; + assert_has_artha_taddhita("fzaBa", artha, T::Yya, &["ArzaBya"]); + assert_has_artha_taddhita("upAnah", artha, T::Yya, &["OpAnahya"]); +} + +#[test] +fn sutra_5_1_15() { + let artha = TadarthamVikrtehPrakrtau; + assert_has_artha_taddhita("varDrI", artha, T::aY, &["vArDra"]); + assert_has_artha_taddhita("varatrA", artha, T::aY, &["vAratra"]); + assert_blocked("varDrI", artha, T::Ca); +} + +#[test] +fn sutra_5_1_17() { + let artha = TadAsyaTadAsminSyat; + assert_has_artha_taddhita("pariKA", artha, T::QaY, &["pAriKeya"]); + assert_blocked("pariKA", artha, T::Ca); +} + +#[test] +fn sutra_5_1_18() { + assert_has_artha_taddhita("pArAyaRa", TadVartayati, T::WaY, &["pArAyaRika"]); + assert_has_artha_taddhita("turAyaRa", TadVartayati, T::WaY, &["tOrAyaRika"]); + assert_has_artha_taddhita("cAndrAyaRa", TadVartayati, T::WaY, &["cAndrAyaRika"]); +} + #[ignore] #[test] fn sutra_5_1_22() { - assert_has_taddhitanta(&prati("paYca"), T::kan, &["paYcaka"]); - assert_has_taddhitanta(&prati("bahu"), T::kan, &["bahuka"]); - assert_has_taddhitanta(&prati("gaRa"), T::kan, &["gaRaka"]); + assert_has_taddhita("paYca", T::kan, &["paYcaka"]); + assert_has_taddhita("bahu", T::kan, &["bahuka"]); + assert_has_taddhita("gaRa", T::kan, &["gaRaka"]); // a-ti-Sat - assert_has_taddhitanta(&prati("saptati"), T::WaY, &["sAptatika"]); - assert_has_taddhitanta(&prati("catvAriMSat"), T::WaY, &["cAtvAriMSatka"]); + assert_has_taddhita("saptati", T::WaY, &["sAptatika"]); + assert_has_taddhita("catvAriMSat", T::WaY, &["cAtvAriMSatka"]); +} + +#[test] +fn sutra_5_1_63() { + assert_has_artha_taddhita("SvetacCatra", TadArhati, T::Wak, &["SvEtacCatrika"]); + assert_has_artha_taddhita("vastrayugma", TadArhati, T::Wak, &["vAstrayugmika"]); + assert_has_artha_taddhita("Sata", TadArhati, T::Wan, &["Satika"]); + assert_has_artha_taddhita("Sata", TadArhati, T::yat, &["Satya"]); + assert_has_artha_taddhita("sahasra", TadArhati, T::aR, &["sAhasra"]); +} + +#[test] +fn sutra_5_1_66() { + assert_has_artha_taddhita("daRqa", TadArhati, T::yat, &["daRqya"]); + assert_has_artha_taddhita("musala", TadArhati, T::yat, &["musalya"]); + assert_blocked("daRqa", TadArhati, T::Wak); +} + +#[test] +fn sutra_5_1_67() { + let t = Tester::with_chaandasa(); + t.assert_has_artha_taddhita("udaka", TadArhati, T::yat, &["udakya"]); + t.assert_has_artha_taddhita("yUpa", TadArhati, T::yat, &["yUpya"]); +} + +#[test] +fn sutra_5_1_68() { + assert_has_artha_taddhita("pAtra", TadArhati, T::Gan, &["pAtriya"]); + assert_has_artha_taddhita("pAtra", TadArhati, T::yat, &["pAtrya"]); + assert_blocked("pAtra", TadArhati, T::Wak); + assert_blocked("pAtra", TadArhati, T::WaY); +} + +#[test] +fn sutra_5_1_69() { + assert_has_artha_taddhita("kaqaNkara", TadArhati, T::Ca, &["kaqaNkarIya"]); + assert_has_artha_taddhita("kaqaNkara", TadArhati, T::yat, &["kaqaNkarya"]); + assert_has_artha_taddhita("dakziRA", TadArhati, T::Ca, &["dakziRIya"]); + assert_has_artha_taddhita("dakziRA", TadArhati, T::yat, &["dakziRya"]); + assert_blocked("kaqaNkara", TadArhati, T::Wak); +} + +#[test] +fn sutra_5_1_70() { + assert_has_artha_taddhita("sTAlIbila", TadArhati, T::Ca, &["sTAlIbilIya"]); + assert_has_artha_taddhita("sTAlIbila", TadArhati, T::yat, &["sTAlIbilya"]); + assert_blocked("sTAlIbila", TadArhati, T::Wak); +} + +#[test] +fn sutra_5_1_71() { + assert_has_artha_taddhita("yajYa", TadArhati, T::Ga, &["yajYiya"]); + assert_has_artha_taddhita("ftvij", TadArhati, T::KaY, &["ArtvijIna"]); + assert_blocked("yajYa", TadArhati, T::Wak); + assert_blocked("ftvij", TadArhati, T::Wak); +} + +#[test] +fn sutra_5_1_72() { + assert_has_artha_taddhita("pArAyaRa", TadVartayati, T::WaY, &["pArAyaRika"]); + assert_has_artha_taddhita("turAyaRa", TadVartayati, T::WaY, &["tOrAyaRika"]); + assert_has_artha_taddhita("cAndrAyaRa", TadVartayati, T::WaY, &["cAndrAyaRika"]); +} + +#[test] +fn sutra_5_1_73() { + assert_has_artha_taddhita("saMSaya", Apanna, T::WaY, &["sAMSayika"]); +} + +#[test] +fn sutra_5_1_74() { + assert_has_artha_taddhita("yojana", Gacchati, T::WaY, &["yOjanika"]); +} + +#[test] +fn sutra_5_1_74_v1() { + let artha = AbhigamanamArhati; + assert_has_artha_taddhita("kroSaSata", artha, T::WaY, &["krOSaSatika"]); + assert_has_artha_taddhita("yojanaSata", artha, T::WaY, &["yOjanaSatika"]); +} + +#[test] +fn sutra_5_1_75() { + let pathika = create_artha_taddhita("paTika", "paTin", Gacchati, T::zkan); + assert_has_sup_1s(&pathika, Pum, &["paTikaH"]); + assert_has_sup_1s(&pathika, Stri, &["paTikI"]); } #[test] fn sutra_5_1_105() { - assert_has_taddhitanta(&prati("ftu"), T::aR, &["Artava"]); + assert_has_taddhita("ftu", T::aR, &["Artava"]); } #[test] fn sutra_5_1_106() { - assert_has_taddhitanta(&prati("ftu"), T::Gas, &["ftviya"]); + assert_has_taddhita("ftu", T::Gas, &["ftviya"]); } #[test] fn sutra_5_1_119() { - assert_has_taddhitanta(&prati("aSva"), T::tva, &["aSvatva"]); - assert_has_taddhitanta(&prati("aSva"), T::tal, &["aSvatA"]); - assert_has_taddhitanta(&prati("go"), T::tva, &["gotva"]); - assert_has_taddhitanta(&prati("go"), T::tal, &["gotA"]); + assert_has_taddhita("aSva", T::tva, &["aSvatva"]); + assert_has_taddhita("aSva", T::tal, &["aSvatA"]); + assert_has_taddhita("go", T::tva, &["gotva"]); + assert_has_taddhita("go", T::tal, &["gotA"]); } #[test] fn sutra_5_1_122() { - assert_has_taddhitanta(&prati("pfTu"), T::imanic, &["praTiman"]); - assert_has_taddhitanta(&prati("pfTu"), T::aR, &["pArTava"]); - assert_has_taddhitanta(&prati("mfdu"), T::imanic, &["mradiman"]); - assert_has_taddhitanta(&prati("mfdu"), T::aR, &["mArdava"]); + assert_has_taddhita("pfTu", T::imanic, &["praTiman"]); + assert_has_taddhita("pfTu", T::aR, &["pArTava"]); + assert_has_taddhita("mfdu", T::imanic, &["mradiman"]); + assert_has_taddhita("mfdu", T::aR, &["mArdava"]); } diff --git a/vidyut-prakriya/tests/kashika_5_2.rs b/vidyut-prakriya/tests/kashika_5_2.rs index b03c42e..f91a18a 100644 --- a/vidyut-prakriya/tests/kashika_5_2.rs +++ b/vidyut-prakriya/tests/kashika_5_2.rs @@ -1,8 +1,14 @@ extern crate test_utils; use test_utils::*; +use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha; use vidyut_prakriya::args::TaddhitaArtha::*; +fn assert_blocked(text: &str, artha: TaddhitaArtha, t: T) { + assert_has_artha_taddhita(text, artha, t, &[]); +} + #[ignore] #[test] fn sutra_5_2_1() { @@ -70,45 +76,377 @@ fn sutra_5_2_8() { #[ignore] #[test] fn sutra_5_2_9() { - assert_has_taddhitanta("anupada", T::Ka, &["anupadIna"]); - assert_has_taddhitanta("sarvAnna", T::Ka, &["sarvAnnIna"]); - assert_has_taddhitanta("AyAnaya", T::Ka, &["AyAnayIna"]); + assert_has_taddhita("anupada", T::Ka, &["anupadIna"]); + assert_has_taddhita("sarvAnna", T::Ka, &["sarvAnnIna"]); + assert_has_taddhita("AyAnaya", T::Ka, &["AyAnayIna"]); +} + +#[test] +fn sutra_5_2_10() { + assert_has_artha_taddhita("parovara", TadAnubhavati, T::Ka, &["parovarIRa"]); + assert_has_artha_taddhita("parampara", TadAnubhavati, T::Ka, &["paramparIRa"]); + assert_has_artha_taddhita("putrapOtra", TadAnubhavati, T::Ka, &["putrapOtrIRa"]); +} + +#[test] +fn sutra_5_2_11() { + assert_has_artha_taddhita("avArapAra", Gami, T::Ka, &["avArapArIRa"]); + assert_has_artha_taddhita("atyanta", Gami, T::Ka, &["atyantIna"]); + assert_has_artha_taddhita("anukAma", Gami, T::Ka, &["anukAmIna"]); +} + +#[test] +fn sutra_5_2_15() { + assert_has_artha_taddhita("anugu", AlamGami, T::Ka, &["anugavIna"]); +} + +#[test] +fn sutra_5_2_16() { + assert_has_artha_taddhita("aDvan", AlamGami, T::yat, &["aDvanya"]); + assert_has_artha_taddhita("aDvan", AlamGami, T::Ka, &["aDvanIna"]); +} + +#[test] +fn sutra_5_2_17() { + assert_has_artha_taddhita("anugu", AlamGami, T::Ka, &["anugavIna"]); +} + +#[test] +fn sutra_5_2_18() { + assert_has_artha_taddhita("gozWa", BhutaPurva, T::KaY, &["gOzWIna"]); +} + +#[test] +fn sutra_5_2_19() { + assert_has_artha_taddhita("aSva", EkahaGama, T::KaY, &["ASvIna"]); +} + +#[test] +fn sutra_5_2_21() { + assert_has_artha_taddhita("vrAta", TenaJivati, T::KaY, &["vrAtIna"]); +} + +#[test] +fn sutra_5_2_24() { + let artha = TasyaPakamula; + assert_has_artha_taddhita("pIlu", artha, T::kuRap, &["pIlukuRa"]); + assert_has_artha_taddhita("karkanDu", artha, T::kuRap, &["karkanDukuRa"]); + assert_has_artha_taddhita("karRa", artha, T::jAhac, &["karRajAha"]); +} + +#[test] +fn sutra_5_2_25() { + assert_has_artha_taddhita("pakza", TasyaMula, T::ti, &["pakzati"]); +} + +#[test] +fn sutra_5_2_26() { + let artha = TenaVitta; + assert_has_artha_taddhita("vidyA", artha, T::cuYcup, &["vidyAcuYcu"]); + assert_has_artha_taddhita("vidyA", artha, T::caRap, &["vidyAcaRa"]); +} + +#[test] +fn sutra_5_2_28() { + assert_has_taddhita("vi", T::SAlac, &["viSAla"]); + assert_has_taddhita("vi", T::SaNkawac, &["viSaNkawa"]); +} + +#[test] +fn sutra_5_2_29() { + assert_has_taddhita("sam", T::kawac, &["saNkawa"]); + assert_has_taddhita("pra", T::kawac, &["prakawa"]); + assert_has_taddhita("ud", T::kawac, &["utkawa"]); + assert_has_taddhita("vi", T::kawac, &["vikawa"]); +} + +#[test] +fn sutra_5_2_29_v1() { + assert_has_taddhita("alAbU", T::kawac, &["alAbUkawa"]); + assert_has_taddhita("tila", T::kawac, &["tilakawa"]); +} + +#[test] +fn sutra_5_2_30() { + assert_has_taddhita("ava", T::kawac, &["avakawa"]); + assert_has_taddhita("ava", T::kuwArac, &["avakuwAra"]); +} + +#[test] +fn sutra_5_2_31() { + assert_has_taddhita("ava", T::wIwac, &["avawIwa"]); + assert_has_taddhita("ava", T::nAwac, &["avanAwa"]); + assert_has_taddhita("ava", T::Brawac, &["avaBrawa"]); +} + +#[ignore] +#[test] +fn sutra_5_2_32() { + assert_has_taddhita("ni", T::biqac, &["nibiqa"]); + assert_has_taddhita("ni", T::birIsac, &["nibirIsa"]); +} + +#[test] +fn sutra_5_2_33() { + assert_has_taddhita("ni", T::inac, &["cikina"]); + assert_has_taddhita("ni", T::piwac, &["cipiwa"]); +} + +#[test] +fn sutra_5_2_34() { + assert_has_taddhita("upa", T::tyakan, &["upatyaka"]); + assert_has_taddhita("aDi", T::tyakan, &["aDityaka"]); +} + +#[test] +fn sutra_5_2_35() { + assert_has_taddhita("karman", T::aWac, &["karmaWa"]); +} + +#[test] +fn sutra_5_2_36() { + let artha = TadAsyaSamjatam; + assert_has_artha_taddhita("tArakA", artha, T::itac, &["tArakita"]); + assert_has_artha_taddhita("puzpa", artha, T::itac, &["puzpita"]); +} + +#[test] +fn sutra_5_2_37() { + let artha = TadAsyaPramanam; + assert_has_artha_taddhita("Uru", artha, T::dvayasac, &["Urudvayasa"]); + assert_has_artha_taddhita("Uru", artha, T::daGnac, &["UrudaGna"]); + assert_has_artha_taddhita("Uru", artha, T::mAtrac, &["UrumAtra"]); + + assert_has_artha_taddhita("jAnu", artha, T::dvayasac, &["jAnudvayasa"]); + assert_has_artha_taddhita("jAnu", artha, T::daGnac, &["jAnudaGna"]); + assert_has_artha_taddhita("jAnu", artha, T::mAtrac, &["jAnumAtra"]); + + assert_has_artha_taddhita("prasTa", artha, T::mAtrac, &["prasTamAtra"]); +} + +#[test] +fn sutra_5_2_38() { + let artha = TadAsyaPramanam; + assert_has_artha_taddhita("puruza", artha, T::aR, &["pOruza"]); + assert_has_artha_taddhita("puruza", artha, T::dvayasac, &["puruzadvayasa"]); + assert_has_artha_taddhita("puruza", artha, T::daGnac, &["puruzadaGna"]); + assert_has_artha_taddhita("puruza", artha, T::mAtrac, &["puruzamAtra"]); + + assert_has_artha_taddhita("hastin", artha, T::aR, &["hAstina"]); + assert_has_artha_taddhita("hastin", artha, T::dvayasac, &["hastidvayasa"]); + assert_has_artha_taddhita("hastin", artha, T::daGnac, &["hastidaGna"]); + assert_has_artha_taddhita("hastin", artha, T::mAtrac, &["hastimAtra"]); +} + +#[test] +fn sutra_5_2_39() { + assert_has_artha_taddhita("yad", Parimana, T::vatup, &["yAvat"]); + assert_has_artha_taddhita("tad", Parimana, T::vatup, &["tAvat"]); + assert_has_artha_taddhita("etad", Parimana, T::vatup, &["etAvat"]); +} + +#[test] +fn sutra_5_2_40() { + assert_has_artha_taddhita("kim", Parimana, T::vatup, &["kiyat"]); + assert_has_artha_taddhita("idam", Parimana, T::vatup, &["iyat"]); +} + +#[test] +fn sutra_5_2_41() { + assert_has_artha_taddhita("kim", Parimana, T::qati, &["kati"]); +} + +#[test] +fn sutra_5_2_42() { + assert_has_artha_taddhita("paYcan", Avasana, T::tayap, &["paYcataya"]); + assert_has_artha_taddhita("daSan", Avasana, T::tayap, &["daSataya"]); + assert_has_artha_taddhita("catur", Avasana, T::tayap, &["catuzwaya"]); + + let catushtaya = create_taddhitanta("catuzwaya", "catur", T::tayap); + assert_has_sup_1s(&catushtaya, Stri, &["catuzwayI"]); +} + +#[test] +fn sutra_5_2_43() { + assert_has_artha_taddhita("dvi", Avasana, T::tayap, &["dvaya", "dvitaya"]); + assert_has_artha_taddhita("tri", Avasana, T::tayap, &["traya", "tritaya"]); + + let traya = taddhitanta("tri", T::tayap).with_require("traya"); + assert_has_sup_1s(&traya, Stri, &["trayI"]); +} + +#[ignore] +#[test] +fn sutra_5_2_44() { + let ubhaya = create_taddhitanta("uBaya", "uBa", T::tayap); + assert_has_sup_1s(&ubhaya, Pum, &["uBayaH"]); + assert_has_sup_1p(&ubhaya, Pum, &["uBaye"]); +} + +#[test] +fn sutra_5_2_47() { + assert_has_artha_taddhita("dvi", Nimana, T::mayaw, &["dvimaya"]); + assert_has_artha_taddhita("tri", Nimana, T::mayaw, &["trimaya"]); + assert_has_artha_taddhita("catur", Nimana, T::mayaw, &["caturmaya"]); +} + +#[ignore] +#[test] +fn sutra_5_2_48() { + assert_has_artha_taddhita("ekadaSan", Purana, T::qaw, &["ekadaSa"]); + assert_has_artha_taddhita("ekadaSan", Purana, T::qaw, &["ekadaSa"]); +} + +#[ignore] +#[test] +fn sutra_5_2_49() { + assert_has_artha_taddhita("paYcan", Purana, T::qaw, &["paYcama"]); +} + +#[test] +fn sutra_5_2_54() { + assert_has_artha_taddhita("dvi", Purana, T::tIya, &["dvitIya"]); +} + +#[test] +fn sutra_5_2_55() { + assert_has_artha_taddhita("tri", Purana, T::tIya, &["tftIya"]); +} + +#[test] +fn sutra_5_2_61() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("vimukta", artha, T::aR, &["vEmukta"]); + assert_has_artha_taddhita("devAsura", artha, T::aR, &["dEvAsura"]); +} + +#[test] +fn sutra_5_2_62() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("gozada", artha, T::vun, &["gozadaka"]); + assert_has_artha_taddhita("izetvA", artha, T::vun, &["izetvaka"]); + assert_has_artha_taddhita("mAtariSvan", artha, T::vun, &["mAtariSvaka"]); +} + +#[test] +fn sutra_5_2_63() { + assert_has_artha_taddhita("paTin", TatraKushala, T::vun, &["paTaka"]); +} + +#[test] +fn sutra_5_2_64() { + assert_has_artha_taddhita("Akarza", TatraKushala, T::kan, &["Akarzaka"]); + assert_has_artha_taddhita("tsaru", TatraKushala, T::kan, &["tsaruka"]); +} + +#[test] +fn sutra_5_2_65() { + assert_has_artha_taddhita("Dana", TatraKama, T::kan, &["Danaka"]); + assert_has_artha_taddhita("hiraRya", TatraKama, T::kan, &["hiraRyaka"]); +} + +#[test] +fn sutra_5_2_67() { + assert_has_artha_taddhita("udara", TatraAdyuna, T::Wak, &["Odarika"]); + assert_blocked("udara", TatraAdyuna, T::kan); + // HACK -- what is the real artha for udaraka? + assert_has_artha_taddhita("udara", Alpe, T::ka, &["udaraka"]); +} + +#[test] +fn sutra_5_2_68() { + assert_has_artha_taddhita("sasya", TatraParijata, T::kan, &["sasyaka"]); +} + +#[test] +fn sutra_5_2_69() { + assert_has_artha_taddhita("aMSa", Hari, T::kan, &["aMSaka"]); +} + +#[test] +fn sutra_5_2_70() { + assert_has_artha_taddhita("tantra", AciraApahrta, T::kan, &["tantraka"]); +} + +#[test] +fn sutra_5_2_72() { + assert_has_artha_taddhita("SIta", Karin, T::kan, &["SItaka"]); + assert_has_artha_taddhita("uzRa", Karin, T::kan, &["uzRaka"]); +} + +#[test] +fn sutra_5_2_75() { + assert_has_artha_taddhita("pArSva", Anvicchati, T::kan, &["pArSvaka"]); } #[test] fn sutra_5_2_94() { - assert_has_taddhitanta("go", T::matup, &["gomat"]); - assert_has_taddhitanta("vfkza", T::matup, &["vfkzavat"]); - assert_has_taddhitanta("yava", T::matup, &["yavamat"]); - assert_has_taddhitanta("plakza", T::matup, &["plakzavat"]); + assert_has_taddhita("go", T::matup, &["gomat"]); + assert_has_taddhita("vfkza", T::matup, &["vfkzavat"]); + assert_has_taddhita("yava", T::matup, &["yavamat"]); + assert_has_taddhita("plakza", T::matup, &["plakzavat"]); } #[test] fn sutra_5_2_96() { - assert_has_taddhitanta("cUqA", T::lac, &["cUqAla"]); - assert_has_taddhitanta("cUqA", T::matup, &["cUqAvat"]); + assert_has_taddhita("cUqA", T::lac, &["cUqAla"]); + assert_has_taddhita("cUqA", T::matup, &["cUqAvat"]); // AtaH - assert_has_taddhitanta("hasta", T::matup, &["hastavat"]); - assert_has_taddhitanta("pAda", T::matup, &["pAdavat"]); + assert_has_taddhita("hasta", T::matup, &["hastavat"]); + assert_has_taddhita("pAda", T::matup, &["pAdavat"]); +} + +#[test] +fn sutra_5_2_97() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("siDma", artha, T::lac, &["siDmala"]); + assert_has_artha_taddhita("siDma", artha, T::matup, &["siDmavat"]); + assert_has_artha_taddhita("gaqu", artha, T::lac, &["gaqula"]); + assert_has_artha_taddhita("gaqu", artha, T::matup, &["gaqumat"]); +} + +#[test] +fn sutra_5_2_99() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("Pena", artha, T::ilac, &["Penila"]); + assert_has_artha_taddhita("Pena", artha, T::lac, &["Penala"]); + assert_has_artha_taddhita("Pena", artha, T::matup, &["Penavat"]); } #[test] fn sutra_5_2_100() { - assert_has_taddhitanta("loman", T::Sa, &["lomaSa"]); - assert_has_taddhitanta("loman", T::matup, &["lomavat"]); - assert_has_taddhitanta("pAman", T::na, &["pAmana"]); - assert_has_taddhitanta("pAman", T::matup, &["pAmavat"]); - assert_has_taddhitanta("picCa", T::ilac, &["picCila"]); - assert_has_taddhitanta("picCa", T::matup, &["picCavat"]); - assert_has_taddhitanta("uras", T::ilac, &["urasila"]); - assert_has_taddhitanta("uras", T::matup, &["urasvat"]); + assert_has_taddhita("loman", T::Sa, &["lomaSa"]); + assert_has_taddhita("loman", T::matup, &["lomavat"]); + assert_has_taddhita("pAman", T::na, &["pAmana"]); + assert_has_taddhita("pAman", T::matup, &["pAmavat"]); + assert_has_taddhita("picCa", T::ilac, &["picCila"]); + assert_has_taddhita("picCa", T::matup, &["picCavat"]); + assert_has_taddhita("uras", T::ilac, &["urasila"]); + assert_has_taddhita("uras", T::matup, &["urasvat"]); +} + +#[test] +fn sutra_5_2_112() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("rajas", artha, T::valac, &["rajasvala"]); + assert_has_artha_taddhita("kfzI", artha, T::valac, &["kfzIvala"]); + assert_has_artha_taddhita("AsutI", artha, T::valac, &["AsutIvala"]); + assert_has_artha_taddhita("parizad", artha, T::valac, &["parizadvala"]); +} + +#[test] +fn sutra_5_2_112_v1() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("BrAtf", artha, T::valac, &["BrAtfvala"]); + assert_has_artha_taddhita("putra", artha, T::valac, &["putravala"]); + assert_has_artha_taddhita("utsAha", artha, T::valac, &["utsAhavala"]); } #[test] fn sutra_5_2_121() { - assert_has_taddhitanta("yaSas", T::vini, &["yaSasvin"]); - assert_has_taddhitanta("payas", T::vini, &["payasvin"]); - assert_has_taddhitanta("mAyA", T::vini, &["mAyAvin"]); - assert_has_taddhitanta("meDA", T::vini, &["meDAvin"]); - assert_has_taddhitanta("sraj", T::vini, &["sragvin"]); + assert_has_taddhita("yaSas", T::vini, &["yaSasvin"]); + assert_has_taddhita("payas", T::vini, &["payasvin"]); + assert_has_taddhita("mAyA", T::vini, &["mAyAvin"]); + assert_has_taddhita("meDA", T::vini, &["meDAvin"]); + assert_has_taddhita("sraj", T::vini, &["sragvin"]); } diff --git a/vidyut-prakriya/tests/kashika_5_3.rs b/vidyut-prakriya/tests/kashika_5_3.rs index b1322ab..0a11787 100644 --- a/vidyut-prakriya/tests/kashika_5_3.rs +++ b/vidyut-prakriya/tests/kashika_5_3.rs @@ -2,113 +2,118 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha; use vidyut_prakriya::args::TaddhitaArtha::*; +fn assert_blocked(text: &str, artha: TaddhitaArtha, t: T) { + assert_has_artha_taddhita(text, artha, t, &[]); +} + #[ignore] #[test] fn sutra_5_3_3() { - assert_has_taddhitanta("idam", T::ha, &["iha"]); + assert_has_taddhita("idam", T::ha, &["iha"]); } #[ignore] #[test] fn sutra_5_3_4() { - assert_has_taddhitanta("idam", T::rhil, &["etarhi"]); - assert_has_taddhitanta("idam", T::Tamu, &["itTam"]); + assert_has_taddhita("idam", T::rhil, &["etarhi"]); + assert_has_taddhita("idam", T::Tamu, &["itTam"]); } #[test] fn sutra_5_3_5() { - assert_has_taddhitanta("etad", T::tasil, &["atas"]); - assert_has_taddhitanta("etad", T::tral, &["atra"]); + assert_has_taddhita("etad", T::tasil, &["atas"]); + assert_has_taddhita("etad", T::tral, &["atra"]); } #[test] fn sutra_5_3_6() { - assert_has_taddhitanta("sarva", T::dA, &["sarvadA", "sadA"]); + assert_has_taddhita("sarva", T::dA, &["sarvadA", "sadA"]); } #[test] fn sutra_5_3_7() { - assert_has_taddhitanta("kim", T::tasil, &["kutas"]); - assert_has_taddhitanta("yad", T::tasil, &["yatas"]); - assert_has_taddhitanta("tad", T::tasil, &["tatas"]); - assert_has_taddhitanta("bahu", T::tasil, &["bahutas"]); + assert_has_taddhita("kim", T::tasil, &["kutas"]); + assert_has_taddhita("yad", T::tasil, &["yatas"]); + assert_has_taddhita("tad", T::tasil, &["tatas"]); + assert_has_taddhita("bahu", T::tasil, &["bahutas"]); } #[test] fn sutra_5_3_9() { - assert_has_taddhitanta("pari", T::tasil, &["paritas"]); - assert_has_taddhitanta("aBi", T::tasil, &["aBitas"]); + assert_has_taddhita("pari", T::tasil, &["paritas"]); + assert_has_taddhita("aBi", T::tasil, &["aBitas"]); } #[test] fn sutra_5_3_10() { - assert_has_taddhitanta("kim", T::tral, &["kutra"]); - assert_has_taddhitanta("yad", T::tral, &["yatra"]); - assert_has_taddhitanta("tad", T::tral, &["tatra"]); - assert_has_taddhitanta("bahu", T::tral, &["bahutra"]); + assert_has_taddhita("kim", T::tral, &["kutra"]); + assert_has_taddhita("yad", T::tral, &["yatra"]); + assert_has_taddhita("tad", T::tral, &["tatra"]); + assert_has_taddhita("bahu", T::tral, &["bahutra"]); // But, not for idam - assert_has_taddhitanta("idam", T::tral, &[]); + assert_has_taddhita("idam", T::tral, &[]); } #[ignore] #[test] fn sutra_5_3_11() { - assert_has_taddhitanta("idam", T::ha, &["iha"]); + assert_has_taddhita("idam", T::ha, &["iha"]); } #[test] fn sutra_5_3_12() { - assert_has_taddhitanta("kim", T::at, &["kva"]); + assert_has_taddhita("kim", T::at, &["kva"]); } #[test] fn sutra_5_3_13() { - assert_has_taddhitanta("kim", T::ha, &["kuha"]); + assert_has_taddhita("kim", T::ha, &["kuha"]); } #[test] fn sutra_5_3_15() { - assert_has_taddhitanta("sarva", T::dA, &["sarvadA", "sadA"]); - assert_has_taddhitanta("eka", T::dA, &["ekadA"]); - assert_has_taddhitanta("anya", T::dA, &["anyadA"]); - assert_has_taddhitanta("kim", T::dA, &["kadA"]); - assert_has_taddhitanta("yad", T::dA, &["yadA"]); - assert_has_taddhitanta("tad", T::dA, &["tadA"]); - assert_has_taddhitanta("idam", T::dA, &[]); + assert_has_taddhita("sarva", T::dA, &["sarvadA", "sadA"]); + assert_has_taddhita("eka", T::dA, &["ekadA"]); + assert_has_taddhita("anya", T::dA, &["anyadA"]); + assert_has_taddhita("kim", T::dA, &["kadA"]); + assert_has_taddhita("yad", T::dA, &["yadA"]); + assert_has_taddhita("tad", T::dA, &["tadA"]); + assert_has_taddhita("idam", T::dA, &[]); } #[test] fn sutra_5_3_16() { - assert_has_taddhitanta("idam", T::rhil, &["etarhi"]); + assert_has_taddhita("idam", T::rhil, &["etarhi"]); } #[ignore] #[test] fn sutra_5_3_18() { - assert_has_taddhitanta("idam", T::dAnIm, &["idAnIm"]); + assert_has_taddhita("idam", T::dAnIm, &["idAnIm"]); } #[test] fn sutra_5_3_19() { - assert_has_taddhitanta("tad", T::dAnIm, &["tadAnIm"]); + assert_has_taddhita("tad", T::dAnIm, &["tadAnIm"]); } #[ignore] #[test] fn sutra_5_3_23() { - assert_has_taddhitanta("idam", T::Tamu, &["itTam"]); + assert_has_taddhita("idam", T::Tamu, &["itTam"]); } #[test] fn sutra_5_3_24() { - assert_has_taddhitanta("kim", T::Tamu, &["kaTam"]); + assert_has_taddhita("kim", T::Tamu, &["kaTam"]); } #[test] fn sutra_5_3_25() { - assert_has_taddhitanta("tad", T::TAl, &["taTA"]); + assert_has_taddhita("tad", T::TAl, &["taTA"]); } #[test] @@ -128,41 +133,41 @@ fn sutra_5_3_29() { #[test] fn sutra_5_3_42() { // EkaDyam is from 5.3.44. - assert_has_taddhitanta("eka", T::DA, &["ekaDA", "EkaDyam"]); + assert_has_taddhita("eka", T::DA, &["ekaDA", "EkaDyam"]); // dvEDam/trEDam are from 5.3.45. // dveDA/treDA are from 5.3.46. - assert_has_taddhitanta("dvi", T::DA, &["dviDA", "dvEDam", "dveDA"]); - assert_has_taddhitanta("tri", T::DA, &["triDA", "trEDam", "treDA"]); - assert_has_taddhitanta("catur", T::DA, &["caturDA"]); - assert_has_taddhitanta("paYcan", T::DA, &["paYcaDA"]); + assert_has_taddhita("dvi", T::DA, &["dviDA", "dvEDam", "dveDA"]); + assert_has_taddhita("tri", T::DA, &["triDA", "trEDam", "treDA"]); + assert_has_taddhita("catur", T::DA, &["caturDA"]); + assert_has_taddhita("paYcan", T::DA, &["paYcaDA"]); } #[test] fn sutra_5_3_44() { - assert_has_taddhitanta("eka", T::DA, &["ekaDA", "EkaDyam"]); + assert_has_taddhita("eka", T::DA, &["ekaDA", "EkaDyam"]); } #[test] fn sutra_5_3_45_to_sutra_5_3_56() { - assert_has_taddhitanta("dvi", T::DA, &["dviDA", "dvEDam", "dveDA"]); - assert_has_taddhitanta("tri", T::DA, &["triDA", "trEDam", "treDA"]); + assert_has_taddhita("dvi", T::DA, &["dviDA", "dvEDam", "dveDA"]); + assert_has_taddhita("tri", T::DA, &["triDA", "trEDam", "treDA"]); } #[test] fn sutra_5_3_47() { - assert_has_taddhitanta("vEyAkaraRa", T::pASap, &["vEyAkaraRapASa"]); - assert_has_taddhitanta("yAjYika", T::pASap, &["yAjYikapASa"]); + assert_has_taddhita("vEyAkaraRa", T::pASap, &["vEyAkaraRapASa"]); + assert_has_taddhita("yAjYika", T::pASap, &["yAjYikapASa"]); } #[test] fn sutra_5_3_52() { - assert_has_taddhitanta("eka", T::Akinic, &["ekAkin"]); + assert_has_taddhita("eka", T::Akinic, &["ekAkin"]); } #[test] fn sutra_5_3_53() { - assert_has_taddhitanta("AQya", T::caraw, &["AQyacara"]); - assert_has_taddhitanta("sukumAra", T::caraw, &["sukumAracara"]); + assert_has_taddhita("AQya", T::caraw, &["AQyacara"]); + assert_has_taddhita("sukumAra", T::caraw, &["sukumAracara"]); let adhyacara = create_taddhitanta("AQyacara", "AQya", T::caraw); assert_has_sup_1s(&adhyacara, Stri, &["AQyacarI"]); @@ -170,88 +175,234 @@ fn sutra_5_3_53() { #[test] fn sutra_5_3_54() { - assert_has_taddhitanta("devadatta", T::rUpya, &["devadattarUpya"]); - assert_has_taddhitanta("devadatta", T::caraw, &["devadattacara"]); + assert_has_taddhita("devadatta", T::rUpya, &["devadattarUpya"]); + assert_has_taddhita("devadatta", T::caraw, &["devadattacara"]); } #[test] fn sutra_5_3_55() { - assert_has_taddhitanta("AQya", T::tamap, &["AQyatama"]); - assert_has_taddhitanta("darSanIya", T::tamap, &["darSanIyatama"]); - assert_has_taddhitanta("sukumAra", T::tamap, &["sukumAratama"]); - assert_has_taddhitanta("pawu", T::izWan, &["pawizWa"]); - assert_has_taddhitanta("laGu", T::izWan, &["laGizWa"]); - assert_has_taddhitanta("guru", T::izWan, &["garizWa"]); - assert_has_taddhitanta("SrezWa", T::tamap, &["SrezWatama"]); + assert_has_taddhita("AQya", T::tamap, &["AQyatama"]); + assert_has_taddhita("darSanIya", T::tamap, &["darSanIyatama"]); + assert_has_taddhita("sukumAra", T::tamap, &["sukumAratama"]); + assert_has_taddhita("pawu", T::izWan, &["pawizWa"]); + assert_has_taddhita("laGu", T::izWan, &["laGizWa"]); + assert_has_taddhita("guru", T::izWan, &["garizWa"]); + assert_has_taddhita("SrezWa", T::tamap, &["SrezWatama"]); } #[test] fn sutra_5_3_57() { - assert_has_taddhitanta("AQya", T::tarap, &["AQyatara"]); - assert_has_taddhitanta("sukumAra", T::tarap, &["sukumAratara"]); - assert_has_taddhitanta("pawu", T::Iyasun, &["pawIyas"]); + assert_has_taddhita("AQya", T::tarap, &["AQyatara"]); + assert_has_taddhita("sukumAra", T::tarap, &["sukumAratara"]); + assert_has_taddhita("pawu", T::Iyasun, &["pawIyas"]); // TODO: others } #[test] fn sutra_5_3_60_to_sutra_5_3_61() { - assert_has_taddhitanta("praSasya", T::Iyasun, &["Sreyas", "jyAyas"]); - assert_has_taddhitanta("praSasya", T::izWan, &["SrezWa", "jyezWa"]); + assert_has_taddhita("praSasya", T::Iyasun, &["Sreyas", "jyAyas"]); + assert_has_taddhita("praSasya", T::izWan, &["SrezWa", "jyezWa"]); } #[test] fn sutra_5_3_62() { - assert_has_taddhitanta("vfdDa", T::Iyasun, &["jyAyas", "varzIyas"]); - assert_has_taddhitanta("vfdDa", T::izWan, &["jyezWa", "varzizWa"]); + assert_has_taddhita("vfdDa", T::Iyasun, &["jyAyas", "varzIyas"]); + assert_has_taddhita("vfdDa", T::izWan, &["jyezWa", "varzizWa"]); } #[test] fn sutra_5_3_63() { - assert_has_taddhitanta("antika", T::izWan, &["nedizWa"]); - assert_has_taddhitanta("antika", T::Iyasun, &["nedIyas"]); - assert_has_taddhitanta("bAQa", T::izWan, &["sADizWa"]); - assert_has_taddhitanta("bAQa", T::Iyasun, &["sADIyas"]); + assert_has_taddhita("antika", T::izWan, &["nedizWa"]); + assert_has_taddhita("antika", T::Iyasun, &["nedIyas"]); + assert_has_taddhita("bAQa", T::izWan, &["sADizWa"]); + assert_has_taddhita("bAQa", T::Iyasun, &["sADIyas"]); } #[test] fn sutra_5_3_64() { - assert_has_taddhitanta("yuvan", T::izWan, &["kanizWa", "yavizWa"]); - assert_has_taddhitanta("yuvan", T::Iyasun, &["kanIyas", "yavIyas"]); - assert_has_taddhitanta("alpa", T::izWan, &["kanizWa", "alpizWa"]); - assert_has_taddhitanta("alpa", T::Iyasun, &["kanIyas", "alpIyas"]); + assert_has_taddhita("yuvan", T::izWan, &["kanizWa", "yavizWa"]); + assert_has_taddhita("yuvan", T::Iyasun, &["kanIyas", "yavIyas"]); + assert_has_taddhita("alpa", T::izWan, &["kanizWa", "alpizWa"]); + assert_has_taddhita("alpa", T::Iyasun, &["kanIyas", "alpIyas"]); } #[test] fn sutra_5_3_66() { - assert_has_taddhitanta("vEyAkaraRa", T::rUpap, &["vEyAkaraRarUpa"]); - assert_has_taddhitanta("yAjYika", T::rUpap, &["yAjYikarUpa"]); - assert_has_taddhitanta("cora", T::rUpap, &["corarUpa"]); - assert_has_taddhitanta("dasyu", T::rUpap, &["dasyurUpa"]); + assert_has_taddhita("vEyAkaraRa", T::rUpap, &["vEyAkaraRarUpa"]); + assert_has_taddhita("yAjYika", T::rUpap, &["yAjYikarUpa"]); + assert_has_taddhita("cora", T::rUpap, &["corarUpa"]); + assert_has_taddhita("dasyu", T::rUpap, &["dasyurUpa"]); // TODO: pacatirUpam, etc. } #[test] fn sutra_5_3_67() { - assert_has_taddhitanta("pawu", T::kalpap, &["pawukalpa"]); - assert_has_taddhitanta("pawu", T::deSya, &["pawudeSya"]); - assert_has_taddhitanta("pawu", T::deSIyar, &["pawudeSIya"]); + assert_has_taddhita("pawu", T::kalpap, &["pawukalpa"]); + assert_has_taddhita("pawu", T::deSya, &["pawudeSya"]); + assert_has_taddhita("pawu", T::deSIyar, &["pawudeSIya"]); - assert_has_taddhitanta("mfdu", T::kalpap, &["mfdukalpa"]); - assert_has_taddhitanta("mfdu", T::deSya, &["mfdudeSya"]); - assert_has_taddhitanta("mfdu", T::deSIyar, &["mfdudeSIya"]); + assert_has_taddhita("mfdu", T::kalpap, &["mfdukalpa"]); + assert_has_taddhita("mfdu", T::deSya, &["mfdudeSya"]); + assert_has_taddhita("mfdu", T::deSIyar, &["mfdudeSIya"]); // TODO: pacatikalpam, etc. } #[test] fn sutra_5_3_68() { - assert_has_taddhitanta("pawu", T::bahuc, &["bahupawu"]); - assert_has_taddhitanta("mfdu", T::bahuc, &["bahumfdu"]); - assert_has_taddhitanta("guqa", T::bahuc, &["bahuguqa"]); + assert_has_taddhita("pawu", T::bahuc, &["bahupawu"]); + assert_has_taddhita("mfdu", T::bahuc, &["bahumfdu"]); + assert_has_taddhita("guqa", T::bahuc, &["bahuguqa"]); } #[test] fn sutra_5_3_69() { - assert_has_taddhitanta("pawu", T::jAtIyar, &["pawujAtIya"]); - assert_has_taddhitanta("mfdu", T::jAtIyar, &["mfdujAtIya"]); - assert_has_taddhitanta("darSanIya", T::jAtIyar, &["darSanIyajAtIya"]); + assert_has_taddhita("pawu", T::jAtIyar, &["pawujAtIya"]); + assert_has_taddhita("mfdu", T::jAtIyar, &["mfdujAtIya"]); + assert_has_taddhita("darSanIya", T::jAtIyar, &["darSanIyajAtIya"]); +} + +#[test] +fn sutra_5_3_70() { + assert_has_artha_taddhita("aSva", Ajnate, T::ka, &["aSvaka"]); + assert_has_artha_taddhita("gardaBa", Ajnate, T::ka, &["gardaBaka"]); +} + +#[test] +fn sutra_5_3_75() { + assert_has_artha_taddhita("SUdra", Kutsite, T::kan, &["SUdraka"]); + assert_has_artha_taddhita("DAra", Kutsite, T::kan, &["DAraka"]); + assert_has_artha_taddhita("pUrRa", Kutsite, T::kan, &["pUrRaka"]); +} + +#[test] +fn sutra_5_3_76() { + assert_has_artha_taddhita("putra", Anukampayam, T::ka, &["putraka"]); + assert_has_artha_taddhita("vatsa", Anukampayam, T::ka, &["vatsaka"]); + assert_has_artha_taddhita("durbala", Anukampayam, T::ka, &["durbalaka"]); +} + +#[test] +fn sutra_5_3_86() { + assert_has_artha_taddhita("vfkza", Hrasve, T::ka, &["vfkzaka"]); + assert_has_artha_taddhita("plakza", Hrasve, T::ka, &["plakzaka"]); + assert_has_artha_taddhita("stamBa", Hrasve, T::ka, &["stamBaka"]); +} + +#[test] +fn sutra_5_3_87() { + assert_has_artha_taddhita("vaMSa", Hrasve, T::ka, &["vaMSaka"]); + assert_has_artha_taddhita("veRu", Hrasve, T::ka, &["veRuka"]); + assert_has_artha_taddhita("daRqa", Hrasve, T::ka, &["daRqaka"]); +} + +#[test] +fn sutra_5_3_88() { + assert_has_artha_taddhita("kuwI", Hrasve, T::ra, &["kuwIra"]); + assert_has_artha_taddhita("SamI", Hrasve, T::ra, &["SamIra"]); + assert_has_artha_taddhita("SuRqA", Hrasve, T::ra, &["SuRqAra"]); + assert_blocked("kuwI", Hrasve, T::ka); +} + +#[test] +fn sutra_5_3_89() { + assert_has_artha_taddhita("kutU", Hrasve, T::qupac, &["kutupa"]); + assert_blocked("kutU", Hrasve, T::ka); +} + +#[test] +fn sutra_5_3_90() { + let kasutara = create_artha_taddhita("kAsUtara", "kAsU", Hrasve, T::zwarac); + let gonitara = create_artha_taddhita("goRItara", "goRI", Hrasve, T::zwarac); + assert_has_sup_1s(&kasutara, Stri, &["kAsUtarI"]); + assert_has_sup_1s(&gonitara, Stri, &["goRItarI"]); + assert_blocked("kAsU", Hrasve, T::ka); +} + +#[test] +fn sutra_5_3_91() { + assert_has_artha_taddhita("vatsa", Tanutve, T::zwarac, &["vatsatara"]); + assert_has_artha_taddhita("ukzan", Tanutve, T::zwarac, &["ukzatara"]); + assert_has_artha_taddhita("aSva", Tanutve, T::zwarac, &["aSvatara"]); + assert_has_artha_taddhita("fzaBa", Tanutve, T::zwarac, &["fzaBatara"]); +} + +#[test] +fn sutra_5_3_92() { + assert_has_artha_taddhita("kim", DvayorEka, T::qatarac, &["katara"]); + assert_has_artha_taddhita("yad", DvayorEka, T::qatarac, &["yatara"]); + assert_has_artha_taddhita("tad", DvayorEka, T::qatarac, &["tatara"]); +} + +#[test] +fn sutra_5_3_93() { + assert_has_artha_taddhita("kim", BahunamEka, T::qatamac, &["katama"]); + assert_has_artha_taddhita("yad", BahunamEka, T::qatamac, &["yatama"]); + assert_has_artha_taddhita("tad", BahunamEka, T::qatamac, &["tatama"]); +} + +#[ignore] +#[test] +fn sutra_5_3_94() { + assert_has_artha_taddhita("eka", DvayorEka, T::qatarac, &["ekatara"]); + assert_has_artha_taddhita("eka", BahunamEka, T::qatamac, &["ekatama"]); +} + +#[test] +fn sutra_5_3_96() { + assert_has_artha_taddhita("aSva", IvePratikrtau, T::kan, &["aSvaka"]); + assert_has_artha_taddhita("uzwra", IvePratikrtau, T::kan, &["uzwraka"]); + assert_has_artha_taddhita("gardaBa", IvePratikrtau, T::kan, &["gardaBaka"]); +} + +#[test] +fn sutra_5_3_101() { + let vasteya = create_artha_taddhita("vAsteya", "vasti", IvePratikrtau, T::QaY); + assert_has_sup_1s(&vasteya, Pum, &["vAsteyaH"]); + assert_has_sup_1s(&vasteya, Stri, &["vAsteyI"]); +} + +#[test] +fn sutra_5_3_103() { + assert_has_artha_taddhita("SAKA", IvePratikrtau, T::yat, &["SAKya"]); + assert_has_artha_taddhita("muKa", IvePratikrtau, T::yat, &["muKya"]); + assert_has_artha_taddhita("jaGana", IvePratikrtau, T::yat, &["jaGanya"]); +} + +#[test] +fn sutra_5_3_105() { + assert_has_artha_taddhita("kuSAgra", IvePratikrtau, T::Ca, &["kuSAgrIya"]); +} + +#[test] +fn sutra_5_3_107() { + assert_has_artha_taddhita("SarkarA", IvePratikrtau, T::aR, &["SArkara"]); + assert_has_artha_taddhita("kapAlikA", IvePratikrtau, T::aR, &["kApAlika"]); +} + +#[test] +fn sutra_5_3_108() { + assert_has_artha_taddhita("aNguli", IvePratikrtau, T::Wak, &["ANgulika"]); + assert_has_artha_taddhita("Baruja", IvePratikrtau, T::Wak, &["BArujika"]); +} + +#[test] +fn sutra_5_3_109() { + assert_has_artha_taddhita("ekaSAlA", IvePratikrtau, T::Wac, &["ekaSAlika"]); + assert_has_artha_taddhita("ekaSAlA", IvePratikrtau, T::Wak, &["EkaSAlika"]); +} + +#[test] +fn sutra_5_3_110() { + assert_has_artha_taddhita("karka", IvePratikrtau, T::Ikak, &["kArkIka"]); + assert_has_artha_taddhita("lohita", IvePratikrtau, T::Ikak, &["lOhitIka"]); +} + +#[ignore] +#[test] +fn sutra_5_3_115() { + let artha = AyudhaJiviSangha; + let varkenya = create_artha_taddhita("vArkeRya", "vfka", artha, T::weRyaR); + assert_has_sup_1s(&varkenya, Pum, &["vArkeRyaH"]); + assert_has_sup_1d(&varkenya, Pum, &["vArkeRyO"]); + assert_has_sup_1p(&varkenya, Pum, &["vfkAH"]); } diff --git a/vidyut-prakriya/tests/kashika_5_4.rs b/vidyut-prakriya/tests/kashika_5_4.rs index aba90a6..29e54ba 100644 --- a/vidyut-prakriya/tests/kashika_5_4.rs +++ b/vidyut-prakriya/tests/kashika_5_4.rs @@ -8,128 +8,146 @@ use vidyut_prakriya::args::Unadi; #[test] fn sutra_5_4_3() { - assert_has_taddhitanta(&prati("sTUla"), T::kan, &["sTUlaka"]); - assert_has_taddhitanta(&prati("aRu"), T::kan, &["aRuka"]); - assert_has_taddhitanta(&prati("mAza"), T::kan, &["mAzaka"]); - assert_has_taddhitanta(&prati("gomUtra"), T::kan, &["gomUtraka"]); + assert_has_taddhita("sTUla", T::kan, &["sTUlaka"]); + assert_has_taddhita("aRu", T::kan, &["aRuka"]); + assert_has_taddhita("mAza", T::kan, &["mAzaka"]); + assert_has_taddhita("gomUtra", T::kan, &["gomUtraka"]); } #[test] fn sutra_5_4_3_v1() { - assert_has_taddhitanta(&prati("caYcut"), T::kan, &["caYcutka"]); - assert_has_taddhitanta(&prati("bfhat"), T::kan, &["bfhatka"]); + assert_has_taddhita("caYcut", T::kan, &["caYcutka"]); + assert_has_taddhita("bfhat", T::kan, &["bfhatka"]); +} + +#[ignore] +#[test] +fn sutra_5_4_6() { + assert_has_artha_taddhita("bfhatI", Acchadana, T::kan, &["bfhatika"]); +} + +#[test] +fn sutra_5_4_7() { + assert_has_artha_taddhita("azaqakza", Svarthe, T::Ka, &["azaqakzIRa"]); + assert_has_artha_taddhita("ASitaNgu", Svarthe, T::Ka, &["ASitaNgavIna"]); + assert_has_artha_taddhita("alaNkarman", Svarthe, T::Ka, &["alaNkarmIRa"]); + assert_has_artha_taddhita("alampuruza", Svarthe, T::Ka, &["alampuruzIRa"]); + + // TODO: how to derive rAjADi? nalopa has in asiddha section ... + // let rajadhi = create_tatpurusha("rAjADi", &["rAjan", "aDi"], Vibhakti::Saptami); + // assert_has_artha_taddhita(&rajadhi, Svarthe, T::Ka, &["rAjADIna"]); } #[test] fn sutra_5_4_17() { - assert_has_taddhitanta(&prati("paYcan"), T::kftvasuc, &["paYcakftvas"]); - assert_has_taddhitanta(&prati("saptan"), T::kftvasuc, &["saptakftvas"]); + assert_has_taddhita("paYcan", T::kftvasuc, &["paYcakftvas"]); + assert_has_taddhita("saptan", T::kftvasuc, &["saptakftvas"]); // TODO: saNKyAyAH? // For these, see 5.4.18. - assert_has_taddhitanta(&prati("dvi"), T::kftvasuc, &[]); - assert_has_taddhitanta(&prati("tri"), T::kftvasuc, &[]); - assert_has_taddhitanta(&prati("catur"), T::kftvasuc, &[]); + assert_has_taddhita("dvi", T::kftvasuc, &[]); + assert_has_taddhita("tri", T::kftvasuc, &[]); + assert_has_taddhita("catur", T::kftvasuc, &[]); } #[ignore] #[test] fn sutra_5_4_18() { - assert_has_taddhitanta(&prati("dvi"), T::suc, &["dviH"]); - assert_has_taddhitanta(&prati("tri"), T::suc, &["triH"]); - assert_has_taddhitanta(&prati("catur"), T::suc, &["catuH"]); + assert_has_taddhita("dvi", T::suc, &["dviH"]); + assert_has_taddhita("tri", T::suc, &["triH"]); + assert_has_taddhita("catur", T::suc, &["catuH"]); } #[ignore] #[test] fn sutra_5_4_19() { - assert_has_taddhitanta(&prati("eka"), T::suc, &["sakft"]); + assert_has_taddhita("eka", T::suc, &["sakft"]); } #[test] fn sutra_5_4_21() { - assert_has_taddhitanta(&prati("anna"), T::mayaw, &["annamaya"]); - assert_has_taddhitanta(&prati("apUpa"), T::mayaw, &["apUpamaya"]); - assert_has_taddhitanta(&prati("vawaka"), T::mayaw, &["vawakamaya"]); + assert_has_taddhita("anna", T::mayaw, &["annamaya"]); + assert_has_taddhita("apUpa", T::mayaw, &["apUpamaya"]); + assert_has_taddhita("vawaka", T::mayaw, &["vawakamaya"]); } #[test] fn sutra_5_4_23() { - assert_has_taddhitanta(&prati("ananta"), T::Yya, &["Anantya"]); - assert_has_taddhitanta(&prati("AvasaTa"), T::Yya, &["AvasaTya"]); - assert_has_taddhitanta(&prati("itiha"), T::Yya, &["Etihya"]); - assert_has_taddhitanta(&prati("Bezaja"), T::Yya, &["BEzajya"]); + assert_has_taddhita("ananta", T::Yya, &["Anantya"]); + assert_has_taddhita("AvasaTa", T::Yya, &["AvasaTya"]); + assert_has_taddhita("itiha", T::Yya, &["Etihya"]); + assert_has_taddhita("Bezaja", T::Yya, &["BEzajya"]); } #[test] fn sutra_5_4_26() { - assert_has_taddhitanta(&prati("atiTi"), T::Yya, &["AtiTya"]); + assert_has_taddhita("atiTi", T::Yya, &["AtiTya"]); } #[test] fn sutra_5_4_27() { - assert_has_taddhitanta("deva", T::tal, &["devatA"]); + assert_has_taddhita("deva", T::tal, &["devatA"]); } #[test] fn sutra_5_4_28() { - assert_has_taddhitanta("avi", T::ka, &["avika"]); + assert_has_taddhita("avi", T::ka, &["avika"]); } #[test] fn sutra_5_4_29() { - assert_has_taddhitanta("yAva", T::ka, &["yAvaka"]); - assert_has_taddhitanta("maRi", T::ka, &["maRika"]); + assert_has_taddhita("yAva", T::ka, &["yAvaka"]); + assert_has_taddhita("maRi", T::ka, &["maRika"]); } #[test] fn sutra_5_4_30_to_sutra_5_4_32() { - assert_has_taddhitanta("lohita", T::ka, &["lohitaka"]); + assert_has_taddhita("lohita", T::ka, &["lohitaka"]); } #[test] fn sutra_5_4_33() { - assert_has_taddhitanta("kAla", T::ka, &["kAlaka"]); + assert_has_taddhita("kAla", T::ka, &["kAlaka"]); } #[test] fn sutra_5_4_34() { - assert_has_taddhitanta("vinaya", T::Wak, &["vEnayika"]); - assert_has_taddhitanta("samaya", T::Wak, &["sAmayika"]); - assert_has_taddhitanta("upAya", T::Wak, &["OpAyika"]); + assert_has_taddhita("vinaya", T::Wak, &["vEnayika"]); + assert_has_taddhita("samaya", T::Wak, &["sAmayika"]); + assert_has_taddhita("upAya", T::Wak, &["OpAyika"]); } #[test] fn sutra_5_4_35() { - assert_has_taddhitanta("vAc", T::Wak, &["vAcika"]); + assert_has_taddhita("vAc", T::Wak, &["vAcika"]); } #[ignore] #[test] fn sutra_5_4_39() { - assert_has_taddhitanta(&prati("mft"), T::tikan, &["mfttikA"]); + assert_has_taddhita("mft", T::tikan, &["mfttikA"]); } #[ignore] #[test] fn sutra_5_4_43() { - assert_has_taddhitanta(&prati("dvi"), T::Sas, &["dviSaH"]); - assert_has_taddhitanta(&prati("tri"), T::Sas, &["triSaH"]); - assert_has_taddhitanta(&prati("kArzApaRa"), T::Sas, &["kArzApaRaSaH"]); - assert_has_taddhitanta(&prati("mAza"), T::Sas, &["mAzaSaH"]); - assert_has_taddhitanta(&prati("pAda"), T::Sas, &["pAdaSaH"]); + assert_has_taddhita("dvi", T::Sas, &["dviSaH"]); + assert_has_taddhita("tri", T::Sas, &["triSaH"]); + assert_has_taddhita("kArzApaRa", T::Sas, &["kArzApaRaSaH"]); + assert_has_taddhita("mAza", T::Sas, &["mAzaSaH"]); + assert_has_taddhita("pAda", T::Sas, &["pAdaSaH"]); } #[test] fn sutra_5_4_44() { - assert_has_taddhitanta(&prati("vAsudeva"), T::tasi, &["vAsudevatas"]); - assert_has_taddhitanta(&prati("arjuna"), T::tasi, &["arjunatas"]); + assert_has_taddhita("vAsudeva", T::tasi, &["vAsudevatas"]); + assert_has_taddhita("arjuna", T::tasi, &["arjunatas"]); // Akrtigana - assert_has_taddhitanta(&prati("Adi"), T::tasi, &["Aditas"]); - assert_has_taddhitanta(&prati("maDya"), T::tasi, &["maDyatas"]); - assert_has_taddhitanta(&prati("pArSva"), T::tasi, &["pArSvatas"]); - assert_has_taddhitanta(&prati("pfzWa"), T::tasi, &["pfzWatas"]); + assert_has_taddhita("Adi", T::tasi, &["Aditas"]); + assert_has_taddhita("maDya", T::tasi, &["maDyatas"]); + assert_has_taddhita("pArSva", T::tasi, &["pArSvatas"]); + assert_has_taddhita("pfzWa", T::tasi, &["pfzWatas"]); } #[test] @@ -156,8 +174,8 @@ fn sutra_5_4_52() { #[test] fn sutra_5_4_54() { - assert_has_taddhitanta(&prati("agni"), T::sAti, &["agnisAt"]); - assert_has_taddhitanta(&prati("udaka"), T::sAti, &["udakasAt"]); + assert_has_taddhita("agni", T::sAti, &["agnisAt"]); + assert_has_taddhita("udaka", T::sAti, &["udakasAt"]); } #[test] @@ -251,7 +269,6 @@ fn sutra_5_4_106() { // TODO: others } -#[ignore] #[test] fn sutra_5_4_108() { assert_has_avyayibhava("upa", "rAjan", &["uparAjam"]); @@ -260,6 +277,52 @@ fn sutra_5_4_108() { assert_has_avyayibhava("prati", "Atman", &["pratyAtmam"]); } +#[test] +fn sutra_5_4_111() { + assert_has_avyayibhava("upa", "samiD", &["upasamiDam", "upasamit"]); + assert_has_avyayibhava("upa", "dfzad", &["upadfzadam", "upadfzat"]); +} + +#[test] +fn sutra_5_4_112() { + assert_has_avyayibhava("antar", "giri", &["antargiram", "antargiri"]); + assert_has_avyayibhava("upa", "giri", &["upagiram", "upagiri"]); +} + +#[test] +fn sutra_5_4_115() { + assert_has_bahuvrihi("dvi", "mUrDan", &["dvimUrDa"]); + assert_has_bahuvrihi("tri", "mUrDan", &["trimUrDa"]); +} + +#[test] +fn sutra_5_4_117() { + assert_has_bahuvrihi("antar", "loman", &["antarloma"]); + assert_has_bahuvrihi("bahis", "loman", &["bahirloma"]); +} + +#[test] +fn sutra_5_4_125() { + assert_has_bahuvrihi("su", "jamBa", &["sujamBan"]); + assert_has_bahuvrihi("harita", "jamBa", &["haritajamBan"]); + assert_has_bahuvrihi("tfRa", "jamBa", &["tfRajamBan"]); + assert_has_bahuvrihi("soma", "jamBa", &["somajamBan"]); + + // others? + assert_has_bahuvrihi("patita", "jamBa", &["patitajamBa"]); +} + +#[test] +fn sutra_5_4_129() { + assert_has_bahuvrihi("pra", "jAnu", &["prajYu"]); + assert_has_bahuvrihi("sam", "jAnu", &["saYjYu"]); +} + +#[test] +fn sutra_5_4_130() { + assert_has_bahuvrihi("UrDva", "jAnu", &["UrDvajAnu", "UrDvajYu"]); +} + #[test] fn sutra_5_4_132() { assert_has_bahuvrihi("SArNga", "Danus", &["SArNgaDanvan"]); @@ -284,6 +347,12 @@ fn sutra_5_4_135() { // TODO: suganDa in other sense } +#[test] +fn sutra_5_4_140() { + assert_has_bahuvrihi("dvi", "pAda", &["dvipAd"]); + assert_has_bahuvrihi("su", "pAda", &["supAd"]); +} + #[test] fn sutra_5_4_148() { assert_has_bahuvrihi("ud", "kAkuda", &["utkAkud"]); diff --git a/vidyut-prakriya/tests/kashika_6_1.rs b/vidyut-prakriya/tests/kashika_6_1.rs index 5b840f8..0443fa1 100644 --- a/vidyut-prakriya/tests/kashika_6_1.rs +++ b/vidyut-prakriya/tests/kashika_6_1.rs @@ -1,4 +1,5 @@ extern crate test_utils; +use lazy_static::lazy_static; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; @@ -6,9 +7,14 @@ use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; +lazy_static! { + static ref S: Tester = Tester::with_svara_rules(); +} + #[test] fn sutra_6_1_1() { assert_has_tip( @@ -24,7 +30,7 @@ fn sutra_6_1_1() { #[test] fn sutra_6_1_2() { - let san = |u, g| d(u, g).with_sanadi(&[Sanadi::San]); + let san = |u, g| d(u, g).with_sanadi(&[Sanadi::san]); assert_has_tip(&[], &san("awa~", Bhvadi), Lat, &["awiwizati"]); assert_has_tip(&[], &san("aSa~", Kryadi), Lat, &["aSiSizati"]); assert_has_tip(&[], &san("f\\", Kryadi), Lat, &["aririzati"]); @@ -32,7 +38,7 @@ fn sutra_6_1_2() { #[test] fn sutra_6_1_3() { - let san = |u, g| d(u, g).with_sanadi(&[Sanadi::San]); + let san = |u, g| d(u, g).with_sanadi(&[Sanadi::san]); assert_has_tip(&[], &san("undI~", Rudhadi), Lat, &["undidizati"]); assert_has_tip(&[], &san("adqa~", Bhvadi), Lat, &["aqqiqizati"]); assert_has_tip(&[], &san("arca~", Bhvadi), Lat, &["arcicizati"]); @@ -60,8 +66,8 @@ fn sutra_6_1_3_v2() { #[test] fn sutra_6_1_4() { let pac = d("qupa\\ca~^z", Bhvadi); - let san = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::San]); - let yan = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Yan]); + let san = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::san]); + let yan = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::yaN]); assert_has_tip(&[], &pac, Lit, &["papAca"]); assert_has_tip(&[], &san(&pac), Lat, &["pipakzati"]); @@ -124,7 +130,7 @@ fn sutra_6_1_9() { assert_has_lat(&["pra"], &yan(&d("UrRuY", Adadi)), &["prorRonUyate"]); // anaByAsasya assert_has_lat(&[], &san(&d("gupa~\\", Bhvadi)), &["jugupsizate"]); - let lu_yan_san = d("lUY", Kryadi).with_sanadi(&[Sanadi::Yan, Sanadi::San]); + let lu_yan_san = d("lUY", Kryadi).with_sanadi(&[Sanadi::yaN, Sanadi::san]); assert_has_lat(&[], &lu_yan_san, &["lolUyizate"]); } @@ -137,7 +143,7 @@ fn sutra_6_1_10() { #[test] fn sutra_6_1_11() { - let nic = |u, g| d(u, g).with_sanadi(&[Sanadi::Nic]); + let nic = |u, g| d(u, g).with_sanadi(&[Sanadi::Ric]); assert_has_tip(&[], &nic("qupa\\ca~^z", Bhvadi), Lun, &["apIpacat"]); assert_has_tip(&[], &nic("paWa~", Bhvadi), Lun, &["apIpaWat"]); @@ -304,7 +310,7 @@ fn sutra_6_1_17() { #[test] fn sutra_6_1_18() { - let svap_nic = d("Yizva\\pa~", Adadi).with_sanadi(&[Sanadi::Nic]); + let svap_nic = d("Yizva\\pa~", Adadi).with_sanadi(&[Sanadi::Ric]); assert_has_tip(&[], &svap_nic, Lun, &["asUzupat"]); assert_has_tas(&[], &svap_nic, Lun, &["asUzupatAm"]); assert_has_jhi(&[], &svap_nic, Lun, &["asUzupan"]); @@ -315,7 +321,7 @@ fn sutra_6_1_18() { #[test] fn sutra_6_1_19() { - let yan = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Yan]); + let yan = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::yaN]); let svap = d("Yizva\\pa~", Adadi); let syam = d("syamu~", Bhvadi); @@ -383,20 +389,20 @@ fn sutra_6_1_28() { #[test] fn sutra_6_1_29() { let pyay = d("o~pyAyI~\\", Bhvadi); - assert_has_tinanta(&["AN"], &pyay, Lit, Prathama, Eka, &["Apipye"]); - assert_has_tinanta(&["AN"], &pyay, Lit, Prathama, Dvi, &["ApipyAte"]); - assert_has_tinanta(&["AN"], &pyay, Lit, Prathama, Bahu, &["Apipyire"]); + assert_has_tinantas(&["AN"], &pyay, Lit, Prathama, Eka, &["Apipye"]); + assert_has_tinantas(&["AN"], &pyay, Lit, Prathama, Dvi, &["ApipyAte"]); + assert_has_tinantas(&["AN"], &pyay, Lit, Prathama, Bahu, &["Apipyire"]); // yaNi - assert_has_tinanta(&["AN"], &yan(&pyay), Lat, Prathama, Eka, &["ApepIyate"]); - assert_has_tinanta(&["AN"], &yan(&pyay), Lat, Prathama, Dvi, &["ApepIyete"]); - assert_has_tinanta(&["AN"], &yan(&pyay), Lat, Prathama, Bahu, &["ApepIyante"]); + assert_has_tinantas(&["AN"], &yan(&pyay), Lat, Prathama, Eka, &["ApepIyate"]); + assert_has_tinantas(&["AN"], &yan(&pyay), Lat, Prathama, Dvi, &["ApepIyete"]); + assert_has_tinantas(&["AN"], &yan(&pyay), Lat, Prathama, Bahu, &["ApepIyante"]); } #[test] fn sutra_6_1_30() { let svi = d("wuo~Svi", Bhvadi); - assert_has_tinanta(&[], &svi, Lit, Prathama, Eka, &["SuSAva", "SiSvAya"]); - assert_has_tinanta(&[], &svi, Lit, Prathama, Dvi, &["SuSuvatuH", "SiSviyatuH"]); + assert_has_tinantas(&[], &svi, Lit, Prathama, Eka, &["SuSAva", "SiSvAya"]); + assert_has_tinantas(&[], &svi, Lit, Prathama, Dvi, &["SuSuvatuH", "SiSviyatuH"]); assert_has_lat(&[], &yan(&svi), &["SoSUyate", "SeSvIyate"]); } @@ -730,11 +736,11 @@ fn sutra_6_1_78() { #[test] fn sutra_6_1_79() { - assert_has_taddhitanta(&prati("baBru"), T::yaY, &["bABravya"]); - assert_has_taddhitanta(&prati("maRqu"), T::yaY, &["mARqavya"]); - assert_has_taddhitanta(&prati("SaNku"), T::yat, &["SaNkavya"]); - assert_has_taddhitanta(&prati("picu"), T::yat, &["picavya"]); - assert_has_taddhitanta(&prati("nO"), T::yat, &["nAvya"]); + assert_has_taddhita("baBru", T::yaY, &["bABravya"]); + assert_has_taddhita("maRqu", T::yaY, &["mARqavya"]); + assert_has_taddhita("SaNku", T::yat, &["SaNkavya"]); + assert_has_taddhita("picu", T::yat, &["picavya"]); + assert_has_taddhita("nO", T::yat, &["nAvya"]); // TODO: vAntaH? @@ -757,16 +763,16 @@ fn sutra_6_1_80() { assert_has_krdanta(&[], &pu, Krt::Ryat, &["pAvya"]); // DAtoH? - assert_has_taddhitanta(&prati("baBru"), T::yaY, &["bABravya"]); - assert_has_taddhitanta(&prati("go"), T::yat, &["gavya"]); - assert_has_taddhitanta(&prati("nO"), T::yat, &["nAvya"]); + assert_has_taddhita("baBru", T::yaY, &["bABravya"]); + assert_has_taddhita("go", T::yat, &["gavya"]); + assert_has_taddhita("nO", T::yat, &["nAvya"]); // tan-nimittasya? let u = d("u\\N", Bhvadi); assert_has_ta_k(&["upa"], &u, Lat, &["upoyate"]); assert_has_ta_k(&[], &u, Lan, &["Oyata"]); - assert_has_taddhitanta(&prati("loyamAna"), T::iY, &["lOyamAni"]); - assert_has_taddhitanta(&prati("poyamAna"), T::iY, &["pOyamAni"]); + assert_has_taddhita("loyamAna", T::iY, &["lOyamAni"]); + assert_has_taddhita("poyamAna", T::iY, &["pOyamAni"]); } #[test] @@ -1041,10 +1047,10 @@ fn sutra_6_1_114() { #[test] fn sutra_6_1_125() { - let agni = create_sup_1d("agnI", "agni", Pum); - let vayu = create_sup_1d("vAyU", "vAyu", Pum); - let khatve = create_sup_1d("Kawve", &nyap("KawvA"), Stri); - let male = create_sup_1d("mAle", &nyap("mAlA"), Stri); + let agni = sup_1d("agnI", "agni", Pum); + let vayu = sup_1d("vAyU", "vAyu", Pum); + let khatve = sup_1d("Kawve", &nyap("KawvA"), Stri); + let male = sup_1d("mAle", &nyap("mAlA"), Stri); let iti = Pada::from_text("iti"); assert_has_vakya(&agni, &iti, &["agnI iti"]); @@ -1121,4 +1127,176 @@ fn sutra_6_1_141() { assert_has_krdanta(&["prati"], &kr, Krt::kta, &["pratiskIrRa", "pratikIrRa"]); } -// 6.1.158 - 6.1.223 are various accent rules. +#[test] +fn sutra_6_1_159() { + S.assert_has_krt(&[], &d("kf\\za~", Bhvadi), Krt::GaY, &["karza/"]); +} + +#[ignore] +#[test] +fn sutra_6_1_162() { + S.assert_has_tip(&[], &d("qupa\\ca~^z", Bhvadi), Lat, &["pa/cati"]); + S.assert_has_tip(&[], &d("paWa~", Bhvadi), Lat, &["pa/Wati"]); + S.assert_has_tip(&[], &d("UrRuY", Adadi), Lat, &["UrRo/ti", "UrRO/ti"]); + S.assert_has_tip(&[], &d("gupU~", Bhvadi), Lat, &["gopAya/ti"]); + S.assert_has_tip(&[], &d("yA\\", Adadi), Lat, &["yA/ti"]); +} + +#[test] +fn sutra_6_1_163() { + S.assert_has_krt(&[], &d("Ba\\njo~", Rudhadi), Krt::Gurac, &["BaNgura/"]); + S.assert_has_krt(&[], &d("BAsf~\\", Bhvadi), Krt::Gurac, &["BAsura/"]); + S.assert_has_krt(&[], &d("YimidA~", Divadi), Krt::Gurac, &["medura/"]); + // TODO: others +} + +#[test] +fn sutra_6_1_164() { + S.assert_has_artha_taddhita("kuYja", Gotra, T::cPaY, &["kOYjAyana/"]); + // TODO: where is this from? + // S.assert_has_artha_taddhita("muYja", Gotra, T::cPaY, &["mOYjAyana/"]); +} + +#[test] +fn sutra_6_1_165() { + S.assert_has_artha_taddhita("naqa", Gotra, T::Pak, &["nAqAyana/"]); + S.assert_has_artha_taddhita("cara", Gotra, T::Pak, &["cArAyaRa/"]); + S.assert_has_artha_taddhita("akza", TenaDivyatiJayatiJitam, T::Wak, &["Akzika/"]); +} + +#[test] +fn sutra_6_1_166() { + S.assert_has_sup_1p("tri", Stri, &["tisra/H"]); +} + +#[test] +fn sutra_6_1_167() { + S.assert_has_sup_2p("catur", Pum, &["catu/raH"]); +} + +#[test] +fn sutra_6_1_179() { + S.assert_has_sup_3p("zaz", Pum, &["zaqBi/H"]); + S.assert_has_sup_4p("zaz", Pum, &["zaqBya/H"]); + S.assert_has_sup_6p("paYcan", Pum, &["paYcAnA/m"]); + S.assert_has_sup_6p("zaz", Pum, &["zaRRA/m"]); + S.assert_has_sup_6p("saptan", Pum, &["saptAnA/m"]); + + S.assert_has_sup_3p("tri", Pum, &["triBi/H"]); + S.assert_has_sup_4p("tri", Pum, &["triBya/H"]); + S.assert_has_sup_6p("tri", Pum, &["trayARA/m"]); + + // TODO: caturByaH? + S.assert_has_sup_6p("catur", Pum, &["caturRA/m"]); + + // halAdiH? + S.assert_has_sup_2p("catur", Stri, &["cata/sraH"]); +} + +#[test] +fn sutra_6_1_180() { + S.assert_has_sup_3p("paYcan", Pum, &["paYca/BiH"]); + S.assert_has_sup_3p("saptan", Pum, &["sapta/BiH"]); + S.assert_has_sup_3p("tri", Stri, &["tisf/BiH"]); + S.assert_has_sup_3p("catur", Pum, &["catu/rBiH"]); + + // Jali? + S.assert_has_sup_6p("paYcan", Pum, &["paYcAnA/m"]); + S.assert_has_sup_6p("saptan", Pum, &["saptAnA/m"]); + + // upottama? + S.assert_has_sup_3p("zaz", Pum, &["zaqBi/H"]); + S.assert_has_sup_4p("zaz", Pum, &["zaqBya/H"]); +} + +#[test] +fn sutra_6_1_183() { + S.assert_has_sup_3d("div", Pum, &["dyu/ByAm"]); + S.assert_has_sup_3p("div", Pum, &["dyu/BiH"]); + + // Jal? + S.assert_has_sup_3s("div", Pum, &["di/vA"]); +} + +#[test] +fn sutra_6_1_185() { + let kr = d("qukf\\Y", Tanadi); + let hr = d("hf\\Y", Bhvadi); + S.assert_has_krt(&[], &san(&kr), Krt::yat, &["cikIrzya^"]); + S.assert_has_krt(&[], &san(&hr), Krt::yat, &["jihIrzya^"]); + S.assert_has_krt(&[], &kr, Krt::Ryat, &["kArya^"]); + S.assert_has_krt(&[], &hr, Krt::Ryat, &["hArya^"]); +} + +#[test] +fn sutra_6_1_191() { + S.assert_has_sup_1s("sarva", Pum, &["sa/rvaH"]); + S.assert_has_sup_1d("sarva", Pum, &["sa/rvO"]); + S.assert_has_sup_1p("sarva", Pum, &["sa/rve"]); +} + +#[test] +fn sutra_6_1_193() { + let kr = d("qukf\\Y", Tanadi); + let hr = d("hf\\Y", Bhvadi); + S.assert_has_krt(&[], &san(&kr), Krt::Rvul, &["cikI/rzaka"]); + S.assert_has_krt(&[], &san(&hr), Krt::Rvul, &["jihI/rzaka"]); + + S.assert_has_taddhita("BOriki", T::viDal, &["BOriki/viDa"]); + S.assert_has_taddhita("BOliki", T::viDal, &["BOliki/viDa"]); + S.assert_has_taddhita("EzukAri", T::Baktal, &["EzukAri/Bakta"]); +} + +#[test] +fn sutra_6_1_197() { + S.assert_has_taddhita("garga", T::yaY, &["gA/rgya"]); +} + +#[test] +fn sutra_6_1_199() { + S.assert_has_sup_1s("paTin", Pum, &["pa/nTAH"]); + S.assert_has_sup_1d("paTin", Pum, &["pa/nTAnO"]); + S.assert_has_sup_1p("paTin", Pum, &["pa/nTAnaH"]); + + S.assert_has_sup_1s("maTin", Pum, &["ma/nTAH"]); + S.assert_has_sup_1d("maTin", Pum, &["ma/nTAnO"]); + S.assert_has_sup_1p("maTin", Pum, &["ma/nTAnaH"]); + + // TODO: others +} + +#[test] +fn sutra_6_1_211() { + S.assert_has_sup_6s("yuzmad", Pum, &["ta/va"]); + S.assert_has_sup_6s("asmad", Pum, &["ma/ma"]); +} + +#[test] +fn sutra_6_1_212() { + S.assert_has_sup_4s("yuzmad", Pum, &["tu/Byam"]); + S.assert_has_sup_4s("asmad", Pum, &["ma/hyam"]); +} + +#[test] +fn sutra_6_1_217() { + let kr = d("qukf\\Y", Tanadi); + let hr = d("hf\\Y", Bhvadi); + S.assert_has_krt(&[], &kr, Krt::anIyar, &["karaRI/ya"]); + S.assert_has_krt(&[], &hr, Krt::anIyar, &["haraRI/ya"]); + + S.assert_has_taddhita("pawu", T::jAtIyar, &["pawujAtI/ya"]); + S.assert_has_taddhita("mfdu", T::jAtIyar, &["mfdujAtI/ya"]); +} + +#[test] +fn sutra_6_1_222() { + let dadhyac = create_upapada_krdanta("daDyac", "daDi", &[], &d("ancu~", Bhvadi), Krt::kvin); + S.assert_has_sup_2p(&dadhyac, Pum, &["daDI/caH"]); + S.assert_has_sup_3s(&dadhyac, Pum, &["daDI/cA"]); + S.assert_has_sup_4s(&dadhyac, Pum, &["daDI/ce"]); + + let madhvac = create_upapada_krdanta("maDvac", "maDu", &[], &d("ancu~", Bhvadi), Krt::kvin); + S.assert_has_sup_2p(&madhvac, Pum, &["maDU/caH"]); + S.assert_has_sup_3s(&madhvac, Pum, &["maDU/cA"]); + S.assert_has_sup_4s(&madhvac, Pum, &["maDU/ce"]); +} diff --git a/vidyut-prakriya/tests/kashika_6_2.rs b/vidyut-prakriya/tests/kashika_6_2.rs new file mode 100644 index 0000000..da5659a --- /dev/null +++ b/vidyut-prakriya/tests/kashika_6_2.rs @@ -0,0 +1,48 @@ +extern crate test_utils; +use lazy_static::lazy_static; +use test_utils::*; + +lazy_static! { + static ref S: Tester = Tester::with_svara_rules(); +} + +#[test] +fn sutra_6_2_27() { + S.assert_has_karmadharaya("kumAra", "pratyenas", &["ku/mArapratyenas"]); +} + +#[ignore] +#[test] +fn sutra_6_2_179() { + S.assert_has_bahuvrihi("antar", "vana", &["antarvaRa/"]); +} + +#[ignore] +#[test] +fn sutra_6_2_180() { + S.assert_has_bahuvrihi("pra", "antar", &["prAnta/r"]); +} + +#[test] +fn sutra_6_2_185() { + S.assert_has_bahuvrihi("aBi", "muKa", &["aBimuKa/"]); +} + +#[test] +fn sutra_6_2_186() { + S.assert_has_bahuvrihi("apa", "muKa", &["apamuKa/"]); +} + +#[test] +fn sutra_6_2_187() { + S.assert_has_bahuvrihi("apa", "sPiga", &["apasPiga/"]); + S.assert_has_bahuvrihi("apa", "pUta", &["apapUta/"]); + S.assert_has_bahuvrihi("apa", "vIRA", &["apavIRA/"]); + S.assert_has_bahuvrihi("apa", "aYjas", &["apAYja/s"]); + S.assert_has_bahuvrihi("apa", "aDvan", &["apADva/n"]); + S.assert_has_bahuvrihi("apa", "kukzi", &["apakukzi/"]); + S.assert_has_bahuvrihi("apa", "sIra", &["apasIra/"]); + S.assert_has_bahuvrihi("apa", "nAman", &["apanAma/n"]); + + // TODO: apahala, etc. +} diff --git a/vidyut-prakriya/tests/kashika_6_3.rs b/vidyut-prakriya/tests/kashika_6_3.rs index f6dd740..0bf4e6b 100644 --- a/vidyut-prakriya/tests/kashika_6_3.rs +++ b/vidyut-prakriya/tests/kashika_6_3.rs @@ -3,21 +3,83 @@ use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; +use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; +#[test] +fn skip_sutra_6_3_1() {} + +#[test] +fn sutra_6_3_2() { + let mukta = create_krdanta("mukta", &[], &d("mu\\cx~^", Tudadi), Krt::kta); + let agata = create_krdanta("Agata", &["AN"], &d("ga\\mx~", Bhvadi), Krt::kta); + assert_has_panchami_tatpurusha("stoka", &mukta, &["stokAnmukta"]); + assert_has_panchami_tatpurusha("alpa", &mukta, &["alpAnmukta"]); + assert_has_panchami_tatpurusha("antika", &agata, &["antikAdAgata"]); + assert_has_panchami_tatpurusha("aByASa", &agata, &["aByASAdAgata"]); + assert_has_panchami_tatpurusha("dUra", &agata, &["dUrAdAgata"]); + assert_has_panchami_tatpurusha("viprakfzwa", &agata, &["viprakfzwAdAgata"]); + assert_has_panchami_tatpurusha("kfcCra", &mukta, &["kfcCrAnmukta"]); +} + +#[test] +fn sutra_6_3_3() { + let krta = create_krdanta("kfta", &[], &d("qukf\\Y", Tanadi), Krt::kta); + assert_has_trtiya_tatpurusha("ojas", &krta, &["ojasAkfta"]); + assert_has_trtiya_tatpurusha("sahas", &krta, &["sahasAkfta"]); + assert_has_trtiya_tatpurusha("amBas", &krta, &["amBasAkfta"]); + assert_has_trtiya_tatpurusha("tamas", &krta, &["tamasAkfta"]); +} + +#[test] +fn sutra_6_3_7() { + assert_has_caturthi_tatpurusha("Atman", "pada", &["Atmanepada"]); +} + +#[test] +fn sutra_6_3_8() { + assert_has_caturthi_tatpurusha("para", "pada", &["parasmEpada"]); +} + +#[test] +fn sutra_6_3_11() { + assert_has_saptami_tatpurusha("maDya", "guru", &["maDyeguru"]); +} + +#[test] +fn sutra_6_3_11_v1() { + assert_has_saptami_tatpurusha("anta", "guru", &["anteguru"]); +} + +#[test] +fn sutra_6_3_15() { + assert_has_saptami_tatpurusha("prAvfz", "ja", &["prAvfzija"]); + assert_has_saptami_tatpurusha("Sarad", "ja", &["Saradija"]); + assert_has_saptami_tatpurusha("kAla", "ja", &["kAleja"]); + assert_has_saptami_tatpurusha("div", "ja", &["divija"]); +} + +#[test] +fn sutra_6_3_16() { + assert_has_saptami_tatpurusha("varza", "ja", &["varzeja", "varzaja"]); + assert_has_saptami_tatpurusha("kzara", "ja", &["kzareja", "kzaraja"]); + assert_has_saptami_tatpurusha("Sara", "ja", &["Sareja", "Saraja"]); + assert_has_saptami_tatpurusha("vara", "ja", &["vareja", "varaja"]); +} + #[test] fn sutra_6_3_43() { - assert_has_taddhitanta(&prati("brAhmaRI"), T::tarap, &["brAhmaRitara"]); - assert_has_taddhitanta(&prati("brAhmaRI"), T::tamap, &["brAhmaRitama"]); - assert_has_taddhitanta(&prati("brAhmaRI"), T::rUpap, &["brAhmaRirUpa"]); - assert_has_taddhitanta(&prati("brAhmaRI"), T::kalpap, &["brAhmaRikalpa"]); + assert_has_taddhita("brAhmaRI", T::tarap, &["brAhmaRitara"]); + assert_has_taddhita("brAhmaRI", T::tamap, &["brAhmaRitama"]); + assert_has_taddhita("brAhmaRI", T::rUpap, &["brAhmaRirUpa"]); + assert_has_taddhita("brAhmaRI", T::kalpap, &["brAhmaRikalpa"]); // TODO: others - // assert_has_taddhitanta(&prati("brAhmaRI"), T::tamap, &["brAhmaRibruva"]); - // assert_has_taddhitanta(&prati("brAhmaRI"), T::tamap, &["brAhmaRigotra"]); - // assert_has_taddhitanta(&prati("brAhmaRI"), T::tamap, &["brAhmaRimata"]); - // assert_has_taddhitanta(&prati("brAhmaRI"), T::tamap, &["brAhmaRihata"]); + // assert_has_taddhitanta("brAhmaRI", T::tamap, &["brAhmaRibruva"]); + // assert_has_taddhitanta("brAhmaRI", T::tamap, &["brAhmaRigotra"]); + // assert_has_taddhitanta("brAhmaRI", T::tamap, &["brAhmaRimata"]); + // assert_has_taddhitanta("brAhmaRI", T::tamap, &["brAhmaRihata"]); } #[test] @@ -26,7 +88,7 @@ fn sutra_6_3_46() { assert_has_karmadharaya("mahat", "brAhmaRa", &["mahAbrAhmaRa"]); assert_has_bahuvrihi("mahat", "bAhu", &["mahAbAhu"]); assert_has_bahuvrihi("mahat", "bala", &["mahAbala"]); - assert_has_taddhitanta(&prati("mahat"), T::jAtIyar, &["mahAjAtIya"]); + assert_has_taddhita("mahat", T::jAtIyar, &["mahAjAtIya"]); // samAnAdhikaraNa? assert_has_sasthi_tatpurusha("mahat", "putra", &["mahatputra"]); @@ -67,6 +129,94 @@ fn sutra_6_3_69() { assert_has_upapada_krdanta("pur", &[], &daari, Krt::Kac, &["purandara"]); } +#[test] +fn sutra_6_3_73() { + assert_has_avyaya_tatpurusha("naY", "brAhmaRa", &["abrAhmaRa"]); + assert_has_avyaya_tatpurusha("naY", "vfzala", &["avfzala"]); + assert_has_avyaya_tatpurusha("naY", "somapa", &["asomapa"]); +} + +#[test] +fn sutra_6_3_74() { + assert_has_avyaya_tatpurusha("naY", "aja", &["anaja"]); + assert_has_avyaya_tatpurusha("naY", "aSva", &["anaSva"]); +} + +#[test] +fn sutra_6_3_85() { + assert_has_bahuvrihi("samAna", "jyotis", &["sajyotis"]); + assert_has_bahuvrihi("samAna", "janapada", &["sajanapada"]); + assert_has_bahuvrihi("samAna", "rAtri", &["sarAtri"]); + assert_has_bahuvrihi("samAna", "nABi", &["sanABi"]); + assert_has_bahuvrihi("samAna", "nAman", &["sanAman"]); + assert_has_bahuvrihi("samAna", "gotra", &["sagotra"]); + assert_has_bahuvrihi("samAna", "rUpa", &["sarUpa"]); + assert_has_bahuvrihi("samAna", "sTAna", &["sasTAna"]); + assert_has_bahuvrihi("samAna", "varRa", &["savarRa"]); + assert_has_bahuvrihi("samAna", "vayas", &["savayas"]); + assert_has_bahuvrihi("samAna", "vacana", &["savacana"]); + assert_has_bahuvrihi("samAna", "banDu", &["sabanDu"]); +} + +#[test] +fn sutra_6_3_89() { + let drsh = d("df\\Si~r", Bhvadi); + assert_has_upapada_krdanta("samAna", &[], &drsh, Krt::kvin, &["sadfS"]); + assert_has_upapada_krdanta("samAna", &[], &drsh, Krt::kaY, &["sadfSa"]); +} + +#[test] +fn sutra_6_3_90() { + let drsh = d("df\\Si~r", Bhvadi); + assert_has_upapada_krdanta("idam", &[], &drsh, Krt::kvin, &["IdfS"]); + assert_has_upapada_krdanta("idam", &[], &drsh, Krt::kaY, &["IdfSa"]); + assert_has_taddhita("idam", T::vatup, &["iyat"]); + + assert_has_upapada_krdanta("kim", &[], &drsh, Krt::kvin, &["kIdfS"]); + assert_has_upapada_krdanta("kim", &[], &drsh, Krt::kaY, &["kIdfSa"]); + assert_has_taddhita("kim", T::vatup, &["kiyat"]); +} + +#[test] +fn sutra_6_3_91() { + let drsh = d("df\\Si~r", Bhvadi); + assert_has_upapada_krdanta("tad", &[], &drsh, Krt::kvin, &["tAdfS"]); + assert_has_upapada_krdanta("tad", &[], &drsh, Krt::kaY, &["tAdfSa"]); + assert_has_taddhita("tad", T::vatup, &["tAvat"]); + + assert_has_upapada_krdanta("yad", &[], &drsh, Krt::kvin, &["yAdfS"]); + assert_has_upapada_krdanta("yad", &[], &drsh, Krt::kaY, &["yAdfSa"]); + assert_has_taddhita("yad", T::vatup, &["yAvat"]); +} + +#[test] +fn sutra_6_3_101() { + assert_has_avyaya_tatpurusha("ku", "aja", &["kadaja"]); + assert_has_avyaya_tatpurusha("ku", "aSva", &["kadaSva"]); + assert_has_avyaya_tatpurusha("ku", "uzwra", &["kaduzwra"]); + assert_has_avyaya_tatpurusha("ku", "anna", &["kadanna"]); + + // tatpuruze? + assert_has_bahuvrihi("ku", "uzwra", &["kUzwra"]); + + // aci? + assert_has_avyaya_tatpurusha("ku", "brAhmaRa", &["kubrAhmaRa"]); + assert_has_avyaya_tatpurusha("ku", "puruza", &["kupuruza"]); +} + +#[test] +fn sutra_6_3_102() { + assert_has_avyaya_tatpurusha("ku", "raTa", &["kadraTa"]); + assert_has_avyaya_tatpurusha("ku", "vada", &["kadvada"]); +} + +#[test] +fn sutra_6_3_104() { + // TODO: how to get kApaTa? + assert_has_avyaya_tatpurusha("ku", "paTin", &["kApaTin"]); + assert_has_avyaya_tatpurusha("ku", "akza", &["kAkza"]); +} + #[test] fn sutra_6_3_111() { assert_has_krdanta(&[], &d("li\\ha~^", Adadi), Krt::kta, &["lIQa"]); @@ -104,6 +254,22 @@ fn sutra_6_3_112() { assert_has_thas(&["ud"], &vah, Lun, &["udavoQam"]); } +#[test] +fn sutra_6_3_118() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("Asuti", artha, T::valac, &["AsutIvala"]); + assert_has_artha_taddhita("kfzi", artha, T::valac, &["kfzIvala"]); + assert_has_artha_taddhita("danta", artha, T::valac, &["dantAvala"]); +} + +#[test] +fn sutra_6_3_118_v1() { + let artha = TadAsyaAstiAsmin; + assert_has_artha_taddhita("utsAha", artha, T::valac, &["utsAhavala"]); + assert_has_artha_taddhita("BrAtf", artha, T::valac, &["BrAtfvala"]); + assert_has_artha_taddhita("pitf", artha, T::valac, &["pitfvala"]); +} + #[test] fn sutra_6_3_123() { let kash = d("kASf~", Bhvadi); @@ -129,3 +295,16 @@ fn sutra_6_3_124() { // ti ? // TODO: how to best justify sudatta? } + +#[test] +fn sutra_6_3_138() { + let dadhyac = create_upapada_krdanta("daDyac", "daDi", &[], &d("ancu~", Bhvadi), Krt::kvin); + assert_has_sup_2p(&dadhyac, Pum, &["daDIcaH"]); + assert_has_sup_3s(&dadhyac, Pum, &["daDIcA"]); + assert_has_sup_4s(&dadhyac, Pum, &["daDIce"]); + + let madhvac = create_upapada_krdanta("maDvac", "maDu", &[], &d("ancu~", Bhvadi), Krt::kvin); + assert_has_sup_2p(&madhvac, Pum, &["maDUcaH"]); + assert_has_sup_3s(&madhvac, Pum, &["maDUcA"]); + assert_has_sup_4s(&madhvac, Pum, &["maDUce"]); +} diff --git a/vidyut-prakriya/tests/kashika_6_4.rs b/vidyut-prakriya/tests/kashika_6_4.rs index 80de57e..82f4883 100644 --- a/vidyut-prakriya/tests/kashika_6_4.rs +++ b/vidyut-prakriya/tests/kashika_6_4.rs @@ -6,17 +6,10 @@ use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; -fn prati_udit(text: &str) -> Pratipadika { - Pratipadika::builder() - .text(text) - .is_udit(true) - .build() - .unwrap() -} - fn assert_has_hi(prefixes: &[&str], d: &Dhatu, expected: &[&str]) { assert_has_sip(prefixes, &d, Lot, expected); } @@ -113,7 +106,7 @@ fn sutra_6_4_8() { #[test] fn sutra_6_4_10() { - let shreyas = prati_udit("Sreyas"); + let shreyas = taddhitanta("praSasya", T::Iyasun).with_require("Sreyas"); assert_has_sup_1s(&shreyas, Pum, &["SreyAn"]); assert_has_sup_1d(&shreyas, Pum, &["SreyAMsO"]); assert_has_sup_1p(&shreyas, Pum, &["SreyAMsaH"]); @@ -121,7 +114,7 @@ fn sutra_6_4_10() { assert_has_sup_1p("payas", Napumsaka, &["payAMsi"]); assert_has_sup_1p("yaSas", Napumsaka, &["yaSAMsi"]); // mahat - let mahat = prati_udit("mahat"); + let mahat = create_krdanta("mahat", &[], &d("maha~", Bhvadi), Unadi::ati); assert_has_sup_1s(&mahat, Pum, &["mahAn"]); assert_has_sup_1d(&mahat, Pum, &["mahAntO"]); assert_has_sup_1p(&mahat, Pum, &["mahAntaH"]); @@ -130,12 +123,31 @@ fn sutra_6_4_10() { assert_has_sup_ss(&mahat, Pum, &["mahan"]); } +#[ignore] +#[test] +fn sutra_6_4_11() { + assert_has_sup_1p("ap", Stri, &["ApaH"]); + let bahvap = create_bahuvrihi("bahvap", "bahu", "ap"); + assert_has_sup_1p(&bahvap, Napumsaka, &["bahvAmpi"]); +} + +#[ignore] +#[test] +fn sutra_6_4_12() { + let bahudandin = create_bahuvrihi("bahudaRqin", "bahu", "daRqin"); + assert_has_sup_1p(&bahudandin, Napumsaka, &["bahudaRqIni"]); + + let bahucchatrin = create_bahuvrihi("bahucCatrin", "bahu", "Catrin"); + assert_has_sup_1p(&bahucchatrin, Napumsaka, &["bahucCatrIRi"]); +} + #[test] fn sutra_6_4_14() { - assert_has_sup_1s(&prati_udit("Bavat"), Pum, &["BavAn"]); - assert_has_sup_1s(&prati_udit("kftavat"), Pum, &["kftavAn"]); - assert_has_sup_1s(&prati_udit("gomat"), Pum, &["gomAn"]); - assert_has_sup_1s(&prati_udit("yavamat"), Pum, &["yavamAn"]); + let bhavat = create_krdanta("Bavat", &[], &d("BA\\", Adadi), Unadi::qavatu); + assert_has_sup_1s(bhavat, Pum, &["BavAn"]); + assert_has_sup_1s(taddhitanta("kfta", T::matup), Pum, &["kftavAn"]); + assert_has_sup_1s(taddhitanta("go", T::matup), Pum, &["gomAn"]); + assert_has_sup_1s(taddhitanta("yava", T::matup), Pum, &["yavamAn"]); assert_has_sup_1s("suyaSas", Pum, &["suyaSAH"]); assert_has_sup_1s("suSrotas", Pum, &["suSrotAH"]); // TODO: others @@ -376,19 +388,22 @@ fn sutra_6_4_33() { #[test] fn sutra_6_4_34() { let shas = d("SAsu~", Adadi); - assert_has_tinanta(&["anu"], &shas, Lun, Prathama, Eka, &["anvaSizat"]); - assert_has_tinanta(&["anu"], &shas, Lun, Prathama, Dvi, &["anvaSizatAm"]); - assert_has_tinanta(&["anu"], &shas, Lun, Prathama, Bahu, &["anvaSizan"]); + assert_has_tip(&["anu"], &shas, Lun, &["anvaSizat"]); + assert_has_tas(&["anu"], &shas, Lun, &["anvaSizatAm"]); + assert_has_jhi(&["anu"], &shas, Lun, &["anvaSizan"]); + // Niti - assert_has_tinanta(&[], &shas, Lat, Uttama, Dvi, &["SizvaH"]); - assert_has_tinanta(&[], &shas, Lat, Uttama, Bahu, &["SizmaH"]); + assert_has_vas(&[], &shas, Lat, &["SizvaH"]); + assert_has_mas(&[], &shas, Lat, &["SizmaH"]); + // aNhaloH - assert_has_tinanta(&[], &shas, Lat, Prathama, Bahu, &["SAsati"]); - assert_has_tinanta(&[], &shas, Lit, Prathama, Dvi, &["SaSAsatuH"]); - assert_has_tinanta(&[], &shas, Lit, Prathama, Bahu, &["SaSAsuH"]); + assert_has_jhi(&[], &shas, Lat, &["SAsati"]); + assert_has_tas(&[], &shas, Lit, &["SaSAsatuH"]); + assert_has_jhi(&[], &shas, Lit, &["SaSAsuH"]); + // Not A-SAs let ashas = d("SAsu~\\", Adadi); - assert_has_tinanta(&["AN"], &ashas, Lat, Prathama, Eka, &["ASAste"]); + assert_has_ta(&["AN"], &ashas, Lat, &["ASAste"]); // TODO: others } @@ -396,22 +411,8 @@ fn sutra_6_4_34() { #[test] fn sutra_6_4_35() { let shas = d("SAsu~", Adadi); - assert_has_tinanta( - &["anu"], - &shas, - Lot, - Madhyama, - Eka, - &["anuSADi", "anuSizwAt"], - ); - assert_has_tinanta( - &["pra"], - &shas, - Lot, - Madhyama, - Eka, - &["praSADi", "praSizwAt"], - ); + assert_has_sip(&["anu"], &shas, Lot, &["anuSADi", "anuSizwAt"]); + assert_has_sip(&["pra"], &shas, Lot, &["praSADi", "praSizwAt"]); } #[test] @@ -426,32 +427,41 @@ fn sutra_6_4_37() { assert_has_krdanta(&[], &yam, Krt::kta, &["yata"]); assert_has_krdanta(&[], &yam, Krt::ktavatu, &["yatavat"]); assert_has_krdanta(&[], &yam, Krt::ktin, &["yati"]); + let ram = d("ra\\ma~", Bhvadi); assert_has_krdanta(&[], &ram, Krt::ktvA, &["ratvA"]); assert_has_krdanta(&[], &ram, Krt::kta, &["rata"]); assert_has_krdanta(&[], &ram, Krt::ktavatu, &["ratavat"]); assert_has_krdanta(&[], &ram, Krt::ktin, &["rati"]); + let van = d("vana~", Bhvadi); assert_has_krdanta(&[], &van, Krt::ktin, &["vati"]); // TODO: ktic test + let tan = d("tanu~^", Tanadi); assert_has_krdanta(&[], &tan, Krt::kta, &["tata"]); assert_has_krdanta(&[], &tan, Krt::ktavatu, &["tatavat"]); + let kzan = d("kzaRu~^", Tanadi); assert_has_krdanta(&[], &kzan, Krt::kta, &["kzata"]); assert_has_krdanta(&[], &kzan, Krt::ktavatu, &["kzatavat"]); + let rn = d("fRu~^", Tanadi); assert_has_krdanta(&[], &rn, Krt::kta, &["fta"]); assert_has_krdanta(&[], &rn, Krt::ktavatu, &["ftavat"]); + let tfn = d("tfRu~^", Tanadi); assert_has_krdanta(&[], &tfn, Krt::kta, &["tfta"]); assert_has_krdanta(&[], &tfn, Krt::ktavatu, &["tftavat"]); + let ghfn = d("GfRu~^", Tanadi); assert_has_krdanta(&[], &ghfn, Krt::kta, &["Gfta"]); assert_has_krdanta(&[], &ghfn, Krt::ktavatu, &["Gftavat"]); + let van = d("vanu~\\", Tanadi); assert_has_krdanta(&[], &van, Krt::kta, &["vata"]); assert_has_krdanta(&[], &van, Krt::ktavatu, &["vatavat"]); + let man = d("manu~\\", Tanadi); assert_has_krdanta(&[], &man, Krt::kta, &["mata"]); assert_has_krdanta(&[], &man, Krt::ktavatu, &["matavat"]); @@ -459,20 +469,25 @@ fn sutra_6_4_37() { assert_has_ta(&[], &tan, Lun, &["atata", "atanizwa"]); assert_has_thaas(&[], &tan, Lun, &["ataTAH", "atanizWAH"]); // anudAttopadeSavanatitanotyAdInAm ? + let sham = d("Samu~", Divadi); assert_has_krdanta(&[], &sham, Krt::kta, &["SAnta"]); assert_has_krdanta(&[], &sham, Krt::ktavatu, &["SAntavat"]); + let tam = d("tamu~", Divadi); assert_has_krdanta(&[], &tam, Krt::kta, &["tAnta"]); assert_has_krdanta(&[], &tam, Krt::ktavatu, &["tAntavat"]); + let dam = d("damu~", Divadi); assert_has_krdanta(&[], &dam, Krt::kta, &["dAnta"]); assert_has_krdanta(&[], &dam, Krt::ktavatu, &["dAntavat"]); // anunAsikasya + let pac = d("qupa\\ca~^z", Bhvadi); assert_has_krdanta(&[], &pac, Krt::kta, &["pakva"]); assert_has_krdanta(&[], &pac, Krt::ktavatu, &["pakvavat"]); // Jali + let gam = d("ga\\mx~", Bhvadi); assert_has_ta_k(&[], &gam, Lat, &["gamyate"]); assert_has_ta_k(&[], &d("ra\\mu~\\", Bhvadi), Lat, &["ramyate"]); @@ -515,6 +530,14 @@ fn sutra_6_4_38() { assert_has_krdanta(&["pra"], &d("kzaRu~^", Tanadi), Krt::ktvA, &["prakzatya"]); } +#[test] +fn sutra_6_4_40() { + let gam = d("ga\\mx~", Bhvadi); + assert_has_upapada_krdanta("aNga", &[], &gam, Krt::kvip, &["aNgagat"]); + assert_has_upapada_krdanta("kaliNga", &[], &gam, Krt::kvip, &["kaliNgagat"]); + assert_has_upapada_krdanta("aDvan", &[], &gam, Krt::kvip, &["aDvagat"]); +} + #[test] fn sutra_6_4_42() { let jan = d("janI~\\", Divadi); @@ -577,8 +600,8 @@ fn sutra_6_4_48() { assert_has_krdanta(&[], &san(&kf), Krt::tfc, &["cikIrzitf"]); assert_has_krdanta(&[], &san(&kf), Krt::tumun, &["cikIrzitum"]); assert_has_krdanta(&[], &san(&kf), Krt::tavya, &["cikIrzitavya"]); - assert_has_tinanta(&[], &d("Divi~", Bhvadi), Lat, Prathama, Dvi, &["DinutaH"]); - assert_has_tinanta(&[], &d("kfvi~", Bhvadi), Lat, Prathama, Dvi, &["kfRutaH"]); + assert_has_tas(&[], &d("Divi~", Bhvadi), Lat, &["DinutaH"]); + assert_has_tas(&[], &d("kfvi~", Bhvadi), Lat, &["kfRutaH"]); // ataH assert_has_krdanta(&[], &d("ci\\Y", Svadi), Krt::tfc, &["cetf"]); @@ -589,8 +612,8 @@ fn sutra_6_4_48() { assert_has_krdanta(&[], &d("vA\\", Adadi), Krt::tfc, &["vAtf"]); // ArdhadhAtuke - assert_has_taddhitanta("vfkza", T::tva, &["vfkzatva"]); - assert_has_taddhitanta("vfkza", T::tal, &["vfkzatA"]); + assert_has_taddhita("vfkza", T::tva, &["vfkzatva"]); + assert_has_taddhita("vfkza", T::tal, &["vfkzatA"]); // Others let hf = d("hf\\Y", Bhvadi); @@ -689,6 +712,24 @@ fn sutra_6_4_55() { assert_has_krdanta(&[], &d("pAra", Curadi), Krt::izRuc, &["pArayizRu"]); } +#[ignore] +#[test] +fn sutra_6_4_56() { + use Krt::ktvA; + assert_has_krdanta(&["pra"], &nic(&d("Ra\\ma~", Bhvadi)), ktvA, &["praRamayya"]); + assert_has_krdanta(&["pra"], &nic(&d("tamu~", Divadi)), ktvA, &["pratamayya"]); + assert_has_krdanta(&["pra"], &nic(&d("damu~", Divadi)), ktvA, &["pradamayya"]); + assert_has_krdanta(&["pra"], &nic(&d("Samu~", Divadi)), ktvA, &["praSamayya"]); + assert_has_krdanta(&["pra"], &nic(&d("damu~", Divadi)), ktvA, &["sandamayya"]); + + let bebhidya = yan_nic(&d("Bi\\di^&r", Rudhadi)); + assert_has_krdanta(&["pra"], &bebhidya, ktvA, &["prabeBidayya"]); + assert_has_krdanta(&["pra"], &nic(&d("gaRa", Curadi)), ktvA, &["pragaRayya"]); + + // laGupUrva? + assert_has_krdanta(&["pra"], &nic(&d("patx~", Bhvadi)), ktvA, &["prapAtya"]); +} + #[ignore] #[test] fn sutra_6_4_62() { @@ -779,9 +820,9 @@ fn sutra_6_4_62() { #[test] fn sutra_6_4_63() { let di = d("dI\\N", Divadi); - assert_has_tinanta(&["upa"], &di, Lit, Prathama, Eka, &["upadidIye"]); - assert_has_tinanta(&["upa"], &di, Lit, Prathama, Dvi, &["upadidIyAte"]); - assert_has_tinanta(&["upa"], &di, Lit, Prathama, Bahu, &["upadidIyire"]); + assert_has_tinantas(&["upa"], &di, Lit, Prathama, Eka, &["upadidIye"]); + assert_has_tinantas(&["upa"], &di, Lit, Prathama, Dvi, &["upadidIyAte"]); + assert_has_tinantas(&["upa"], &di, Lit, Prathama, Bahu, &["upadidIyire"]); // aci? assert_has_lat(&["upa"], &yan(&di), &["upadedIyate"]); @@ -948,16 +989,69 @@ fn sutra_6_4_72() { assert_has_lun(&[], &ih, &["Ehizwa"]); assert_has_lun(&[], &ubj, &["ObjIt"]); assert_has_lun(&[], &umbh, &["OmBIt"]); + assert_has_lan(&[], &ikz, &["Ekzata"]); assert_has_lan(&[], &ih, &["Ehata"]); assert_has_lan(&[], &ubj, &["Objat"]); assert_has_lan(&[], &umbh, &["OmBat"]); + assert_has_lrn(&[], &ikz, &["Ekzizyata"]); assert_has_lrn(&[], &ih, &["Ehizyata"]); assert_has_lrn(&[], &ubj, &["Objizyat"]); assert_has_lrn(&[], &umbh, &["OmBizyat"]); } +#[test] +fn sutra_6_4_77() { + // Snu + let aap = d("A\\px~", Svadi); + let radh = d("rA\\Da~", Svadi); + let shak = d("Sa\\kx~", Svadi); + assert_has_jhi(&[], &aap, Lat, &["Apnuvanti"]); + assert_has_jhi(&[], &radh, Lat, &["rADnuvanti"]); + assert_has_jhi(&[], &shak, Lat, &["Saknuvanti"]); + + // DAtu + let kzi = d("kzi\\", Bhvadi); + let lu = d("lUY", Kryadi); + let ni_kvip = create_krdanta("nI", &[], &d("RI\\Y", Bhvadi), Krt::kvip); + let lu_kvip = create_krdanta("lU", &[], &lu, Krt::kvip); + assert_has_tas(&[], &kzi, Lit, &["cikziyatuH"]); + assert_has_jhi(&[], &kzi, Lit, &["cikziyuH"]); + assert_has_tas(&[], &lu, Lit, &["luluvatuH"]); + assert_has_jhi(&[], &lu, Lit, &["luluvuH"]); + assert_has_sup_1d(&ni_kvip, Pum, &["niyO"]); + assert_has_sup_1p(&ni_kvip, Pum, &["niyaH"]); + assert_has_sup_1d(&lu_kvip, Pum, &["luvO"]); + assert_has_sup_1p(&lu_kvip, Pum, &["luvaH"]); + + // BrU + assert_has_sup_1d("BrU", Stri, &["BruvO"]); + assert_has_sup_1p("BrU", Stri, &["BruvaH"]); + + // aci? + assert_has_tip(&[], &aap, VidhiLin, &["ApnuyAt"]); + assert_has_tip(&[], &shak, VidhiLin, &["SaknuyAt"]); + assert_has_tip(&[], &d("sA\\Da~", Svadi), VidhiLin, &["sADnuyAt"]); + + // SnuDAtuBruvAm? + assert_has_sup_4s("lakzmI", Stri, &["lakzmyE"]); + assert_has_sup_4s("vaDU", Stri, &["vaDvE"]); + + // yvoH? + let kr = d("qukf\\Y", Tanadi); + assert_has_tas(&[], &kr, Lit, &["cakratuH"]); + assert_has_jhi(&[], &kr, Lit, &["cakruH"]); + + // guna-vrddhi + let ci = d("ci\\Y", Svadi); + assert_has_krdanta(&[], &ci, Krt::lyuw, &["cayana"]); + assert_has_krdanta(&[], &ci, Krt::Rvul, &["cAyaka"]); + + assert_has_krdanta(&[], &lu, Krt::lyuw, &["lavana"]); + assert_has_krdanta(&[], &lu, Krt::Rvul, &["lAvaka"]); +} + #[test] fn sutra_6_4_78() { let iz = d("izu~", Tudadi); @@ -967,22 +1061,18 @@ fn sutra_6_4_78() { assert_has_lat(&[], &d("f\\", Juhotyadi), &["iyarti"]); // asavarRe - assert_has_tinanta(&[], &iz, Lit, Prathama, Dvi, &["IzatuH"]); - assert_has_tinanta(&[], &iz, Lit, Prathama, Bahu, &["IzuH"]); - assert_has_tinanta( + assert_has_tas(&[], &iz, Lit, &["IzatuH"]); + assert_has_jhi(&[], &iz, Lit, &["IzuH"]); + assert_has_tas( &[], &uz, Lit, - Prathama, - Dvi, &["UzatuH", "ozAYcakratuH", "ozAmAsatuH", "ozAmbaBUvatuH"], ); - assert_has_tinanta( + assert_has_jhi( &[], &uz, Lit, - Prathama, - Bahu, &["UzuH", "ozAYcakruH", "ozAmAsuH", "ozAmbaBUvuH"], ); @@ -1009,13 +1099,25 @@ fn sutra_6_4_80() { #[test] fn sutra_6_4_81() { let i = d("i\\R", Adadi); - assert_has_tinanta(&[], &i, Lat, Prathama, Bahu, &["yanti"]); - assert_has_tinanta(&[], &i, Lot, Prathama, Bahu, &["yantu"]); - assert_has_tinanta(&[], &i, Lan, Prathama, Bahu, &["Ayan"]); + assert_has_tinantas(&[], &i, Lat, Prathama, Bahu, &["yanti"]); + assert_has_tinantas(&[], &i, Lot, Prathama, Bahu, &["yantu"]); + assert_has_tinantas(&[], &i, Lan, Prathama, Bahu, &["Ayan"]); assert_has_krdanta(&[], &i, Krt::lyuw, &["ayana"]); assert_has_krdanta(&[], &i, Krt::Rvul, &["Ayaka"]); } +#[ignore] +#[test] +fn sutra_6_4_82() { + let ni = d("RI\\Y", Bhvadi); + assert_has_tas(&[], &ni, Lit, &["ninyatuH"]); + assert_has_jhi(&[], &ni, Lit, &["ninyuH"]); + + let unni = create_krdanta("unnI", &["ud"], &ni, Krt::kvip); + assert_has_sup_1d(&unni, Pum, &["unnyO"]); + assert_has_sup_1p(&unni, Pum, &["unnyaH"]); +} + #[ignore] #[test] fn sutra_6_4_83() { @@ -1036,6 +1138,30 @@ fn sutra_6_4_83() { // TODO: luvO, luvaH, etc. } +#[test] +fn sutra_6_4_84() { + assert_has_sup_1d("varzABU", Pum, &["varzABvO"]); + assert_has_sup_1p("varzABU", Pum, &["varzABvaH"]); +} + +#[test] +fn sutra_6_4_84_v1() { + let punarbhu = create_bahuvrihi("punarBU", "punar", "BU"); + assert_has_sup_1d(&punarbhu, Stri, &["punarBvO"]); + assert_has_sup_1p(&punarbhu, Stri, &["punarBvaH"]); + + let karabhu = create_bahuvrihi("kAraBU", "kAra", "BU"); + assert_has_sup_1d(&karabhu, Stri, &["kAraBvO"]); + assert_has_sup_1p(&karabhu, Stri, &["kAraBvaH"]); +} + +#[test] +fn sutra_6_4_85() { + let pratibhu = create_upapada_krdanta("pratiBU", "prati", &[], &d("BU", Bhvadi), Krt::kvip); + assert_has_sup_1d(&pratibhu, Stri, &["pratiBuvO"]); + assert_has_sup_1p(&pratibhu, Stri, &["pratiBuvaH"]); +} + #[test] fn sutra_6_4_88() { let bhu = d("BU", Bhvadi); @@ -1367,16 +1493,16 @@ fn sutra_6_4_113() { #[test] fn sutra_6_4_114() { let daridra = d("daridrA", Adadi); - assert_has_tinanta(&[], &daridra, Lat, Prathama, Dvi, &["daridritaH"]); - assert_has_tinanta(&[], &daridra, Lat, Madhyama, Dvi, &["daridriTaH"]); - assert_has_tinanta(&[], &daridra, Lat, Uttama, Dvi, &["daridrivaH"]); - assert_has_tinanta(&[], &daridra, Lat, Uttama, Bahu, &["daridrimaH"]); + assert_has_tinantas(&[], &daridra, Lat, Prathama, Dvi, &["daridritaH"]); + assert_has_tinantas(&[], &daridra, Lat, Madhyama, Dvi, &["daridriTaH"]); + assert_has_tinantas(&[], &daridra, Lat, Uttama, Dvi, &["daridrivaH"]); + assert_has_tinantas(&[], &daridra, Lat, Uttama, Bahu, &["daridrimaH"]); // hali - assert_has_tinanta(&[], &daridra, Lat, Prathama, Bahu, &["daridrati"]); + assert_has_tinantas(&[], &daridra, Lat, Prathama, Bahu, &["daridrati"]); // kNiti - assert_has_tinanta(&[], &daridra, Lat, Prathama, Eka, &["daridrAti"]); + assert_has_tinantas(&[], &daridra, Lat, Prathama, Eka, &["daridrAti"]); } #[test] @@ -1400,16 +1526,16 @@ fn sutra_6_4_115() { #[test] fn sutra_6_4_116() { let haa = d("o~hA\\k", Juhotyadi); - assert_has_tinanta(&[], &haa, Lat, Prathama, Dvi, &["jahitaH", "jahItaH"]); - assert_has_tinanta(&[], &haa, Lat, Madhyama, Dvi, &["jahiTaH", "jahITaH"]); - assert_has_tinanta(&[], &haa, Lat, Uttama, Dvi, &["jahivaH", "jahIvaH"]); - assert_has_tinanta(&[], &haa, Lat, Uttama, Bahu, &["jahimaH", "jahImaH"]); + assert_has_tinantas(&[], &haa, Lat, Prathama, Dvi, &["jahitaH", "jahItaH"]); + assert_has_tinantas(&[], &haa, Lat, Madhyama, Dvi, &["jahiTaH", "jahITaH"]); + assert_has_tinantas(&[], &haa, Lat, Uttama, Dvi, &["jahivaH", "jahIvaH"]); + assert_has_tinantas(&[], &haa, Lat, Uttama, Bahu, &["jahimaH", "jahImaH"]); // hali - assert_has_tinanta(&[], &haa, Lat, Prathama, Bahu, &["jahati"]); + assert_has_tinantas(&[], &haa, Lat, Prathama, Bahu, &["jahati"]); // kNiti - assert_has_tinanta(&[], &haa, Lat, Prathama, Eka, &["jahAti"]); + assert_has_tinantas(&[], &haa, Lat, Prathama, Eka, &["jahAti"]); // sArvadhAtuke assert_has_ta_k(&[], &haa, Lat, &["hIyate"]); @@ -1419,7 +1545,7 @@ fn sutra_6_4_116() { #[test] fn sutra_6_4_117() { let haa = d("o~hA\\k", Juhotyadi); - assert_has_tinanta( + assert_has_tinantas( &[], &haa, Lot, @@ -1432,9 +1558,9 @@ fn sutra_6_4_117() { #[test] fn sutra_6_4_118() { let haa = d("o~hA\\k", Juhotyadi); - assert_has_tinanta(&[], &haa, VidhiLin, Prathama, Eka, &["jahyAt"]); - assert_has_tinanta(&[], &haa, VidhiLin, Prathama, Dvi, &["jahyAtAm"]); - assert_has_tinanta(&[], &haa, VidhiLin, Prathama, Bahu, &["jahyuH"]); + assert_has_tinantas(&[], &haa, VidhiLin, Prathama, Eka, &["jahyAt"]); + assert_has_tinantas(&[], &haa, VidhiLin, Prathama, Dvi, &["jahyAtAm"]); + assert_has_tinantas(&[], &haa, VidhiLin, Prathama, Bahu, &["jahyuH"]); } #[test] @@ -1637,19 +1763,49 @@ fn sutra_6_4_126() { assert_has_sip(&[], &d("pUY", Kryadi), Lit, &["pupaviTa"]); } +#[ignore] +#[test] +fn sutra_6_4_130() { + let dvipad = create_bahuvrihi("dvipAd", "dvi", "pAda"); + assert_has_sup_2p(&dvipad, Pum, &["dvipadaH"]); + assert_has_sup_3s(&dvipad, Pum, &["dvipadA"]); + assert_has_sup_4s(&dvipad, Pum, &["dvipade"]); + + let tripad = create_bahuvrihi("tripAd", "tri", "pAda"); + let vyaghrapad = create_bahuvrihi("vyAGrapad", "vyAGra", "pAda"); + assert_has_taddhita(&dvipad, T::vun, &["dvipadika"]); + assert_has_taddhita(&tripad, T::vun, &["tripadika"]); + assert_has_taddhita(&vyaghrapad, T::yak, &["vEyAGrapadya"]); +} + #[ignore] #[test] fn sutra_6_4_131() { - assert_has_sup_6s("vidvas", Pum, &["viduzaH"]); + assert_has_sup_2p("vidvas", Pum, &["viduzaH"]); assert_has_sup_3s("vidvas", Pum, &["viduzA"]); assert_has_sup_4s("vidvas", Pum, &["viduze"]); - assert_has_sup_6s("pecivas", Pum, &["pecuzaH"]); + assert_has_sup_2p("pecivas", Pum, &["pecuzaH"]); assert_has_sup_3s("pecivas", Pum, &["pecuzA"]); assert_has_sup_4s("pecivas", Pum, &["pecuze"]); assert_has_sup_6s("papivas", Pum, &["papuzaH"]); } +#[test] +fn sutra_6_4_132() { + let vah = d("va\\ha~^", Bhvadi); + + let prasthavah = create_krdanta("prazWavAh", &["prazWa"], &vah, Krt::Rvi); + assert_has_sup_2p(&prasthavah, Pum, &["prazWOhaH"]); + assert_has_sup_3s(&prasthavah, Pum, &["prazWOhA"]); + assert_has_sup_4s(&prasthavah, Pum, &["prazWOhe"]); + + let dityavah = create_krdanta("dityavAh", &["ditya"], &vah, Krt::Rvi); + assert_has_sup_2p(&dityavah, Pum, &["dityOhaH"]); + assert_has_sup_3s(&dityavah, Pum, &["dityOhA"]); + assert_has_sup_4s(&dityavah, Pum, &["dityOhe"]); +} + #[test] fn sutra_6_4_133() { assert_has_sup_6s("Svan", Pum, &["SunaH"]); @@ -1665,9 +1821,9 @@ fn sutra_6_4_133() { assert_has_sup_4s("maGavan", Pum, &["maGone"]); // atadDite? - assert_has_taddhitanta("Svan", T::aY, &["SOva"]); - assert_has_taddhitanta("yuvan", T::aR, &["yOvana"]); - assert_has_taddhitanta("maGavan", T::aR, &["mAGavana"]); + assert_has_taddhita("Svan", T::aY, &["SOva"]); + assert_has_taddhita("yuvan", T::aR, &["yOvana"]); + assert_has_taddhita("maGavan", T::aR, &["mAGavana"]); // TODO: others } @@ -1720,6 +1876,19 @@ fn sutra_6_4_137() { assert_has_sup_4s("takzan", Pum, &["takzRe"]); } +#[test] +fn sutra_6_4_138() { + let dadhyac = create_upapada_krdanta("daDyac", "daDi", &[], &d("ancu~", Bhvadi), Krt::kvin); + assert_has_sup_2p(&dadhyac, Pum, &["daDIcaH"]); + assert_has_sup_3s(&dadhyac, Pum, &["daDIcA"]); + assert_has_sup_4s(&dadhyac, Pum, &["daDIce"]); + + let madhvac = create_upapada_krdanta("maDvac", "maDu", &[], &d("ancu~", Bhvadi), Krt::kvin); + assert_has_sup_2p(&madhvac, Pum, &["maDUcaH"]); + assert_has_sup_3s(&madhvac, Pum, &["maDUcA"]); + assert_has_sup_4s(&madhvac, Pum, &["maDUce"]); +} + #[test] fn sutra_6_4_140() { let kilalapa = create_upapada_krdanta("kilAlapA", "kilAla", &[], &d("pA\\", Adadi), Krt::vic); @@ -1734,7 +1903,7 @@ fn sutra_6_4_140() { assert_has_sup_4s(&shubhamya, Pum, &["SuBaMye"]); // AtaH? - let ni = dhatu_prati("nI"); + let ni = create_krdanta("nI", &[], &d("RI\\Y", Bhvadi), Krt::kvip); assert_has_sup_3s(&ni, Pum, &["niyA"]); assert_has_sup_4s(&ni, Pum, &["niye"]); @@ -1746,8 +1915,8 @@ fn sutra_6_4_140() { #[ignore] #[test] fn sutra_6_4_142() { - assert_has_taddhitanta(&prati("viMSati"), T::qvun, &["viMSaka"]); - // TODO: assert_has_taddhitanta(&prati("viMSati"), T::waq, &["viMSa"]); + assert_has_taddhita("viMSati", T::qvun, &["viMSaka"]); + // TODO: assert_has_taddhitanta("viMSati", T::waq, &["viMSa"]); // qiti? assert_has_sup_3s("viMSati", Pum, &["viMSatyA"]); @@ -1756,17 +1925,17 @@ fn sutra_6_4_142() { #[ignore] #[test] fn sutra_6_4_143() { - assert_has_taddhitanta("kumuda", T::qmatup, &["kumudvat"]); - assert_has_taddhitanta("naqa", T::qmatup, &["naqvat"]); - assert_has_taddhitanta("vetasa", T::qmatup, &["vetasvat"]); + assert_has_taddhita("kumuda", T::qmatup, &["kumudvat"]); + assert_has_taddhita("naqa", T::qmatup, &["naqvat"]); + assert_has_taddhita("vetasa", T::qmatup, &["vetasvat"]); // TODO: others - assert_has_taddhitanta("triMSat", T::qvun, &["triMSaka"]); + assert_has_taddhita("triMSat", T::qvun, &["triMSaka"]); } #[test] fn sutra_6_4_144() { - assert_has_taddhitanta("agniSarman", T::iY, &["AgniSarmi"]); - assert_has_taddhitanta("uquloman", T::iY, &["Oqulomi"]); + assert_has_taddhita("agniSarman", T::iY, &["AgniSarmi"]); + assert_has_taddhita("uquloman", T::iY, &["Oqulomi"]); // naH? // taddhite? @@ -1776,185 +1945,222 @@ fn sutra_6_4_144() { #[test] fn sutra_6_4_144_v1() { - assert_has_taddhitanta("sabrahmacArin", T::aR, &["sAbrahmacAra"]); - assert_has_taddhitanta("pIWasarpin", T::aR, &["pEWasarpa"]); - assert_has_taddhitanta("kalApin", T::aR, &["kAlApa"]); - assert_has_taddhitanta("kuTumin", T::aR, &["kOTuma"]); - assert_has_taddhitanta("tEtilin", T::aR, &["tEtila"]); - assert_has_taddhitanta("jAjalin", T::aR, &["jAjala"]); - assert_has_taddhitanta("lANgalin", T::aR, &["lANgala"]); - assert_has_taddhitanta("SilAlin", T::aR, &["SElAla"]); - assert_has_taddhitanta("SiKaRqin", T::aR, &["SEKaRqa"]); - assert_has_taddhitanta("sukarasadman", T::aR, &["sOkarasadma"]); - assert_has_taddhitanta("suparvan", T::aR, &["sOparva"]); + assert_has_taddhita("sabrahmacArin", T::aR, &["sAbrahmacAra"]); + assert_has_taddhita("pIWasarpin", T::aR, &["pEWasarpa"]); + assert_has_taddhita("kalApin", T::aR, &["kAlApa"]); + assert_has_taddhita("kuTumin", T::aR, &["kOTuma"]); + assert_has_taddhita("tEtilin", T::aR, &["tEtila"]); + assert_has_taddhita("jAjalin", T::aR, &["jAjala"]); + assert_has_taddhita("lANgalin", T::aR, &["lANgala"]); + assert_has_taddhita("SilAlin", T::aR, &["SElAla"]); + assert_has_taddhita("SiKaRqin", T::aR, &["SEKaRqa"]); + assert_has_taddhita("sukarasadman", T::aR, &["sOkarasadma"]); + assert_has_taddhita("suparvan", T::aR, &["sOparva"]); } #[test] fn sutra_6_4_146() { - assert_has_taddhitanta("baBru", T::yaY, &["bABravya"]); - assert_has_taddhitanta("maRqu", T::yaY, &["mARqavya"]); - assert_has_taddhitanta("SaNku", T::yat, &["SaNkavya"]); - assert_has_taddhitanta("picu", T::yat, &["picavya"]); - assert_has_taddhitanta("kamaRqalu", T::yat, &["kamaRqalavya"]); - assert_has_taddhitanta("upagu", T::aR, &["Opagava"]); - assert_has_taddhitanta("kapawu", T::aR, &["kApawava"]); + assert_has_taddhita("baBru", T::yaY, &["bABravya"]); + assert_has_taddhita("maRqu", T::yaY, &["mARqavya"]); + assert_has_taddhita("SaNku", T::yat, &["SaNkavya"]); + assert_has_taddhita("picu", T::yat, &["picavya"]); + assert_has_taddhita("kamaRqalu", T::yat, &["kamaRqalavya"]); + assert_has_taddhita("upagu", T::aR, &["Opagava"]); + assert_has_taddhita("kapawu", T::aR, &["kApawava"]); // TODO: svAyamBuva } +#[test] +fn sutra_6_4_147() { + assert_has_taddhita("kamaRqalu", T::QaY, &["kAmaRqaleya"]); + // TODO: what is the pratipadika here? + assert_has_taddhita("SItabAhu", T::QaY, &["SEtabAheya"]); + assert_has_taddhita("jambu", T::QaY, &["jAmbeya"]); + + let madrabahu = create_bahuvrihi("madrabAhu", "madra", "bAhu").with_stri(true); + assert_has_taddhita(&madrabahu, T::Qak, &["mAdrabAheya"]); + + // a-kadrvAH? + assert_has_taddhita(&nyap("kadrU"), T::Qak, &["kAdraveya"]); +} + +#[ignore] +#[test] +fn sutra_6_4_149() { + assert_has_taddhita("sUrya", T::aR, &["sOra"]); + assert_has_taddhita("tizya", T::aR, &["tEza"]); + assert_has_taddhita("agastya", T::aR, &["Agasta"]); + assert_has_taddhita("agastya", T::Ka, &["AgastIya"]); + assert_has_sup_1s("matsya", Stri, &["matsI"]); +} + #[test] fn sutra_6_4_155() { - assert_has_taddhitanta("pawu", T::izWan, &["pawizWa"]); - assert_has_taddhitanta("pawu", T::imanic, &["pawiman"]); - assert_has_taddhitanta("pawu", T::Iyasun, &["pawIyas"]); + assert_has_taddhita("pawu", T::izWan, &["pawizWa"]); + assert_has_taddhita("pawu", T::imanic, &["pawiman"]); + assert_has_taddhita("pawu", T::Iyasun, &["pawIyas"]); - assert_has_taddhitanta("laGu", T::izWan, &["laGizWa"]); - assert_has_taddhitanta("laGu", T::imanic, &["laGiman"]); - assert_has_taddhitanta("laGu", T::Iyasun, &["laGIyas"]); + assert_has_taddhita("laGu", T::izWan, &["laGizWa"]); + assert_has_taddhita("laGu", T::imanic, &["laGiman"]); + assert_has_taddhita("laGu", T::Iyasun, &["laGIyas"]); } #[test] fn sutra_6_4_156() { - assert_has_taddhitanta("sTUla", T::izWan, &["sTavizWa"]); - assert_has_taddhitanta("sTUla", T::Iyasun, &["sTavIyas"]); + assert_has_taddhita("sTUla", T::izWan, &["sTavizWa"]); + assert_has_taddhita("sTUla", T::Iyasun, &["sTavIyas"]); - assert_has_taddhitanta("dUra", T::izWan, &["davizWa"]); - assert_has_taddhitanta("dUra", T::Iyasun, &["davIyas"]); + assert_has_taddhita("dUra", T::izWan, &["davizWa"]); + assert_has_taddhita("dUra", T::Iyasun, &["davIyas"]); // kanizWa and kanIyas are by 5.3.64. - assert_has_taddhitanta("yuvan", T::izWan, &["yavizWa", "kanizWa"]); - assert_has_taddhitanta("yuvan", T::Iyasun, &["yavIyas", "kanIyas"]); + assert_has_taddhita("yuvan", T::izWan, &["yavizWa", "kanizWa"]); + assert_has_taddhita("yuvan", T::Iyasun, &["yavIyas", "kanIyas"]); - assert_has_taddhitanta("hrasva", T::izWan, &["hrasizWa"]); - assert_has_taddhitanta("hrasva", T::imanic, &["hrasiman"]); - assert_has_taddhitanta("hrasva", T::Iyasun, &["hrasIyas"]); + assert_has_taddhita("hrasva", T::izWan, &["hrasizWa"]); + assert_has_taddhita("hrasva", T::imanic, &["hrasiman"]); + assert_has_taddhita("hrasva", T::Iyasun, &["hrasIyas"]); - assert_has_taddhitanta("kzipra", T::izWan, &["kzepizWa"]); - assert_has_taddhitanta("kzipra", T::imanic, &["kzepiman"]); - assert_has_taddhitanta("kzipra", T::Iyasun, &["kzepIyas"]); + assert_has_taddhita("kzipra", T::izWan, &["kzepizWa"]); + assert_has_taddhita("kzipra", T::imanic, &["kzepiman"]); + assert_has_taddhita("kzipra", T::Iyasun, &["kzepIyas"]); - assert_has_taddhitanta("kzudra", T::izWan, &["kzodizWa"]); - assert_has_taddhitanta("kzudra", T::imanic, &["kzodiman"]); - assert_has_taddhitanta("kzudra", T::Iyasun, &["kzodIyas"]); + assert_has_taddhita("kzudra", T::izWan, &["kzodizWa"]); + assert_has_taddhita("kzudra", T::imanic, &["kzodiman"]); + assert_has_taddhita("kzudra", T::Iyasun, &["kzodIyas"]); } #[test] fn sutra_6_4_157() { - assert_has_taddhitanta("priya", T::izWan, &["prezWa"]); - assert_has_taddhitanta("priya", T::imanic, &["preman"]); - assert_has_taddhitanta("priya", T::Iyasun, &["preyas"]); + assert_has_taddhita("priya", T::izWan, &["prezWa"]); + assert_has_taddhita("priya", T::imanic, &["preman"]); + assert_has_taddhita("priya", T::Iyasun, &["preyas"]); - assert_has_taddhitanta("sTira", T::izWan, &["sTezWa"]); - assert_has_taddhitanta("sTira", T::imanic, &[]); - assert_has_taddhitanta("sTira", T::Iyasun, &["sTeyas"]); + assert_has_taddhita("sTira", T::izWan, &["sTezWa"]); + assert_has_taddhita("sTira", T::imanic, &[]); + assert_has_taddhita("sTira", T::Iyasun, &["sTeyas"]); - assert_has_taddhitanta("sPira", T::izWan, &["sPezWa"]); - assert_has_taddhitanta("sPira", T::imanic, &[]); - assert_has_taddhitanta("sPira", T::Iyasun, &["sPeyas"]); + assert_has_taddhita("sPira", T::izWan, &["sPezWa"]); + assert_has_taddhita("sPira", T::imanic, &[]); + assert_has_taddhita("sPira", T::Iyasun, &["sPeyas"]); - assert_has_taddhitanta("uru", T::izWan, &["varizWa"]); - assert_has_taddhitanta("uru", T::imanic, &["variman"]); - assert_has_taddhitanta("uru", T::Iyasun, &["varIyas"]); + assert_has_taddhita("uru", T::izWan, &["varizWa"]); + assert_has_taddhita("uru", T::imanic, &["variman"]); + assert_has_taddhita("uru", T::Iyasun, &["varIyas"]); - assert_has_taddhitanta("bahula", T::izWan, &["baMhizWa"]); - assert_has_taddhitanta("bahula", T::imanic, &["baMhiman"]); - assert_has_taddhitanta("bahula", T::Iyasun, &["baMhIyas"]); + assert_has_taddhita("bahula", T::izWan, &["baMhizWa"]); + assert_has_taddhita("bahula", T::imanic, &["baMhiman"]); + assert_has_taddhita("bahula", T::Iyasun, &["baMhIyas"]); - assert_has_taddhitanta("guru", T::izWan, &["garizWa"]); - assert_has_taddhitanta("guru", T::imanic, &["gariman"]); - assert_has_taddhitanta("guru", T::Iyasun, &["garIyas"]); + assert_has_taddhita("guru", T::izWan, &["garizWa"]); + assert_has_taddhita("guru", T::imanic, &["gariman"]); + assert_has_taddhita("guru", T::Iyasun, &["garIyas"]); // jyezWa and jyAyas are by 5.3.62. - assert_has_taddhitanta("vfdDa", T::izWan, &["varzizWa", "jyezWa"]); - assert_has_taddhitanta("vfdDa", T::imanic, &[]); - assert_has_taddhitanta("vfdDa", T::Iyasun, &["varzIyas", "jyAyas"]); + assert_has_taddhita("vfdDa", T::izWan, &["varzizWa", "jyezWa"]); + assert_has_taddhita("vfdDa", T::imanic, &[]); + assert_has_taddhita("vfdDa", T::Iyasun, &["varzIyas", "jyAyas"]); - assert_has_taddhitanta("tfpra", T::izWan, &["trapizWa"]); - assert_has_taddhitanta("tfpra", T::imanic, &[]); - assert_has_taddhitanta("tfpra", T::Iyasun, &["trapIyas"]); + assert_has_taddhita("tfpra", T::izWan, &["trapizWa"]); + assert_has_taddhita("tfpra", T::imanic, &[]); + assert_has_taddhita("tfpra", T::Iyasun, &["trapIyas"]); - assert_has_taddhitanta("dIrGa", T::izWan, &["drAGizWa"]); - assert_has_taddhitanta("dIrGa", T::imanic, &["drAGiman"]); - assert_has_taddhitanta("dIrGa", T::Iyasun, &["drAGIyas"]); + assert_has_taddhita("dIrGa", T::izWan, &["drAGizWa"]); + assert_has_taddhita("dIrGa", T::imanic, &["drAGiman"]); + assert_has_taddhita("dIrGa", T::Iyasun, &["drAGIyas"]); - assert_has_taddhitanta("vfndAraka", T::izWan, &["vfndizWa"]); - assert_has_taddhitanta("vfndAraka", T::imanic, &[]); - assert_has_taddhitanta("vfndAraka", T::Iyasun, &["vfndIyas"]); + assert_has_taddhita("vfndAraka", T::izWan, &["vfndizWa"]); + assert_has_taddhita("vfndAraka", T::imanic, &[]); + assert_has_taddhita("vfndAraka", T::Iyasun, &["vfndIyas"]); } #[test] fn sutra_6_4_158() { - assert_has_taddhitanta("bahu", T::imanic, &["BUman"]); - assert_has_taddhitanta("bahu", T::Iyasun, &["BUyas"]); + assert_has_taddhita("bahu", T::imanic, &["BUman"]); + assert_has_taddhita("bahu", T::Iyasun, &["BUyas"]); } #[test] fn sutra_6_4_159() { - assert_has_taddhitanta("bahu", T::izWan, &["BUyizWa"]); + assert_has_taddhita("bahu", T::izWan, &["BUyizWa"]); } #[test] fn sutra_6_4_160() { - assert_has_taddhitanta("jya", T::Iyasun, &["jyAyas"]); + assert_has_taddhita("jya", T::Iyasun, &["jyAyas"]); } #[test] fn sutra_6_4_161() { - assert_has_taddhitanta("pfTu", T::izWan, &["praTizWa"]); - assert_has_taddhitanta("pfTu", T::imanic, &["praTiman"]); - assert_has_taddhitanta("pfTu", T::Iyasun, &["praTIyas"]); + assert_has_taddhita("pfTu", T::izWan, &["praTizWa"]); + assert_has_taddhita("pfTu", T::imanic, &["praTiman"]); + assert_has_taddhita("pfTu", T::Iyasun, &["praTIyas"]); - assert_has_taddhitanta("mfdu", T::izWan, &["mradizWa"]); - assert_has_taddhitanta("mfdu", T::imanic, &["mradiman"]); - assert_has_taddhitanta("mfdu", T::Iyasun, &["mradIyas"]); + assert_has_taddhita("mfdu", T::izWan, &["mradizWa"]); + assert_has_taddhita("mfdu", T::imanic, &["mradiman"]); + assert_has_taddhita("mfdu", T::Iyasun, &["mradIyas"]); // ftaH? - assert_has_taddhitanta("pawu", T::izWan, &["pawizWa"]); - assert_has_taddhitanta("pawu", T::imanic, &["pawiman"]); - assert_has_taddhitanta("pawu", T::Iyasun, &["pawIyas"]); + assert_has_taddhita("pawu", T::izWan, &["pawizWa"]); + assert_has_taddhita("pawu", T::imanic, &["pawiman"]); + assert_has_taddhita("pawu", T::Iyasun, &["pawIyas"]); // halAdeH? - assert_has_taddhitanta("fju", T::izWan, &["fjizWa"]); - assert_has_taddhitanta("fju", T::imanic, &["fjiman"]); - assert_has_taddhitanta("fju", T::Iyasun, &["fjIyas"]); + assert_has_taddhita("fju", T::izWan, &["fjizWa"]); + assert_has_taddhita("fju", T::imanic, &["fjiman"]); + assert_has_taddhita("fju", T::Iyasun, &["fjIyas"]); // laGoH? - assert_has_taddhitanta("kfzRA", T::izWan, &["kfzRizWa"]); + assert_has_taddhita("kfzRA", T::izWan, &["kfzRizWa"]); // TODO: assert_has_taddhitanta("kfzRA", T::imanic, &["kfzRiman"]); - assert_has_taddhitanta("kfzRA", T::Iyasun, &["kfzRIyas"]); + assert_has_taddhita("kfzRA", T::Iyasun, &["kfzRIyas"]); // TODO: others } #[test] fn sutra_6_4_164() { - assert_has_taddhitanta("saNkUwin", T::aR, &["sANkUwina"]); - assert_has_taddhitanta("saMrAvin", T::aR, &["sAMrAviRa"]); - assert_has_taddhitanta("sammArjin", T::aR, &["sAmmArjina"]); - assert_has_taddhitanta("sragvin", T::aR, &["srAgviRa"]); + assert_has_taddhita("saNkUwin", T::aR, &["sANkUwina"]); + assert_has_taddhita("saMrAvin", T::aR, &["sAMrAviRa"]); + assert_has_taddhita("sammArjin", T::aR, &["sAmmArjina"]); + assert_has_taddhita("sragvin", T::aR, &["srAgviRa"]); // aRi? - assert_has_taddhitanta("daRqin", T::aY, &["dARqa"]); + assert_has_taddhita("daRqin", T::aY, &["dARqa"]); } #[test] fn sutra_6_4_165() { - assert_has_taddhitanta("gATin", T::aR, &["gATina"]); - assert_has_taddhitanta("vidaTin", T::aR, &["vEdaTina"]); - assert_has_taddhitanta("keSin", T::aR, &["kESina"]); - assert_has_taddhitanta("gaRin", T::aR, &["gARina"]); - assert_has_taddhitanta("paRin", T::aR, &["pARina"]); + assert_has_taddhita("gATin", T::aR, &["gATina"]); + assert_has_taddhita("vidaTin", T::aR, &["vEdaTina"]); + assert_has_taddhita("keSin", T::aR, &["kESina"]); + assert_has_taddhita("gaRin", T::aR, &["gARina"]); + assert_has_taddhita("paRin", T::aR, &["pARina"]); } #[test] fn sutra_6_4_166() { - assert_has_taddhitanta("SaNKin", T::aR, &["SANKina"]); - assert_has_taddhitanta("madrin", T::aR, &["mAdriRa"]); - assert_has_taddhitanta("vajrin", T::aR, &["vAjriRa"]); + assert_has_taddhita("SaNKin", T::aR, &["SANKina"]); + assert_has_taddhita("madrin", T::aR, &["mAdriRa"]); + assert_has_taddhita("vajrin", T::aR, &["vAjriRa"]); } #[test] fn sutra_6_4_167() { - assert_has_taddhitanta("sAman", T::aR, &["sAmana"]); - assert_has_taddhitanta("veman", T::aR, &["vEmana"]); - assert_has_taddhitanta("sutvan", T::aR, &["sOtvana"]); - assert_has_taddhitanta("jitvan", T::aR, &["jEtvana"]); + assert_has_taddhita("sAman", T::aR, &["sAmana"]); + assert_has_taddhita("veman", T::aR, &["vEmana"]); + assert_has_taddhita("sutvan", T::aR, &["sOtvana"]); + assert_has_taddhita("jitvan", T::aR, &["jEtvana"]); +} + +#[test] +fn sutra_6_4_168() { + assert_has_artha_taddhita("sAman", TatraSadhu, T::yat, &["sAmanya"]); + assert_has_artha_taddhita("veman", TatraSadhu, T::yat, &["vemanya"]); + // TODO: rAjya +} + +#[test] +fn sutra_6_4_169() { + assert_has_artha_taddhita("Atman", TasmaiHitam, T::Ka, &["AtmanIna"]); + assert_has_artha_taddhita("aDvan", AlamGami, T::Ka, &["aDvanIna"]); } diff --git a/vidyut-prakriya/tests/kashika_7_1.rs b/vidyut-prakriya/tests/kashika_7_1.rs index 3dfa7ea..30ed472 100644 --- a/vidyut-prakriya/tests/kashika_7_1.rs +++ b/vidyut-prakriya/tests/kashika_7_1.rs @@ -4,6 +4,7 @@ use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; +use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::*; #[test] @@ -24,14 +25,14 @@ fn sutra_7_1_1() { #[test] fn sutra_7_1_2() { use Taddhita as T; - assert_has_taddhitanta(&prati("naqa"), T::Pak, &["nAqAyana"]); - assert_has_taddhitanta(&prati("cara"), T::Pak, &["cArAyaRa"]); - assert_has_taddhitanta(&nyap("suparRA"), T::Qak, &["sOparReya"]); - assert_has_taddhitanta(&nyap("vinatA"), T::Qak, &["vEnateya"]); - assert_has_taddhitanta(&prati("kula"), T::Ka, &["kulIna"]); - assert_has_taddhitanta(&prati("gArga"), T::Ca, &["gArgIya"]); - assert_has_taddhitanta(&prati("vAtsa"), T::Ca, &["vAtsIya"]); - assert_has_taddhitanta(&prati("kzatra"), T::Ga, &["kzatriya"]); + assert_has_taddhita("naqa", T::Pak, &["nAqAyana"]); + assert_has_taddhita("cara", T::Pak, &["cArAyaRa"]); + assert_has_taddhita(&nyap("suparRA"), T::Qak, &["sOparReya"]); + assert_has_taddhita(&nyap("vinatA"), T::Qak, &["vEnateya"]); + assert_has_taddhita("kula", T::Ka, &["kulIna"]); + assert_has_taddhita("gArga", T::Ca, &["gArgIya"]); + assert_has_taddhita("vAtsa", T::Ca, &["vAtsIya"]); + assert_has_taddhita("kzatra", T::Ga, &["kzatriya"]); // pratyayagrahanam assert_has_lat(&[], &d("Pakka~", Bhvadi), &["Pakkati"]); @@ -248,7 +249,6 @@ fn sutra_7_1_21() { assert_has_sup_2p("azwan", Pum, &["azwO"]); } -#[ignore] #[test] fn sutra_7_1_22() { assert_has_sup_1p("zaz", Pum, &["zaw"]); @@ -275,7 +275,6 @@ fn sutra_7_1_24() { assert_has_sup_2s("kuRqa", Napumsaka, &["kuRqam"]); } -#[ignore] #[test] fn sutra_7_1_25() { assert_has_sup_1s("katara", Napumsaka, &["katarat"]); @@ -391,7 +390,6 @@ fn sutra_7_1_37() { // 7.1.38 - 7.1.50 are chAndasa. -#[ignore] #[test] fn sutra_7_1_52() { assert_has_sup_6p("sarva", Pum, &["sarvezAm"]); @@ -406,7 +404,6 @@ fn sutra_7_1_52() { assert_has_sup_6p("Bavat", Pum, &["BavatAm"]); } -#[ignore] #[test] fn sutra_7_1_53() { assert_has_sup_6p("tri", Pum, &["trayARAm"]); @@ -432,7 +429,6 @@ fn sutra_7_1_54() { assert_has_sup_6p(&nyap("kArIzaganDyA"), Stri, &["kArIzaganDyAnAm"]); } -#[ignore] #[test] fn sutra_7_1_55() { assert_has_sup_6p("zaz", Pum, &["zaRRAm"]); @@ -513,7 +509,7 @@ fn sutra_7_1_61() { let jabh = d("jaBI~\\", Bhvadi); assert_has_tip( &[], - &radh.clone().with_sanadi(&[Sanadi::Nic]), + &radh.clone().with_sanadi(&[Sanadi::Ric]), Lat, &["ranDayati"], ); @@ -524,7 +520,7 @@ fn sutra_7_1_61() { assert_has_tip( &[], - &jabh.clone().with_sanadi(&[Sanadi::Nic]), + &jabh.clone().with_sanadi(&[Sanadi::Ric]), Lat, &["jamBayati"], ); @@ -651,6 +647,54 @@ fn sutra_7_1_69() { assert_has_krdanta(&["pra"], &labh, Krt::Ramul, &["pralamBam"]); } +#[test] +fn sutra_7_1_70() { + let bhavat = create_krdanta("Bavat", &[], &d("BA\\", Adadi), Unadi::qavatu); + assert_has_sup_1s(&bhavat, Pum, &["BavAn"]); + assert_has_sup_1d(&bhavat, Pum, &["BavantO"]); + assert_has_sup_1p(&bhavat, Pum, &["BavantaH"]); + + let shreyas = create_taddhitanta("Sreyas", "praSasya", T::Iyasun); + assert_has_sup_1s(&shreyas, Pum, &["SreyAn"]); + assert_has_sup_1d(&shreyas, Pum, &["SreyAMsO"]); + assert_has_sup_1p(&shreyas, Pum, &["SreyAMsaH"]); + + let prac = create_krdanta("prAc", &["pra"], &d("ancu~", Bhvadi), Krt::kvin); + assert_has_sup_1s(&prac, Pum, &["prAN"]); + assert_has_sup_1d(&prac, Pum, &["prAYcO"]); + assert_has_sup_1p(&prac, Pum, &["prAYcaH"]); + + let pacat = create_krdanta("pacat", &[], &d("qupa\\ca~^z", Bhvadi), Krt::Satf); + assert_has_sup_1s(&pacat, Pum, &["pacan"]); + assert_has_sup_1d(&pacat, Pum, &["pacantO"]); + assert_has_sup_1p(&pacat, Pum, &["pacantaH"]); + + // ugidacAm? + assert_has_sup_1s("dfzad", Pum, &["dfzat"]); + assert_has_sup_1d("dfzad", Pum, &["dfzadO"]); + assert_has_sup_1p("dfzad", Pum, &["dfzadaH"]); + + // sarvanAmasthAne? + assert_has_sup_2p(&bhavat, Pum, &["BavataH"]); + assert_has_sup_2p(&shreyas, Pum, &["SreyasaH"]); +} + +#[ignore] +#[test] +fn sutra_7_1_71() { + let yuj = create_krdanta("yuj", &[], &d("yu\\ji~^r", Rudhadi), Krt::kvin); + assert_has_sup_1s(&yuj, Pum, &["yuN"]); + assert_has_sup_1d(&yuj, Pum, &["yuYjO"]); + assert_has_sup_1p(&yuj, Pum, &["yuYjaH"]); + + // asamAse? + let ashvayuj = + create_upapada_krdanta("aSvayuj", "aSva", &[], &d("yu\\ji~^r", Rudhadi), Krt::kvip); + assert_has_sup_1s(&ashvayuj, Pum, &["aSvayuk"]); + assert_has_sup_1d(&ashvayuj, Pum, &["aSvayujO"]); + assert_has_sup_1p(&ashvayuj, Pum, &["aSvayujaH"]); +} + #[test] fn sutra_7_1_72() { assert_has_sup_1p("udaSvit", Napumsaka, &["udaSvinti"]); @@ -693,6 +737,18 @@ fn sutra_7_1_73() { assert_has_sup_1d("pIWa", Napumsaka, &["pIWe"]); } +#[test] +fn sutra_7_1_75() { + assert_has_sup_3s("asTi", Pum, &["asTnA"]); + assert_has_sup_4s("asTi", Pum, &["asTne"]); + assert_has_sup_3s("daDi", Pum, &["daDnA"]); + assert_has_sup_4s("daDi", Pum, &["daDne"]); + assert_has_sup_3s("sakTi", Pum, &["sakTnA"]); + assert_has_sup_4s("sakTi", Pum, &["sakTne"]); + assert_has_sup_3s("akzi", Pum, &["akzRA"]); + assert_has_sup_4s("akzi", Pum, &["akzRe"]); +} + #[test] fn sutra_7_1_78() { let dadat = create_krdanta("dadat", &[], &d("qudA\\Y", Juhotyadi), Krt::Satf); @@ -757,6 +813,12 @@ fn sutra_7_1_81() { assert_has_sup_1s(&sivyat, Stri, &["sIvyantI"]); } +#[test] +fn sutra_7_1_82() { + assert_has_sup_1s("anaquh", Pum, &["anaqvAn"]); + assert_has_sup_ss("anaquh", Pum, &["anaqvan"]); +} + #[test] fn sutra_7_1_84() { assert_has_sup_1s("div", Stri, &["dyOH"]); @@ -845,7 +907,6 @@ fn sutra_7_1_92() { assert_has_sup_ss("saKi", Pum, &["saKe"]); } -#[ignore] #[test] fn sutra_7_1_93() { assert_has_sup_1s("saKi", Pum, &["saKA"]); @@ -853,7 +914,6 @@ fn sutra_7_1_93() { assert_has_sup_ss("saKi", Pum, &["saKe"]); } -#[ignore] #[test] fn sutra_7_1_94() { assert_has_sup_1s("kartf", Pum, &["kartA"]); @@ -874,6 +934,73 @@ fn sutra_7_1_94() { assert_has_sup_ss("uSanas", Pum, &["uSanaH"]); } +#[test] +fn sutra_7_1_95() { + assert_has_sup_1s("krozwu", Pum, &["krozwA"]); + assert_has_sup_1d("krozwu", Pum, &["krozwArO"]); + assert_has_sup_1p("krozwu", Pum, &["krozwAraH"]); + assert_has_sup_2s("krozwu", Pum, &["krozwAram"]); + assert_has_sup_2d("krozwu", Pum, &["krozwArO"]); + assert_has_sup_2p("krozwu", Pum, &["krozwUn"]); + + // asambuddhau? + assert_has_sup_ss("krozwu", Pum, &["krozwo"]); +} + +#[test] +fn sutra_7_1_96() { + // TODO: see KV commentary on whether krozwu is part of gaurAdi. + assert_has_sup_1s("krozwu", Stri, &["krozwrI"]); + assert_has_sup_3d("krozwu", Stri, &["krozwrIByAm"]); + assert_has_sup_3p("krozwu", Stri, &["krozwrIBiH"]); +} + +#[test] +fn sutra_7_1_97() { + assert_has_sup_3s("krozwu", Pum, &["krozwrA", "krozwunA"]); + assert_has_sup_4s("krozwu", Pum, &["krozwre", "krozwave"]); + assert_has_sup_5s("krozwu", Pum, &["krozwuH", "krozwoH"]); + assert_has_sup_7s("krozwu", Pum, &["krozwari", "krozwO"]); + assert_has_sup_7d("krozwu", Pum, &["krozwroH", "krozwvoH"]); + + // tftIyAdizu? + assert_has_sup_2p("krozwu", Pum, &["krozwUn"]); + + // aci? + assert_has_sup_3d("krozwu", Pum, &["krozwuByAm"]); + assert_has_sup_3p("krozwu", Pum, &["krozwuBiH"]); +} + +#[test] +fn sutra_7_1_98() { + assert_has_sup_1p("catur", Pum, &["catvAraH"]); + + assert_has_sup_1s("anaquh", Pum, &["anaqvAn"]); + assert_has_sup_1d("anaquh", Pum, &["anaqvAhO"]); + assert_has_sup_1p("anaquh", Pum, &["anaqvAhaH"]); + assert_has_sup_2s("anaquh", Pum, &["anaqvAham"]); + + // tadantaviDiratra izyate + let priyacatur = create_bahuvrihi("priyacatur", "priya", "catur"); + assert_has_sup_1s(&priyacatur, Pum, &["priyacatvAH"]); + assert_has_sup_1d(&priyacatur, Pum, &["priyacatvArO"]); + assert_has_sup_1p(&priyacatur, Pum, &["priyacatvAraH"]); + + let priyanaduh = create_bahuvrihi("priyAnaquh", "priya", "anaquh"); + assert_has_sup_1s(&priyanaduh, Pum, &["priyAnaqvAn"]); + assert_has_sup_1d(&priyanaduh, Pum, &["priyAnaqvAhO"]); + assert_has_sup_1p(&priyanaduh, Pum, &["priyAnaqvAhaH"]); +} + +#[test] +fn sutra_7_1_99() { + let priyacatur = create_bahuvrihi("priyacatur", "priya", "catur"); + assert_has_sup_ss(&priyacatur, Pum, &["priyacatvaH"]); + + let priyanaduh = create_bahuvrihi("priyAnaquh", "priya", "anaquh"); + assert_has_sup_ss(&priyanaduh, Pum, &["priyAnaqvan"]); +} + #[test] fn sutra_7_1_100() { assert_has_lat(&[], &d("kF", Tudadi), &["kirati"]); @@ -887,12 +1014,15 @@ fn sutra_7_1_101() { assert_has_tip(&[], &d("kFta~", Curadi), Lat, &["kIrtayati"]); } -#[ignore] #[test] fn sutra_7_1_102() { let pf = d("pF", Juhotyadi); assert_has_krdanta(&[], &pf, Krt::kta, &["pUrta"]); assert_has_tip(&[], &san(&pf), Lat, &["pupUrzati"]); assert_has_tip(&[], &san(&d("mf\\N", Tudadi)), Lat, &["mumUrzati"]); - // TODO: others + assert_has_tip(&[], &san(&d("svF", Kryadi)), Lat, &["susvUrzati"]); + + let vr = d("vf", Svadi); + assert_has_tip(&[], &san(&vr), Lat, &["vuvUrzati"]); + assert_has_tip(&["pra", "AN"], &san(&vr), Lat, &["prAvuvUrzati"]); } diff --git a/vidyut-prakriya/tests/kashika_7_2.rs b/vidyut-prakriya/tests/kashika_7_2.rs index 67c4fbf..af1e79b 100644 --- a/vidyut-prakriya/tests/kashika_7_2.rs +++ b/vidyut-prakriya/tests/kashika_7_2.rs @@ -18,7 +18,7 @@ fn sutra_7_2_1() { assert_has_tip(&[], &d("qukf\\Y", Tanadi), Lun, &["akArzIt"]); assert_has_tip(&[], &d("hf\\Y", Bhvadi), Lun, &["ahArzIt"]); - let kutadi = |u| d(u, Tudadi).with_antargana(Some(Antargana::Kutadi)); + let kutadi = |u| d_kutadi(u, Tudadi); assert_has_tip(&["ni"], &kutadi("RU"), Lun, &["nyanuvIt"]); assert_has_tip(&["ni"], &kutadi("DU"), Lun, &["nyaDuvIt"]); @@ -93,8 +93,8 @@ fn sutra_7_2_7() { assert_has_tip(&[], &d("kaRa~", Bhvadi), Lun, &["akaRIt", "akARIt"]); assert_has_tip(&[], &d("raRa~", Bhvadi), Lun, &["araRIt", "arARIt"]); - let kuw = d("kuwa~", Tudadi).with_antargana(Some(Antargana::Kutadi)); - let puw = d("puwa~", Tudadi).with_antargana(Some(Antargana::Kutadi)); + let kuw = d_kutadi("kuwa~", Tudadi); + let puw = d_kutadi("puwa~", Tudadi); // Various counterexamples assert_has_tip(&[], &d("divu~", Divadi), Lun, &["adevIt"]); @@ -604,6 +604,128 @@ fn sutra_7_2_38() { assert_has_sip(&[], &tf, Lit, &["teriTa"]); } +#[test] +fn sutra_7_2_39() { + let vf1 = d("vfN", Kryadi); + let vf2 = d("vfY", Kryadi); + let stf = d("stFY", Kryadi); + + // For aniw, see 7.2.42. + assert_has_ta(&["vi"], &vf1, AshirLin, &["vivarizIzwa", "vivfzIzwa"]); + assert_has_ta( + &["pra", "AN"], + &vf2, + AshirLin, + &["prAvarizIzwa", "prAvfzIzwa"], + ); + assert_has_ta(&["AN"], &stf, AshirLin, &["AstarizIzwa", "AstIrzIzwa"]); + assert_has_ta(&["vi"], &stf, AshirLin, &["vistarizIzwa", "vistIrzIzwa"]); +} + +#[test] +fn sutra_7_2_40() { + let vf = d("vfY", Kryadi); + let tf = d("tF", Bhvadi); + let stf = d("stFY", Kryadi); + + // for aniw, see 7.2.42. + assert_has_tas(&["pra", "AN"], &vf, Lun, &["prAvArizwAm"]); + assert_has_jhi(&["pra", "AN"], &vf, Lun, &["prAvArizuH"]); + assert_has_tas(&[], &tf, Lun, &["atArizwAm"]); + assert_has_jhi(&[], &tf, Lun, &["atArizuH"]); + assert_has_tas(&[], &stf, Lun, &["astArizwAm"]); + assert_has_jhi(&[], &stf, Lun, &["astArizuH"]); + + // parasmEpadezu? + // For aniw, see 7.2.42. + assert_has_ta( + &["pra", "AN"], + &vf, + Lun, + &["prAvarizwa", "prAvarIzwa", "prAvfta"], + ); +} + +#[test] +fn sutra_7_2_42() { + let vf1 = d("vfN", Kryadi); + let vf2 = d("vfY", Kryadi); + let stf = d("stFY", Kryadi); + + assert_has_ta(&[], &vf1, AshirLin, &["vfzIzwa", "varizIzwa"]); + assert_has_ta( + &["pra", "AN"], + &vf2, + AshirLin, + &["prAvfzIzwa", "prAvarizIzwa"], + ); + assert_has_ta(&["AN"], &stf, AshirLin, &["AstarizIzwa", "AstIrzIzwa"]); + + // sici? + assert_has_ta(&[], &vf1, Lun, &["avfta", "avarizwa", "avarIzwa"]); + assert_has_ta( + &["pra", "AN"], + &vf2, + Lun, + &["prAvfta", "prAvarizwa", "prAvarIzwa"], + ); + assert_has_ta(&["AN"], &stf, Lun, &["AstIrzwa", "Astarizwa", "AstarIzwa"]); + + // Atmanepadezu? + assert_has_tas(&["pra", "AN"], &vf2, Lun, &["prAvArizwAm"]); + assert_has_jhi(&["pra", "AN"], &vf2, Lun, &["prAvArizuH"]); +} + +#[test] +fn sutra_7_2_43() { + let dhvf = d("Dvf\\", Bhvadi); + let smf = d("smf\\", Bhvadi); + + assert_has_ta_k( + &[], + &dhvf, + AshirLin, + &["DvfzIzwa", "DvarizIzwa", "DvArizIzwa"], + ); + assert_has_ta_k( + &[], + &smf, + AshirLin, + &["smfzIzwa", "smarizIzwa", "smArizIzwa"], + ); + assert_has_aataam_k( + &[], + &dhvf, + Lun, + &["aDvfzAtAm", "aDvarizAtAm", "aDvArizAtAm"], + ); + assert_has_aataam_k(&[], &smf, Lun, &["asmfzAtAm", "asmarizAtAm", "asmArizAtAm"]); + + // fta? + let cyu = d("cyu\\N", Bhvadi); + let plu = d("plu\\N", Bhvadi); + assert_has_ta(&[], &cyu, AshirLin, &["cyozIzwa"]); + assert_has_ta(&[], &plu, AshirLin, &["plozIzwa"]); + assert_has_ta(&[], &cyu, Lun, &["acyozwa"]); + assert_has_ta(&[], &plu, Lun, &["aplozwa"]); + + // saMyogAdeH? + let kr = d("qukf\\Y", Tanadi); + let hr = d("hf\\Y", Bhvadi); + assert_has_ta(&[], &kr, AshirLin, &["kfzIzwa"]); + assert_has_ta(&[], &hr, AshirLin, &["hfzIzwa"]); + assert_has_ta(&[], &kr, Lun, &["akfta"]); + assert_has_ta(&[], &hr, Lun, &["ahfta"]); + + // Atmanepadezu? + assert_has_tip(&[], &dhvf, Lun, &["aDvArzIt"]); + assert_has_tip(&[], &smf, Lun, &["asmArzIt"]); + + // suw-Agama + assert_has_ta(&["sam"], &kr, AshirLin, &["saNkfzIzwa", "saMskfzIzwa"]); + assert_has_ta(&["sam"], &kr, Lun, &["samakfta", "samaskfta"]); +} + #[test] fn sutra_7_2_44() { let svf = d("svf", Bhvadi); @@ -891,7 +1013,7 @@ fn sutra_7_2_60() { assert_has_tip(&[], &kfp, Lrn, &["akalpsyat"]); assert_has_tip(&[], &san(&kfp), Lat, &["cikxpsati"]); // parasmaipadezu - assert_has_tinanta( + assert_has_tinantas( &[], &kfp, Lut, @@ -1067,7 +1189,7 @@ fn sutra_7_2_73() { #[test] fn sutra_7_2_74() { let assert_has_san_lat = |u, gana, exp| { - let dhatu = d(u, gana).with_sanadi(&[Sanadi::San]); + let dhatu = d(u, gana).with_sanadi(&[Sanadi::san]); assert_has_lat(&[], &dhatu, exp); }; @@ -1083,7 +1205,7 @@ fn sutra_7_2_74() { #[test] fn sutra_7_2_75() { let assert_has_san_lat = |u, gana, exp| { - let dhatu = d(u, gana).with_sanadi(&[Sanadi::San]); + let dhatu = d(u, gana).with_sanadi(&[Sanadi::san]); assert_has_lat(&[], &dhatu, exp); }; @@ -1114,7 +1236,7 @@ fn sutra_7_2_76() { #[test] fn sutra_7_2_77() { let is = d("ISa~\\", Adadi); - assert_has_tinanta( + assert_has_tinantas( &[], &is, Lakara::Lat, @@ -1122,7 +1244,7 @@ fn sutra_7_2_77() { Vacana::Eka, &["ISize"], ); - assert_has_tinanta( + assert_has_tinantas( &[], &is, Lakara::Lot, @@ -1135,8 +1257,8 @@ fn sutra_7_2_77() { #[test] fn sutra_7_2_79() { let kf = d("qukf\\Y", Tanadi); - assert_has_tinanta(&[], &kf, VidhiLin, Prathama, Eka, &["kuryAt", "kurvIta"]); - assert_has_tinanta( + assert_has_tinantas(&[], &kf, VidhiLin, Prathama, Eka, &["kuryAt", "kurvIta"]); + assert_has_tinantas( &[], &kf, VidhiLin, @@ -1144,11 +1266,11 @@ fn sutra_7_2_79() { Dvi, &["kuryAtAm", "kurvIyAtAm"], ); - assert_has_tinanta(&[], &kf, VidhiLin, Prathama, Bahu, &["kuryuH", "kurvIran"]); + assert_has_tinantas(&[], &kf, VidhiLin, Prathama, Bahu, &["kuryuH", "kurvIran"]); // anantasya assert_has_sip(&[], &kf, VidhiLin, &["kuryAH"]); // sArvadhAtuke - assert_has_tinanta( + assert_has_tinantas( &[], &kf, AshirLin, @@ -1156,7 +1278,7 @@ fn sutra_7_2_79() { Dvi, &["kriyAstAm", "kfzIyAstAm"], ); - assert_has_tinanta(&[], &kf, AshirLin, Prathama, Bahu, &["kriyAsuH", "kfzIran"]); + assert_has_tinantas(&[], &kf, AshirLin, Prathama, Bahu, &["kriyAsuH", "kfzIran"]); assert_has_ta(&[], &kf, AshirLin, &["kfzIzwa"]); } @@ -1167,7 +1289,7 @@ fn sutra_7_2_80() { assert_has_tip(&[], &d("zu\\Y", Svadi), VidhiLin, &["sunuyAt"]); assert_has_tip(&[], &d("yA\\", Adadi), VidhiLin, &["yAyAt"]); - let _cikirs = d("qukf\\Y", Tanadi).with_sanadi(&[Sanadi::San]); + let _cikirs = d("qukf\\Y", Tanadi).with_sanadi(&[Sanadi::san]); // TODO: cikIrzyAt } @@ -1218,8 +1340,8 @@ fn sutra_7_2_84() { assert_has_sup_6p("azwan", Pum, &["azwAnAm"]); assert_has_sup_7p("azwan", Pum, &["azwAsu", "azwasu"]); // viBaktO - assert_has_taddhitanta(&prati("azwan"), T::tva, &["azwatva"]); - assert_has_taddhitanta(&prati("azwan"), T::tal, &["azwatA"]); + assert_has_taddhita("azwan", T::tva, &["azwatva"]); + assert_has_taddhita("azwan", T::tal, &["azwatA"]); } #[test] @@ -1229,8 +1351,8 @@ fn sutra_7_2_85() { // hali assert_has_sup_1d("rE", Pum, &["rAyO"]); // viBaktO - assert_has_taddhitanta(&prati("rE"), T::tva, &["rEtva"]); - assert_has_taddhitanta(&prati("rE"), T::tal, &["rEtA"]); + assert_has_taddhita("rE", T::tva, &["rEtva"]); + assert_has_taddhita("rE", T::tal, &["rEtA"]); } #[test] @@ -1420,14 +1542,14 @@ fn sutra_7_2_103() { #[test] fn sutra_7_2_104() { - assert_has_taddhitanta(&prati("kim"), T::tasil, &["kutas"]); - assert_has_taddhitanta(&prati("kim"), T::tral, &["kutra"]); - assert_has_taddhitanta(&prati("kim"), T::ha, &["kuha"]); + assert_has_taddhita("kim", T::tasil, &["kutas"]); + assert_has_taddhita("kim", T::tral, &["kutra"]); + assert_has_taddhita("kim", T::ha, &["kuha"]); } #[test] fn sutra_7_2_105() { - assert_has_taddhitanta(&prati("kim"), T::at, &["kva"]); + assert_has_taddhita("kim", T::at, &["kva"]); } #[test] @@ -1510,7 +1632,7 @@ fn sutra_7_2_115() { #[test] fn sutra_7_2_116() { - let nic = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Nic]); + let nic = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Ric]); let pac = d("qupa\\ca~^z", Bhvadi); assert_has_krdanta(&[], &pac, Krt::GaY, &["pAka"]); @@ -1533,20 +1655,20 @@ fn sutra_7_2_116() { #[test] fn sutra_7_2_117() { - assert_has_taddhitanta(&prati("garga"), T::yaY, &["gArgya"]); - assert_has_taddhitanta(&prati("vatsa"), T::yaY, &["vAtsya"]); - assert_has_taddhitanta(&prati("dakza"), T::iY, &["dAkzi"]); - assert_has_taddhitanta(&prati("plakza"), T::iY, &["plAkzi"]); - assert_has_taddhitanta(&prati("upagu"), T::aR, &["Opagava"]); - assert_has_taddhitanta(&prati("kapawu"), T::aR, &["kApawava"]); + assert_has_taddhita("garga", T::yaY, &["gArgya"]); + assert_has_taddhita("vatsa", T::yaY, &["vAtsya"]); + assert_has_taddhita("dakza", T::iY, &["dAkzi"]); + assert_has_taddhita("plakza", T::iY, &["plAkzi"]); + assert_has_taddhita("upagu", T::aR, &["Opagava"]); + assert_has_taddhita("kapawu", T::aR, &["kApawava"]); // TODO: others } #[test] fn sutra_7_2_118() { - assert_has_taddhitanta(&prati("naqa"), T::Pak, &["nAqAyana"]); - assert_has_taddhitanta(&prati("cara"), T::Pak, &["cArAyaRa"]); - assert_has_taddhitanta(&prati("akza"), T::Wak, &["Akzika"]); - assert_has_taddhitanta(&prati("SalAkA"), T::Wak, &["SAlAkika"]); + assert_has_taddhita("naqa", T::Pak, &["nAqAyana"]); + assert_has_taddhita("cara", T::Pak, &["cArAyaRa"]); + assert_has_taddhita("akza", T::Wak, &["Akzika"]); + assert_has_taddhita("SalAkA", T::Wak, &["SAlAkika"]); // TODO: others } diff --git a/vidyut-prakriya/tests/kashika_7_3.rs b/vidyut-prakriya/tests/kashika_7_3.rs index 6cbeecf..82b8b38 100644 --- a/vidyut-prakriya/tests/kashika_7_3.rs +++ b/vidyut-prakriya/tests/kashika_7_3.rs @@ -5,6 +5,7 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::*; /// Shorthand for creating a nijanta dhAtu. @@ -14,33 +15,50 @@ fn nic_d(u: &str, g: Gana) -> Dhatu { #[test] fn sutra_7_3_1() { - assert_has_taddhitanta(&prati("devikA"), T::aR, &["dAvika"]); - assert_has_taddhitanta(&prati("SiMSapA"), T::aR, &["SAMSapa"]); + assert_has_taddhita("devikA", T::aR, &["dAvika"]); + assert_has_taddhita("SiMSapA", T::aR, &["SAMSapa"]); // TODO: dityavAh - assert_has_taddhitanta(&prati("dIrGasatra"), T::aR, &["dArGasatra"]); - assert_has_taddhitanta(&prati("Sreyas"), T::aR, &["SrAyasa"]); + assert_has_taddhita("dIrGasatra", T::aR, &["dArGasatra"]); + assert_has_taddhita("Sreyas", T::aR, &["SrAyasa"]); } #[ignore] #[test] fn sutra_7_3_2() { - assert_has_taddhitanta(&prati("kekaya"), T::aY, &["kEkeya"]); - assert_has_taddhitanta(&prati("mitrayu"), T::vuY, &["mEtreyaka"]); - assert_has_taddhitanta(&prati("pralaya"), T::aR, &["prAleya"]); + assert_has_taddhita("kekaya", T::aY, &["kEkeya"]); + assert_has_taddhita("mitrayu", T::vuY, &["mEtreyaka"]); + assert_has_taddhita("pralaya", T::aR, &["prAleya"]); +} + +#[ignore] +#[test] +fn sutra_7_3_3() { + assert_has_artha_taddhita("vyasana", TatraBhava, T::aR, &["vEyasana"]); + assert_has_artha_taddhita("vyAkaraRa", TadAdhiteTadVeda, T::aR, &["vEyAkaraRa"]); + let svashva = create_bahuvrihi("svaSva", "su", "aSva"); + assert_has_taddhita(&svashva, T::aR, &["sOvaSva"]); + + // TODO: others } #[test] fn sutra_7_3_4() { - assert_has_taddhitanta(&prati("dvAra"), T::Wak, &["dOvArika"]); - assert_has_taddhitanta(&prati("svara"), T::aR, &["sOvara"]); - assert_has_taddhitanta(&prati("vyalkaSa"), T::aR, &["vEyalkaSa"]); - assert_has_taddhitanta(&prati("svasti"), T::Wak, &["sOvastika"]); - assert_has_taddhitanta(&prati("Svan"), T::aY, &["SOva"]); - assert_has_taddhitanta(&prati("sva"), T::aR, &["sOva"]); + assert_has_taddhita("dvAra", T::Wak, &["dOvArika"]); + assert_has_taddhita("svara", T::aR, &["sOvara"]); + assert_has_taddhita("vyalkaSa", T::aR, &["vEyalkaSa"]); + assert_has_taddhita("svasti", T::Wak, &["sOvastika"]); + assert_has_taddhita("Svan", T::aY, &["SOva"]); + assert_has_taddhita("sva", T::aR, &["sOva"]); // TODO: others } +#[test] +fn sutra_7_3_5() { + assert_has_artha_taddhita("nyagroDa", TasyaVikara, T::aR, &["nEyagroDa"]); + // TODO: others +} + #[test] fn sutra_7_3_32() { let han = d("ha\\na~", Adadi); @@ -130,7 +148,7 @@ fn sutra_7_3_37() { assert_has_tip(&[], &nic_d("So\\", Divadi), Lat, &["SAyayati"]); assert_has_tip(&["ava"], &nic_d("Co\\", Divadi), Lat, &["avacCAyayati"]); assert_has_tip(&["ava"], &nic_d("zE\\", Bhvadi), Lat, &["avasAyayati"]); - assert_has_tip(&[], &nic_d("hve\\Y", Kryadi), Lat, &["hvAyayati"]); + assert_has_tip(&[], &nic_d("hve\\Y", Bhvadi), Lat, &["hvAyayati"]); assert_has_tip(&["sam"], &nic_d("vye\\Y", Divadi), Lat, &["saMvyAyayati"]); assert_has_tip(&[], &nic_d("pA\\", Bhvadi), Lat, &["pAyayati"]); assert_has_tip(&[], &nic_d("pE\\", Bhvadi), Lat, &["pAyayati"]); @@ -215,9 +233,9 @@ fn sutra_7_3_43() { #[test] fn sutra_7_3_50() { - assert_has_taddhitanta(&prati("akza"), T::Wak, &["Akzika"]); - assert_has_taddhitanta(&prati("SalAkA"), T::Wak, &["SAlAkika"]); - assert_has_taddhitanta(&prati("lavaRa"), T::WaY, &["lAvaRika"]); + assert_has_taddhita("akza", T::Wak, &["Akzika"]); + assert_has_taddhita("SalAkA", T::Wak, &["SAlAkika"]); + assert_has_taddhita("lavaRa", T::WaY, &["lAvaRika"]); } #[test] @@ -232,6 +250,24 @@ fn sutra_7_3_52() { assert_has_krdanta(&[], &d("ri\\ci~^r", Bhvadi), Krt::Ryat, &["rekya", "recya"]); } +#[test] +fn sutra_7_3_53() { + // is + assert_has_taddhita("sarpis", T::Wak, &["sArpizka"]); + // us + assert_has_taddhita("Danus", T::Wak, &["DAnuzka"]); + assert_has_taddhita("yajus", T::Wak, &["yAjuzka"]); + // uk + assert_has_taddhita("nizAdakarzu", T::Wak, &["nEzAdakarzuka"]); + assert_has_taddhita("Sabarajambu", T::Wak, &["SAbarajambuka"]); + assert_has_taddhita("mAtf", T::Wak, &["mAtfka"]); + assert_has_taddhita("pitf", T::Wak, &["pEtfka"]); + // t + assert_has_taddhita("udaSvit", T::Wak, &["OdaSvitka"]); + assert_has_taddhita("Sakft", T::Wak, &["SAkftka"]); + assert_has_taddhita("yakft", T::Wak, &["yAkftka"]); +} + #[test] fn sutra_7_3_54() { let han = d("ha\\na~", Adadi); @@ -540,7 +576,7 @@ fn sutra_7_3_84() { assert_has_krdanta(&[], &d("zwu\\Y", Adadi), Krt::tfc, &["stotf"]); // sArvadhAtukArdhadhAtukayoH - assert_has_taddhitanta(&prati("agni"), Taddhita::tva, &["agnitva"]); + assert_has_taddhita("agni", Taddhita::tva, &["agnitva"]); // TODO: agnikAmyati } @@ -887,16 +923,18 @@ fn sutra_7_3_109() { assert_has_sup_1p("budDi", Stri, &["budDayaH"]); } -#[ignore] #[test] fn sutra_7_3_110() { + // Ni assert_has_sup_7s("mAtf", Stri, &["mAtari"]); assert_has_sup_7s("pitf", Pum, &["pitari"]); assert_has_sup_7s("BrAtf", Pum, &["BrAtari"]); assert_has_sup_7s("kartf", Pum, &["kartari"]); + // sarvanAmasTAne - assert_has_sup_1d("kartf", Pum, &["kartArO"]); - assert_has_sup_1p("kartf", Pum, &["kartAraH"]); + let kartr = create_krdanta("kartf", &[], &d("qukf\\Y", Tanadi), Krt::tfc); + assert_has_sup_1d(&kartr, Pum, &["kartArO"]); + assert_has_sup_1p(&kartr, Pum, &["kartAraH"]); assert_has_sup_1d("mAtf", Stri, &["mAtarO"]); assert_has_sup_1d("pitf", Pum, &["pitarO"]); assert_has_sup_1d("BrAtf", Pum, &["BrAtarO"]); @@ -936,7 +974,6 @@ fn sutra_7_3_113() { assert_has_sup_5s(&nyap("kArIzaganDyA"), Stri, &["kArIzaganDyAyAH"]); } -#[ignore] #[test] fn sutra_7_3_114() { assert_has_sup_4s("sarva", Stri, &["sarvasyE"]); @@ -951,7 +988,11 @@ fn sutra_7_3_114() { assert_has_sup_5s("tad", Stri, &["tasyAH"]); assert_has_sup_5s("kim", Stri, &["kasyAH"]); assert_has_sup_5s("anya", Stri, &["anyasyAH"]); - // TODO: ApaH + + // ApaH? + // TODO: what does KV mean here? + assert_has_sup_7s("Bavat", Stri, &["Bavati"]); + assert_has_sup_4s("Bavat", Stri, &["Bavate"]); } #[test] diff --git a/vidyut-prakriya/tests/kashika_7_4.rs b/vidyut-prakriya/tests/kashika_7_4.rs index 3ccd6ec..04051c1 100644 --- a/vidyut-prakriya/tests/kashika_7_4.rs +++ b/vidyut-prakriya/tests/kashika_7_4.rs @@ -10,11 +10,15 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; fn yan_san(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::Yan, Sanadi::San]) + dhatu.clone().with_sanadi(&[Sanadi::yaN, Sanadi::san]) } fn nic_san(dhatu: &Dhatu) -> Dhatu { - dhatu.clone().with_sanadi(&[Sanadi::Nic, Sanadi::San]) + dhatu.clone().with_sanadi(&[Sanadi::Ric, Sanadi::san]) +} + +fn sanadi(p: Pratipadika, s: Sanadi) -> Dhatu { + Dhatu::nama(p, Some(s)) } #[test] @@ -397,6 +401,16 @@ fn sutra_7_4_31() { assert_has_lat(&[], &yan(&d("DmA\\", Bhvadi)), &["deDmIyate"]); } +#[test] +fn sutra_7_4_33() { + let kyac = |prati| sanadi(prati, Sanadi::kyac); + let p = |text: &str| Pratipadika::Basic(text.to_string(), false); + assert_has_tip(&[], &kyac(p("putra")), Lat, &["putrIyati"]); + assert_has_tip(&[], &kyac(p("Gawa")), Lat, &["GawIyati"]); + assert_has_tip(&[], &kyac(p("KawvA")), Lat, &["KawvIyati"]); + assert_has_tip(&[], &kyac(p("mAlA")), Lat, &["mAlIyati"]); +} + #[ignore] #[test] fn sutra_7_4_40() { @@ -493,19 +507,19 @@ fn sutra_7_4_49() { #[test] fn sutra_7_4_50() { let kf = d("qukf\\Y", Tanadi); - assert_has_tinanta(&[], &kf, Lut, Madhyama, Eka, &["kartAsi", "kartAse"]); - assert_has_tinanta(&[], &d("asa~", Adadi), Lat, Madhyama, Eka, &["asi"]); + assert_has_tinantas(&[], &kf, Lut, Madhyama, Eka, &["kartAsi", "kartAse"]); + assert_has_tinantas(&[], &d("asa~", Adadi), Lat, Madhyama, Eka, &["asi"]); // TODO: vyatise } #[test] fn sutra_7_4_51() { let kf = d("qukf\\Y", Tanadi); - assert_has_tinanta(&[], &kf, Lut, Prathama, Dvi, &["kartArO"]); - assert_has_tinanta(&[], &kf, Lut, Prathama, Bahu, &["kartAraH"]); + assert_has_tinantas(&[], &kf, Lut, Prathama, Dvi, &["kartArO"]); + assert_has_tinantas(&[], &kf, Lut, Prathama, Bahu, &["kartAraH"]); let i = d("i\\N", Adadi); - assert_has_tinanta(&["aDi"], &i, Lut, Prathama, Dvi, &["aDyetArO"]); - assert_has_tinanta(&["aDi"], &i, Lut, Prathama, Bahu, &["aDyetAraH"]); + assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Dvi, &["aDyetArO"]); + assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Bahu, &["aDyetAraH"]); } #[test] @@ -656,7 +670,7 @@ fn sutra_7_4_67() { assert_has_lat(&["vi"], &yan(&dyut), &["videdyutyate"]); // TODO - let _svap = d("Yizva\\pa~", Adadi).with_sanadi(&[Sanadi::Nic, Sanadi::San]); + let _svap = d("Yizva\\pa~", Adadi).with_sanadi(&[Sanadi::Ric, Sanadi::san]); // assert_has_tip(&[], &svap, Lat, &["suzvApayizati"]); } @@ -712,9 +726,9 @@ fn sutra_7_4_71() { #[test] fn sutra_7_4_72() { let ashnoti = d("aSU~\\", Svadi); - assert_has_tinanta(&["vi"], &ashnoti, Lit, Prathama, Eka, &["vyAnaSe"]); - assert_has_tinanta(&["vi"], &ashnoti, Lit, Prathama, Dvi, &["vyAnaSAte"]); - assert_has_tinanta(&["vi"], &ashnoti, Lit, Prathama, Bahu, &["vyAnaSire"]); + assert_has_ta(&["vi"], &ashnoti, Lit, &["vyAnaSe"]); + assert_has_aataam(&["vi"], &ashnoti, Lit, &["vyAnaSAte"]); + assert_has_jha(&["vi"], &ashnoti, Lit, &["vyAnaSire"]); // aSnAti let ashnati = d("aSa~", Kryadi); assert_has_tip(&[], &ashnati, Lit, &["ASa"]); @@ -728,6 +742,7 @@ fn sutra_7_4_73() { assert_has_tip(&[], &bhu, Lit, &["baBUva"]); assert_has_tas(&[], &bhu, Lit, &["baBUvatuH"]); assert_has_jhi(&[], &bhu, Lit, &["baBUvuH"]); + assert_has_lat(&[], &san(&bhu), &["buBUzati"]); assert_has_lat(&[], &yan(&bhu), &["boBUyate"]); } @@ -777,7 +792,7 @@ fn sutra_7_4_79() { // ataH assert_has_tip(&[], &san(&d("lUY", Kryadi)), Lat, &["lulUzati"]); // taparakaraNa - let _pac_yan_san = pac.with_sanadi(&[Sanadi::Yan, Sanadi::San]); + let _pac_yan_san = pac.with_sanadi(&[Sanadi::yaN, Sanadi::san]); // assert_has_ta(&[], &pac_yan_san, Lat, &["pApacizate"]); // TODO: pApacizate } diff --git a/vidyut-prakriya/tests/kashika_8_2.rs b/vidyut-prakriya/tests/kashika_8_2.rs index 60e9860..388342b 100644 --- a/vidyut-prakriya/tests/kashika_8_2.rs +++ b/vidyut-prakriya/tests/kashika_8_2.rs @@ -6,24 +6,15 @@ use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha; -use vidyut_prakriya::args::*; - -fn prati_udit(text: &str) -> Pratipadika { - Pratipadika::builder() - .text(text) - .is_udit(true) - .build() - .unwrap() -} #[test] fn sutra_8_2_7() { assert_has_sup_1s("rAjan", Pum, &["rAjA"]); assert_has_sup_3d("rAjan", Pum, &["rAjaByAm"]); assert_has_sup_3p("rAjan", Pum, &["rAjaBiH"]); - assert_has_taddhitanta("rAjan", T::tal, &["rAjatA"]); - assert_has_taddhitanta("rAjan", T::tarap, &["rAjatara"]); - assert_has_taddhitanta("rAjan", T::tamap, &["rAjatama"]); + assert_has_taddhita("rAjan", T::tal, &["rAjatA"]); + assert_has_taddhita("rAjan", T::tarap, &["rAjatara"]); + assert_has_taddhita("rAjan", T::tamap, &["rAjatama"]); } #[test] @@ -35,35 +26,35 @@ fn sutra_8_2_8() { #[test] fn sutra_8_2_9() { // makAra-anta - assert_has_taddhitanta("kim", T::matup, &["kiMvat"]); - assert_has_taddhitanta("Sam", T::matup, &["SaMvat"]); + assert_has_taddhita("kim", T::matup, &["kiMvat"]); + assert_has_taddhita("Sam", T::matup, &["SaMvat"]); // makAra-upadha - assert_has_taddhitanta("SamI", T::matup, &["SamIvat"]); - assert_has_taddhitanta("dAqimI", T::matup, &["dAqimIvat"]); + assert_has_taddhita("SamI", T::matup, &["SamIvat"]); + assert_has_taddhita("dAqimI", T::matup, &["dAqimIvat"]); // avarRa-anta - assert_has_taddhitanta("vfkza", T::matup, &["vfkzavat"]); - assert_has_taddhitanta("plakza", T::matup, &["plakzavat"]); - assert_has_taddhitanta("KawvA", T::matup, &["KawvAvat"]); - assert_has_taddhitanta("mAlA", T::matup, &["mAlAvat"]); + assert_has_taddhita("vfkza", T::matup, &["vfkzavat"]); + assert_has_taddhita("plakza", T::matup, &["plakzavat"]); + assert_has_taddhita("KawvA", T::matup, &["KawvAvat"]); + assert_has_taddhita("mAlA", T::matup, &["mAlAvat"]); // avarRa-upaDa - assert_has_taddhitanta("payas", T::matup, &["payasvat"]); - assert_has_taddhitanta("yaSas", T::matup, &["yaSasvat"]); - assert_has_taddhitanta("BAs", T::matup, &["BAsvat"]); + assert_has_taddhita("payas", T::matup, &["payasvat"]); + assert_has_taddhita("yaSas", T::matup, &["yaSasvat"]); + assert_has_taddhita("BAs", T::matup, &["BAsvat"]); // mAd? - assert_has_taddhitanta("agni", T::matup, &["agnimat"]); - assert_has_taddhitanta("vAyu", T::matup, &["vAyumat"]); + assert_has_taddhita("agni", T::matup, &["agnimat"]); + assert_has_taddhita("vAyu", T::matup, &["vAyumat"]); // avAdibhyaH? - assert_has_taddhitanta("yava", T::matup, &["yavamat"]); - assert_has_taddhitanta("dalmi", T::matup, &["dalmimat"]); - assert_has_taddhitanta("Urmi", T::matup, &["Urmimat"]); + assert_has_taddhita("yava", T::matup, &["yavamat"]); + assert_has_taddhita("dalmi", T::matup, &["dalmimat"]); + assert_has_taddhita("Urmi", T::matup, &["Urmimat"]); } #[test] fn sutra_8_2_10() { - assert_has_taddhitanta("agnicit", T::matup, &["agnicitvat"]); - assert_has_taddhitanta("vidyut", T::matup, &["vidyutvat"]); - assert_has_taddhitanta("marut", T::matup, &["marutvat"]); - assert_has_taddhitanta("dfzad", T::matup, &["dfzadvat"]); + assert_has_taddhita("agnicit", T::matup, &["agnicitvat"]); + assert_has_taddhita("vidyut", T::matup, &["vidyutvat"]); + assert_has_taddhita("marut", T::matup, &["marutvat"]); + assert_has_taddhita("dfzad", T::matup, &["dfzadvat"]); } #[test] @@ -116,12 +107,16 @@ fn sutra_8_2_21() { #[test] fn sutra_8_2_23() { - assert_has_sup_1s(&prati_udit("gomat"), Pum, &["gomAn"]); - assert_has_sup_1s(&prati_udit("yavamat"), Pum, &["yavamAn"]); - assert_has_sup_1s(&prati_udit("kftavat"), Pum, &["kftavAn"]); - assert_has_sup_1s(&prati_udit("hatavat"), Pum, &["hatavAn"]); - assert_has_sup_1s(&prati_udit("Sreyas"), Pum, &["SreyAn"]); - assert_has_sup_1s(&prati_udit("BUyas"), Pum, &["BUyAn"]); + assert_has_sup_1s(taddhitanta("go", T::matup), Pum, &["gomAn"]); + assert_has_sup_1s(taddhitanta("yava", T::matup), Pum, &["yavamAn"]); + assert_has_sup_1s(taddhitanta("kfta", T::matup), Pum, &["kftavAn"]); + assert_has_sup_1s(taddhitanta("hata", T::matup), Pum, &["hatavAn"]); + assert_has_sup_1s( + taddhitanta("praSasya", T::Iyasun).with_require("Sreyas"), + Pum, + &["SreyAn"], + ); + assert_has_sup_1s(taddhitanta("bahu", T::Iyasun), Pum, &["BUyAn"]); // TODO: others } @@ -631,6 +626,13 @@ fn sutra_8_2_46() { // TODO: akzita } +#[ignore] +#[test] +fn sutra_8_2_47() { + let shyai = d("SyE\\N", Bhvadi); + assert_has_krdanta(&[], ­ai, Krt::kta, &["SIna", "SIta"]); +} + #[test] fn sutra_8_2_51() { let sus = d("Su\\za~", Divadi); @@ -764,6 +766,46 @@ fn sutra_8_2_69() { assert_has_sup_3p("ahan", Pum, &["ahoBiH"]); } +#[test] +fn sutra_8_2_72() { + let vid = d("vida~", Adadi); + let vidvas = create_krdanta("vidvas", &[], &vid, Krt::Satf); + assert_has_sup_3d(&vidvas, Pum, &["vidvadByAm"]); + assert_has_sup_3p(&vidvas, Pum, &["vidvadBiH"]); + + let papivas = create_krdanta("papivas", &[], &d("pA\\", Bhvadi), Krt::kvasu); + assert_has_sup_3d(&papivas, Pum, &["papivadByAm"]); + assert_has_sup_3p(&papivas, Pum, &["papivadBiH"]); + + let ukhasras = + create_upapada_krdanta("uKAsras", "uKA", &[], &d("sransu~\\", Bhvadi), Krt::kvip); + assert_has_sup_3d(&ukhasras, Pum, &["uKAsradByAm"]); + assert_has_sup_3p(&ukhasras, Pum, &["uKAsradBiH"]); + + let parnadhvas = create_upapada_krdanta( + "parRaDvas", + "parRa", + &[], + &d("Dvansu~\\", Bhvadi), + Krt::kvip, + ); + assert_has_sup_3d(&parnadhvas, Pum, &["parRaDvadByAm"]); + assert_has_sup_3p(&parnadhvas, Pum, &["parRaDvadBiH"]); + + assert_has_sup_3d("anaquh", Pum, &["anaqudByAm"]); + assert_has_sup_3p("anaquh", Pum, &["anaqudBiH"]); + + // saH? + assert_has_sup_1s(&vidvas, Pum, &["vidvAn"]); + assert_has_sup_1s(&papivas, Pum, &["papivAn"]); + assert_has_sup_1s("anaquh", Pum, &["anaqvAn"]); + assert_has_sup_ss("anaquh", Pum, &["anaqvan"]); + + // padasya? + assert_has_sup_1d(&vidvas, Pum, &["vidvAMsO"]); + assert_has_sup_1p(&vidvas, Pum, &["vidvAMsaH"]); +} + #[test] fn sutra_8_2_73() { let cakas = &d("cakAsf~", Adadi); @@ -788,10 +830,12 @@ fn sutra_8_2_75() { #[ignore] #[test] fn sutra_8_2_76() { + /* assert_has_sup_1s(&dhatu_prati("gir"), Pum, &["gIH"]); assert_has_sup_1s(&dhatu_prati("Dur"), Pum, &["DUH"]); assert_has_sup_1s(&dhatu_prati("pur"), Pum, &["pUH"]); assert_has_sup_1s(&dhatu_prati("ASis"), Pum, &["pUH"]); + */ } #[test] diff --git a/vidyut-prakriya/tests/kashika_8_3.rs b/vidyut-prakriya/tests/kashika_8_3.rs index 891b928..dbba64b 100644 --- a/vidyut-prakriya/tests/kashika_8_3.rs +++ b/vidyut-prakriya/tests/kashika_8_3.rs @@ -1,10 +1,14 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; +use vidyut_prakriya::args::Dhatu; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; +use vidyut_prakriya::args::Pratipadika; +use vidyut_prakriya::args::Sanadi; use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; #[test] @@ -50,14 +54,38 @@ fn sutra_8_3_16() { assert_has_sup_7p("Dur", Napumsaka, &["DUrzu"]); } +#[test] +fn sutra_8_3_17() { + assert_has_sandhi("Bos", "atra", &["Bo atra"]); + assert_has_sandhi("Bagos", "atra", &["Bago atra"]); + assert_has_sandhi("aGos", "atra", &["aGo atra"]); + + assert_has_sandhi("Bos", "dadAti", &["Bo dadAti"]); + assert_has_sandhi("Bagos", "dadAti", &["Bago dadAti"]); + assert_has_sandhi("aGos", "dadAti", &["aGo dadAti"]); + + assert_has_sandhi("kas", "Aste", &["ka Aste"]); + assert_has_sandhi("puruzAs", "dadati", &["puruzA dadati"]); + + // Bo-Bago-... ? + assert_has_sandhi("agnis", "atra", &["agnir atra"]); + assert_has_sandhi("vAyus", "atra", &["vAyur atra"]); + + // aS? + assert_has_sup_1s("vfkza", Pum, &["vfkzaH"]); + assert_has_sup_1s("plakza", Pum, &["plakzaH"]); + + // TODO: others +} + #[test] fn sutra_8_3_22() { - assert_has_sandhi("Bo", "hasati", &["Bo hasati"]); - assert_has_sandhi("Bago", "hasati", &["Bago hasati"]); - assert_has_sandhi("aDo", "hasati", &["aDo hasati"]); - assert_has_sandhi("Bo", "yAti", &["Bo yAti"]); - assert_has_sandhi("Bago", "yAti", &["Bago yAti"]); - assert_has_sandhi("aDo", "yAti", &["aDo yAti"]); + assert_has_sandhi("Bos", "hasati", &["Bo hasati"]); + assert_has_sandhi("Bagos", "hasati", &["Bago hasati"]); + assert_has_sandhi("aGos", "hasati", &["aGo hasati"]); + assert_has_sandhi("Bos", "yAti", &["Bo yAti"]); + assert_has_sandhi("Bagos", "yAti", &["Bago yAti"]); + assert_has_sandhi("aGos", "yAti", &["aGo yAti"]); assert_has_sandhi("vfkzAs", "hasanti", &["vfkzA hasanti"]); } @@ -96,6 +124,12 @@ fn sutra_8_3_24() { assert_has_ta_k(&[], &d("ga\\mx~", Bhvadi), Lat, &["gamyate"]); } +#[test] +fn sutra_8_3_29() { + assert_has_sandhi("Svaliw", "sAye", &["Svaliw sAye", "Svaliw tsAye"]); + assert_has_sandhi("maDuliw", "sAye", &["maDuliw sAye", "maDuliw tsAye"]); +} + #[test] fn sutra_8_3_34() { // hari @@ -130,6 +164,69 @@ fn sutra_8_3_36() { assert_has_sandhi("vfkzas", "sAye", &["vfkzas sAye", "vfkzaH sAye"]); } +#[test] +fn sutra_8_3_38() { + assert_has_taddhita("payas", T::pASap, &["payaspASa"]); + assert_has_taddhita("payas", T::kalpap, &["payaskalpa"]); + assert_has_taddhita("yaSas", T::kalpap, &["yaSaskalpa"]); + + assert_has_taddhita("payas", T::ka, &["payaska"]); + assert_has_taddhita("yaSas", T::ka, &["yaSaska"]); + + let kamyac = |prati| Dhatu::nama(Pratipadika::basic(prati), Some(Sanadi::kAmyac)); + assert_has_tip(&[], &kamyac("payas"), Lat, &["payaskAmyati"]); + assert_has_tip(&[], &kamyac("yaSas"), Lat, &["yaSaskAmyati"]); + + // TODO: jihvA/upaDmAnIya +} + +#[test] +fn sutra_8_3_39() { + assert_has_taddhita("sarpis", T::pASap, &["sarpizpASa"]); + assert_has_taddhita("yajus", T::pASap, &["yajuzpASa"]); + assert_has_taddhita("sarpis", T::kalpap, &["sarpizkalpa"]); + assert_has_taddhita("yajus", T::kalpap, &["yajuzkalpa"]); + assert_has_taddhita("sarpis", T::ka, &["sarpizka"]); + assert_has_taddhita("yajus", T::ka, &["yajuzka"]); + + let kamyac = |prati| Dhatu::nama(Pratipadika::basic(prati), Some(Sanadi::kAmyac)); + assert_has_tip(&[], &kamyac("sarpis"), Lat, &["sarpizkAmyati"]); + assert_has_tip(&[], &kamyac("yajus"), Lat, &["yajuzkAmyati"]); + + // a-padAdO? + // TODO: need to create these from unAdi-pratyayas. + // assert_has_sandhi("agniH", "karoti", &["agniH karoti"]); + // assert_has_sandhi("vAyuH", "karoti", &["vAyuH karoti"]); + // assert_has_sandhi("agniH", "pacati", &["agniH pacati"]); + // assert_has_sandhi("vAyuH", "pacati", &["vAyuH pacati"]); + + // TODO: sarpiste? how do we construct that? +} + +#[test] +fn sutra_8_3_40() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&["namas"], &kr, Krt::tfc, &["namaskartf"]); + assert_has_krdanta(&["namas"], &kr, Krt::tumun, &["namaskartum"]); + assert_has_krdanta(&["namas"], &kr, Krt::tavya, &["namaskartavya"]); + + // TODO: gatyoH? +} + +#[test] +fn sutra_8_3_42() { + let kr = d("qukf\\Y", Tanadi); + assert_has_tip(&["tiras"], &kr, Lat, &["tiraskaroti", "tiraHkaroti"]); + assert_has_krdanta(&["tiras"], &kr, Krt::tfc, &["tiraskartf", "tiraHkartf"]); + assert_has_krdanta(&["tiras"], &kr, Krt::tumun, &["tiraskartum", "tiraHkartum"]); + assert_has_krdanta( + &["tiras"], + &kr, + Krt::tavya, + &["tiraskartavya", "tiraHkartavya"], + ); +} + #[test] fn sutra_8_3_55() { assert_has_tip(&[], &d("zi\\ca~^", Tudadi), Lit, &["sizeca"]); @@ -551,6 +648,40 @@ fn sutra_8_3_77() { assert_has_lat(&["vi"], &skanbh, &["vizkaBnAti", "vizkaBnoti"]); } +#[test] +fn sutra_8_3_78() { + let cyu = d("cyu\\N", Bhvadi); + let plu = d("plu\\N", Bhvadi); + + // zIQam + assert_has_dhvam(&[], &cyu, AshirLin, &["cyozIQvam"]); + assert_has_dhvam(&[], &plu, AshirLin, &["plozIQvam"]); + + // luN + assert_has_dhvam(&[], &cyu, Lun, &["acyoQvam"]); + assert_has_dhvam(&[], &plu, Lun, &["aploQvam"]); + + // liw + assert_has_dhvam(&[], &d("qukf\\Y", Tanadi), Lit, &["cakfQve"]); + assert_has_dhvam(&[], &d("vfY", Svadi), Lit, &["vavfQve"]); + + // kavarga-nivrtti + assert_has_dhvam(&[], &d("qupa\\ca~^z", Bhvadi), AshirLin, &["pakzIDvam"]); + assert_has_dhvam(&[], &d("ya\\ja~^", Bhvadi), AshirLin, &["yakzIDvam"]); + + // zIDvaMluNliwAm? + assert_has_dhvam(&[], &d("zwu\\Y", Adadi), Lat, &["stuDve", "stuvIDve"]); + assert_has_dhvam(&[], &d("zwu\\Y", Adadi), Lan, &["astuDvam", "astuvIDvam"]); + + // aNgAt? + assert_has_dhvam( + &["pari"], + &d("vi\\zx~^", Juhotyadi), + VidhiLin, + &["parivevizIDvam"], + ); +} + #[test] fn sutra_8_3_79() { let lu = d("lUY", Kryadi); @@ -570,6 +701,56 @@ fn sutra_8_3_79() { assert_has_dhvam(&[], &kf, Lit, &["cakfQve"]); } +#[ignore] +#[test] +fn sutra_8_3_82() { + assert_has_sasthi_tatpurusha("agni", "stut", &["agnizwut"]); + assert_has_sasthi_tatpurusha("agni", "stoma", &["agnizwoma"]); + assert_has_sasthi_tatpurusha("agni", "soma", &["agnizoma"]); +} + +#[test] +fn sutra_8_3_96() { + assert_has_avyaya_tatpurusha("vi", "sTala", &["vizWala"]); + assert_has_avyaya_tatpurusha("ku", "sTala", &["kuzWala"]); + assert_has_sasthi_tatpurusha("Sami", "sTala", &["SamizWala"]); + assert_has_avyaya_tatpurusha("pari", "sTala", &["parizWala"]); +} + +#[ignore] +#[test] +fn sutra_8_3_101() { + let sarpis = create_krdanta("sarpis", &[], &d("sf\\px~", Bhvadi), Unadi::isi); + let yajus = create_krdanta("yajus", &[], &d("ya\\ja~^", Bhvadi), Unadi::usi); + + assert_has_taddhita(&sarpis, T::tarap, &["sarpizwara"]); + assert_has_taddhita(&yajus, T::tarap, &["yajuzwara"]); + + assert_has_taddhita(&sarpis, T::tamap, &["sarpizwama"]); + assert_has_taddhita(&yajus, T::tamap, &["yajuzwama"]); + + assert_has_artha_taddhita("catur", Avasana, T::tayap, &["catuzwaya"]); + + assert_has_taddhita(&sarpis, T::tva, &["sarpizwva"]); + assert_has_taddhita(&yajus, T::tva, &["yajuzwva"]); + + assert_has_taddhita(&sarpis, T::tal, &["sarpizwA"]); + assert_has_taddhita(&yajus, T::tal, &["yajuzwA"]); + + assert_has_taddhita(&sarpis, T::tasi, &["sarpizwas"]); + assert_has_taddhita(&yajus, T::tasi, &["yajuzwas"]); + + // let _avis = SamasaPada::avyaya(Pratipadika::basic("Avis").into()); + // assert_has_taddhita(&avis, T::tyap, &["Avizwya"]); + + // hrasva? + assert_has_taddhita("gir", T::tarap, &["gIstara"]); + assert_has_taddhita("Dur", T::tarap, &["DUstara"]); + + // tAdau? + assert_has_taddhita(&sarpis, T::sAti, &["sarpissAt"]); +} + #[test] fn sutra_8_3_110() { assert_has_krdanta(&["vi"], &d("sransu~\\", Bhvadi), Krt::Rvul, &["visraMsaka"]); @@ -583,8 +764,8 @@ fn sutra_8_3_110() { #[test] fn sutra_8_3_111() { - assert_has_taddhitanta(&prati("agni"), T::sAti, &["agnisAt"]); - assert_has_taddhitanta(&prati("daDi"), T::sAti, &["daDisAt"]); + assert_has_taddhita("agni", T::sAti, &["agnisAt"]); + assert_has_taddhita("daDi", T::sAti, &["daDisAt"]); assert_has_sandhi("daDi", "siYcati", &["daDi siYcati"]); assert_has_sandhi("maDu", "siYcati", &["maDu siYcati"]); } diff --git a/vidyut-prakriya/tests/kashika_8_4.rs b/vidyut-prakriya/tests/kashika_8_4.rs index 33b7a54..070c4ed 100644 --- a/vidyut-prakriya/tests/kashika_8_4.rs +++ b/vidyut-prakriya/tests/kashika_8_4.rs @@ -23,12 +23,11 @@ fn sutra_8_4_1() { assert_has_sandhi("vAyus", "nayati", &["vAyur nayati"]); } -#[ignore] #[test] fn sutra_8_4_1_v1() { - assert_has_sup_6p(&nyap("tri"), Stri, &["tisfRAm"]); - assert_has_sup_6p(&nyap("catur"), Stri, &["catasfRAm"]); - assert_has_sup_6p(&nyap("mAtf"), Stri, &["mAtFRAm"]); + assert_has_sup_6p("tri", Stri, &["tisfRAm"]); + assert_has_sup_6p("catur", Stri, &["catasfRAm"]); + assert_has_sup_6p("mAtf", Stri, &["mAtFRAm"]); assert_has_sup_6p("pitf", Pum, &["pitFRAm"]); } @@ -232,7 +231,7 @@ fn sutra_8_4_19() { #[test] fn sutra_8_4_21() { let an = d("ana~", Adadi); - let nic = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Nic]); + let nic = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Ric]); assert_has_tip(&["pra"], &san(&an), Lat, &["prARiRizati"]); assert_has_tip(&["pra"], &nic(&an), Lun, &["prARiRat"]); assert_has_tip(&["parA"], &san(&an), Lat, &["parARiRizati"]); @@ -361,7 +360,6 @@ fn sutra_8_4_41() { // TODO: awwati, aqqati } -#[ignore] #[test] fn sutra_8_4_42() { assert_has_sandhi("Svaliw", "sAye", &["Svaliw sAye", "Svaliw tsAye"]); @@ -369,7 +367,7 @@ fn sutra_8_4_42() { // padAntAt? assert_has_ta(&[], &d("Iqa~\\", Adadi), Lat, &["Iwwe"]); // woH? - assert_has_taddhitanta(&prati("sarpis"), T::tamap, &["sarpizwama"]); + assert_has_taddhita("sarpis", T::tamap, &["sarpizwama"]); // // an-Am? assert_has_sup_6p("zaz", Pum, &["zaRRAm"]); } diff --git a/vidyut-prakriya/tests/kaumudi_10.rs b/vidyut-prakriya/tests/kaumudi_10.rs index 1532e44..549fd81 100644 --- a/vidyut-prakriya/tests/kaumudi_10.rs +++ b/vidyut-prakriya/tests/kaumudi_10.rs @@ -75,7 +75,6 @@ fn sk_322() { assert_has_sup_3s("daDi", Napumsaka, &["daDnA"]); } -#[ignore] #[test] fn sk_323() { assert_has_sup_1s("pradyo", Napumsaka, &["pradyu"]); @@ -83,13 +82,14 @@ fn sk_323() { assert_has_sup_1p("pradyo", Napumsaka, &["pradyUni"]); assert_has_sup_3s("pradyo", Napumsaka, &["pradyunA"]); - assert_has_sup_1s("prarE", Napumsaka, &["prari"]); - assert_has_sup_1d("prarE", Napumsaka, &["prariRI"]); - assert_has_sup_1p("prarE", Napumsaka, &["prarIRi"]); - assert_has_sup_3s("prarE", Napumsaka, &["prariRA"]); - assert_has_sup_3d("prarE", Napumsaka, &["prarAByAm"]); - assert_has_sup_3p("prarE", Napumsaka, &["prarABiH"]); - assert_has_sup_6p("prarE", Napumsaka, &["prarIRAm"]); + let prari = create_avyaya_tatpurusha("prarE", "pra", "rE"); + assert_has_sup_1s(&prari, Napumsaka, &["prari"]); + assert_has_sup_1d(&prari, Napumsaka, &["prariRI"]); + assert_has_sup_1p(&prari, Napumsaka, &["prarIRi"]); + assert_has_sup_3s(&prari, Napumsaka, &["prariRA"]); + assert_has_sup_3d(&prari, Napumsaka, &["prarAByAm"]); + assert_has_sup_3p(&prari, Napumsaka, &["prarABiH"]); + assert_has_sup_6p(&prari, Napumsaka, &["prarIRAm"]); assert_has_sup_1s("sunu", Napumsaka, &["sunu"]); assert_has_sup_1d("sunu", Napumsaka, &["sununI"]); diff --git a/vidyut-prakriya/tests/kaumudi_11.rs b/vidyut-prakriya/tests/kaumudi_11.rs index 3a56ce3..54cd797 100644 --- a/vidyut-prakriya/tests/kaumudi_11.rs +++ b/vidyut-prakriya/tests/kaumudi_11.rs @@ -4,8 +4,9 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pratipadika; -use vidyut_prakriya::args::SamasaType::*; +use vidyut_prakriya::args::Samasa; use vidyut_prakriya::args::{BaseKrt as Krt, Gana}; +use vidyut_prakriya::args::{Vacana, Vibhakti}; #[test] fn sk_324() { @@ -31,7 +32,7 @@ fn sk_326() { assert_has_krdanta(&[], &duh, Krt::kta, &["dugDa"]); assert_has_krdanta(&[], &duh, Krt::tfc, &["dogDf"]); - let duh = dhatu_prati("duh"); + let duh = krdanta(&[], &d("du\\ha~^", Adadi), Krt::kvip); assert_has_sup_1s(&duh, Pum, &["Duk"]); assert_has_sup_1d(&duh, Pum, &["duhO"]); assert_has_sup_1p(&duh, Pum, &["duhaH"]); @@ -83,18 +84,20 @@ fn sk_333() { assert_has_sup_3s("anaquh", Pum, &["anaquhA"]); } -#[ignore] #[test] fn sk_334() { + let vid = d("vida~", Adadi); + let vidvas = create_krdanta("vidvas", &[], &vid, Krt::Satf); + assert_has_sup_3d("anaquh", Pum, &["anaqudByAm"]); - assert_has_sup_1s("vidvas", Pum, &["vidvAn"]); + assert_has_sup_1s(&vidvas, Pum, &["vidvAn"]); assert_has_krdanta(&[], &d("sransu~\\", Bhvadi), Krt::kta, &["srasta"]); assert_has_krdanta(&[], &d("Dvansu~\\", Bhvadi), Krt::kta, &["Dvasta"]); } #[test] fn sk_336() { - let sudiv = create_samasa("sudiv", &["su", "div"], Bahuvrihi); + let sudiv = bahuvrihi("su", "div"); assert_has_sup_1s(&sudiv, Pum, &["sudyOH"]); assert_has_sup_1d(&sudiv, Pum, &["sudivO"]); assert_has_sup_1p(&sudiv, Pum, &["sudivaH"]); @@ -104,7 +107,7 @@ fn sk_336() { #[test] fn sk_337() { - let sudiv = create_samasa("sudiv", &["su", "div"], Bahuvrihi); + let sudiv = bahuvrihi("su", "div"); assert_has_sup_3d(&sudiv, Pum, &["sudyuByAm"]); assert_has_sup_3p(&sudiv, Pum, &["sudyuBiH"]); @@ -128,7 +131,7 @@ fn skip_sk_339() {} fn sk_340() { assert_has_sup_7p("catur", Pum, &["caturzu"]); - let priyacatur = create_samasa("priyacatur", &["priya", "catur"], Bahuvrihi); + let priyacatur = bahuvrihi("priya", "catur"); assert_has_sup_1s(&priyacatur, Pum, &["priyacatvAH"]); assert_has_sup_ss(&priyacatur, Pum, &["priyacatvaH"]); assert_has_sup_1d(&priyacatur, Pum, &["priyacatvArO"]); @@ -244,16 +247,26 @@ fn skip_sk_360() {} #[ignore] #[test] fn sk_361() { - assert_has_sup_1s("maGavan", Pum, &["maGavAn"]); - assert_has_sup_1s("maGavan", Pum, &["maGavantO"]); - assert_has_sup_1s("maGavan", Pum, &["maGavantaH"]); + assert_has_sup_1s("maGavan", Pum, &["maGavAn", "maGavA"]); + assert_has_sup_1s("maGavan", Pum, &["maGavantO", "maGavAnO"]); + assert_has_sup_1s("maGavan", Pum, &["maGavantaH", "maGavAnaH"]); assert_has_sup_ss("maGavan", Pum, &["maGavan"]); - assert_has_sup_ss("maGavan", Pum, &["maGavantam"]); - assert_has_sup_ss("maGavan", Pum, &["maGavantO"]); - assert_has_sup_ss("maGavan", Pum, &["maGavataH"]); - assert_has_sup_ss("maGavan", Pum, &["maGavatA"]); - assert_has_sup_ss("maGavan", Pum, &["maGavadByAm"]); - assert_has_sup_ss("maGavan", Pum, &["maGavadByAm"]); + assert_has_sup_ss("maGavan", Pum, &["maGavantam", "maGavAnam"]); + assert_has_sup_ss("maGavan", Pum, &["maGavantO", "maGavAnO"]); + assert_has_sup_ss("maGavan", Pum, &["maGavataH", "maGavAnaH"]); + assert_has_sup_ss("maGavan", Pum, &["maGavatA", "maGonA"]); + assert_has_sup_ss("maGavan", Pum, &["maGavadByAm", "maGavaByAm"]); + assert_has_sup_ss("maGavan", Pum, &["maGavadByAm", "maGavaByAm"]); + + // TODO: others (maGavA?) +} + +#[ignore] +#[test] +fn sk_362() { + assert_has_sup_6s("maGavan", Pum, &["maGonaH", "maGavataH"]); + assert_has_sup_2p("maGavan", Pum, &["maGavataH"]); + assert_has_sup_3s("maGavan", Pum, &["maGavatA"]); } #[test] @@ -309,26 +322,26 @@ fn sk_377() { assert_has_sup_3d(&yuj, Pum, &["yugByAm"]); } -#[ignore] #[test] fn sk_378() { let yuj = create_krdanta("yuj", &[], &d("yu\\ji~^r", Rudhadi), Krt::kvin); - let suyuj = create_samasa_p("suyuj", &[Pratipadika::from("su"), yuj], Bahuvrihi); + let suyuj = bahuvrihi(Pratipadika::basic("su"), yuj); assert_has_sup_1s(&suyuj, Pum, &["suyuk"]); assert_has_sup_1d(&suyuj, Pum, &["suyujO"]); assert_has_sup_1p(&suyuj, Pum, &["suyujaH"]); // TODO: do others here - let khanj = create_krdanta("KaYj", &[], &d("Kaji~", Bhvadi), Krt::kvip); + let khanj = krdanta(&[], &d("Kaji~", Bhvadi), Krt::kvip); assert_has_sup_1s(&khanj, Pum, &["Kan"]); assert_has_sup_1d(&khanj, Pum, &["KaYjO"]); assert_has_sup_1p(&khanj, Pum, &["KaYjaH"]); - assert_has_sup_1s("rAj", Pum, &["rAw"]); - assert_has_sup_1d("rAj", Pum, &["rAjO"]); - assert_has_sup_1p("rAj", Pum, &["rAjaH"]); - assert_has_sup_7p("rAj", Pum, &["rAwsu", "rAwtsu"]); + let raj = krdanta(&[], &d("rAjf~^", Bhvadi), Krt::kvip); + assert_has_sup_1s(&raj, Pum, &["rAw"]); + assert_has_sup_1d(&raj, Pum, &["rAjO"]); + assert_has_sup_1p(&raj, Pum, &["rAjaH"]); + assert_has_sup_7p(&raj, Pum, &["rAwsu", "rAwtsu"]); } #[test] @@ -337,11 +350,19 @@ fn skip_sk_382_to_sk_384() {} #[test] fn skip_sk_386() {} -#[ignore] #[test] fn sk_388() { + fn sup_1p(args: Samasa) -> Samasa { + args.with_sup(Pum, Vibhakti::Prathama, Vacana::Bahu) + } + assert_has_sup_1p("yuzmad", Pum, &["yUyam"]); assert_has_sup_1p("asmad", Pum, &["vayam"]); + + assert_has_samasas(&sup_1p(karmadharaya("parama", "yuzmad")), &["paramayUyam"]); + assert_has_samasas(&sup_1p(karmadharaya("parama", "asmad")), &["paramavayam"]); + assert_has_samasas(&sup_1p(karmadharaya("ati", "yuzmad")), &["atiyUyam"]); + assert_has_samasas(&sup_1p(karmadharaya("ati", "asmad")), &["ativayam"]); } #[test] @@ -375,11 +396,22 @@ fn sk_393() { assert_has_sup_3p("asmad", Pum, &["asmABiH"]); } -#[ignore] #[test] fn sk_394() { + fn sup_4s(args: Samasa) -> Samasa { + args.with_sup(Pum, Vibhakti::Caturthi, Vacana::Eka) + } + assert_has_sup_4s("yuzmad", Pum, &["tuByam"]); assert_has_sup_4s("asmad", Pum, &["mahyam"]); + + assert_has_samasas(&sup_4s(karmadharaya("parama", "yuzmad")), &["paramatuByam"]); + assert_has_samasas(&sup_4s(karmadharaya("parama", "asmad")), &["paramamahyam"]); + assert_has_samasas(&sup_4s(karmadharaya("ati", "yuzmad")), &["atituByam"]); + assert_has_samasas(&sup_4s(karmadharaya("ati", "asmad")), &["atimahyam"]); + + assert_has_sup_4d("yuzmad", Pum, &["yuvAByAm"]); + assert_has_sup_4d("asmad", Pum, &["AvAByAm"]); } #[test] @@ -396,7 +428,6 @@ fn sk_396() { assert_has_sup_5d("asmad", Pum, &["AvAByAm"]); } -#[ignore] #[test] fn sk_397() { assert_has_sup_5p("yuzmad", Pum, &["yuzmat"]); @@ -459,11 +490,10 @@ fn sk_428() { // let vevyat = create_krdanta("vevyat", &[], &d("vevIN", Adadi), Krt::Satf); // assert_has_sup_1s(&vevyat, Pum, &["vevyat"]); - let gup = create_krdanta("gup", &[], &d("gupU~", Bhvadi), Krt::kvip); - assert_has_sup_1s(&gup, Pum, &["gup"]); - assert_has_sup_1d(&gup, Pum, &["gupO"]); - assert_has_sup_1p(&gup, Pum, &["gupaH"]); - assert_has_sup_3d(&gup, Pum, &["gubByAm"]); + assert_has_sup_1s("gup", Pum, &["gup"]); + assert_has_sup_1d("gup", Pum, &["gupO"]); + assert_has_sup_1p("gup", Pum, &["gupaH"]); + assert_has_sup_3d("gup", Pum, &["gubByAm"]); } #[test] @@ -480,7 +510,7 @@ fn skip_sk_431() { #[test] fn sk_433() { - let pipathis = create_krdanta("pipaWiz", &[], &san(&d("paWa~", Bhvadi)), Krt::kvip); + let pipathis = krdanta(&[], &san(&d("paWa~", Bhvadi)), Krt::kvip); assert_has_sup_1s(&pipathis, Pum, &["pipaWIH"]); assert_has_sup_1d(&pipathis, Pum, &["pipaWizO"]); assert_has_sup_1p(&pipathis, Pum, &["pipaWizaH"]); @@ -489,7 +519,7 @@ fn sk_433() { #[test] fn sk_434() { - let pipathis = create_krdanta("pipaWiz", &[], &san(&d("paWa~", Bhvadi)), Krt::kvip); + let pipathis = krdanta(&[], &san(&d("paWa~", Bhvadi)), Krt::kvip); assert_has_sup_7p(&pipathis, Pum, &["pipaWIzzu", "pipaWIHzu"]); let nins = d("Risi~\\", Adadi); @@ -499,7 +529,7 @@ fn sk_434() { assert_has_sup_7p("suhins", Pum, &["suhinsu"]); assert_has_sup_7p("pums", Pum, &["puMsu"]); - let cikirsh = create_krdanta("cikIrz", &[], &san(&d("qukf\\Y", Tanadi)), Krt::kvip); + let cikirsh = krdanta(&[], &san(&d("qukf\\Y", Tanadi)), Krt::kvip); assert_has_sup_1s(&cikirsh, Pum, &["cikIH"]); assert_has_sup_1d(&cikirsh, Pum, &["cikIrzO"]); assert_has_sup_1p(&cikirsh, Pum, &["cikIrzaH"]); @@ -518,7 +548,7 @@ fn sk_434() { assert_has_sup_1p(&goraksh, Pum, &["gorakzaH"]); let pis = create_krdanta("pis", &[], &d("pisf~", Bhvadi), Krt::kvip); - let supis = create_samasa_p("supis", &[Pratipadika::from("su"), pis], Bahuvrihi); + let supis = bahuvrihi(Pratipadika::basic("su"), pis); assert_has_sup_1s(&supis, Pum, &["supIH"]); assert_has_sup_1d(&supis, Pum, &["supisO"]); assert_has_sup_1p(&supis, Pum, &["supisaH"]); diff --git a/vidyut-prakriya/tests/kaumudi_12.rs b/vidyut-prakriya/tests/kaumudi_12.rs index 9e22b6c..50d841a 100644 --- a/vidyut-prakriya/tests/kaumudi_12.rs +++ b/vidyut-prakriya/tests/kaumudi_12.rs @@ -4,7 +4,6 @@ use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pratipadika; -use vidyut_prakriya::args::SamasaType::*; #[test] fn sk_440() { @@ -121,7 +120,7 @@ fn sk_442() { let jush = create_krdanta("juz", &[], &d("juzI~\\", Tudadi), Krt::kvip); // HACK: technically "saha", but use "sa" for convenience. - let sajush = create_samasa_p("sajuz", &[Pratipadika::from("sa"), jush], Bahuvrihi); + let sajush = bahuvrihi(Pratipadika::basic("sa"), jush); assert_has_sup_1s(&sajush, Stri, &["sajUH"]); assert_has_sup_1d(&sajush, Stri, &["sajuzO"]); assert_has_sup_1p(&sajush, Stri, &["sajuzaH"]); diff --git a/vidyut-prakriya/tests/kaumudi_13.rs b/vidyut-prakriya/tests/kaumudi_13.rs index fda1226..f9745cf 100644 --- a/vidyut-prakriya/tests/kaumudi_13.rs +++ b/vidyut-prakriya/tests/kaumudi_13.rs @@ -2,7 +2,6 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::SamasaType::*; use vidyut_prakriya::args::{BaseKrt as Krt, Unadi}; #[test] @@ -140,7 +139,7 @@ fn sk_446() { assert_has_sup_3s(&havis, Napumsaka, &["havizA"]); assert_has_sup_3d(&havis, Napumsaka, &["havirByAm"]); - let pipathis = create_krdanta("pipaWiz", &[], &san(&d("paWa~", Bhvadi)), Krt::kvip); + let pipathis = krdanta(&[], &san(&d("paWa~", Bhvadi)), Krt::kvip); assert_has_sup_1s(&pipathis, Napumsaka, &["pipaWIH"]); assert_has_sup_1d(&pipathis, Napumsaka, &["pipaWizI"]); assert_has_sup_1p(&pipathis, Napumsaka, &["pipaWizi"]); @@ -152,7 +151,7 @@ fn sk_446() { assert_has_sup_3s("payas", Napumsaka, &["payasA"]); assert_has_sup_3d("payas", Napumsaka, &["payoByAm"]); - let supums = create_samasa("supums", &["su", "pums"], Bahuvrihi); + let supums = bahuvrihi("su", "pums"); assert_has_sup_1s(&supums, Napumsaka, &["supum"]); assert_has_sup_1d(&supums, Napumsaka, &["supuMsI"]); assert_has_sup_1p(&supums, Napumsaka, &["supumAMsi"]); diff --git a/vidyut-prakriya/tests/kaumudi_49.rs b/vidyut-prakriya/tests/kaumudi_49.rs index d76403a..b804c8c 100644 --- a/vidyut-prakriya/tests/kaumudi_49.rs +++ b/vidyut-prakriya/tests/kaumudi_49.rs @@ -3,7 +3,6 @@ use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; -#[ignore] #[test] fn sk_2543() { let rudh = d("ru\\Di~^r", Rudhadi); diff --git a/vidyut-prakriya/tests/kaumudi_57.rs b/vidyut-prakriya/tests/kaumudi_57.rs new file mode 100644 index 0000000..d3184da --- /dev/null +++ b/vidyut-prakriya/tests/kaumudi_57.rs @@ -0,0 +1,108 @@ +extern crate test_utils; +use test_utils::*; +use vidyut_prakriya::args::Lakara::*; +use vidyut_prakriya::args::{Dhatu, Pratipadika, Sanadi}; + +fn p(text: &str) -> Pratipadika { + Pratipadika::Basic(text.to_string(), false) +} + +fn kyac(pratipadika: Pratipadika) -> Dhatu { + Dhatu::nama(pratipadika, Some(Sanadi::kyac)) +} + +fn kamyac(pratipadika: Pratipadika) -> Dhatu { + Dhatu::nama(pratipadika, Some(Sanadi::kAmyac)) +} + +fn nama(pratipadika: Pratipadika) -> Dhatu { + Dhatu::nama(pratipadika, None) +} + +#[test] +fn skip_sk_2657() {} + +#[test] +fn sk_2658() { + assert_has_tip(&[], &kyac(p("putra")), Lat, &["putrIyati"]); + assert_has_tip(&[], &kyac(p("go")), Lat, &["gavyati"]); + assert_has_tip(&[], &kyac(p("nO")), Lat, &["nAvyati"]); +} + +#[ignore] +#[test] +fn sk_2659() { + let gavya = kyac(p("go")); + assert_has_tip( + &[], + &gavya, + Lit, + &["gavyAYcakAra", "gavyAmAsa", "gavyAmbaBUva"], + ); + assert_has_tip(&[], &gavya, Lut, &["gavyitA"]); + + let navya = kyac(p("nO")); + assert_has_tip( + &[], + &navya, + Lit, + &["nAvyAYcakAra", "nAvyAmAsa", "nAvyAmbaBUva"], + ); + assert_has_tip(&[], &navya, Lut, &["nAvyitA"]); + + assert_has_tip(&[], &kyac(p("rAjan")), Lat, &["rAjIyati"]); + assert_has_tip(&[], &kyac(p("tvad")), Lat, &["tvadyati"]); + assert_has_tip(&[], &kyac(p("mad")), Lat, &["madyati"]); + assert_has_tip(&[], &kyac(p("yuzmad")), Lat, &["yuzmadyati"]); + assert_has_tip(&[], &kyac(p("asmad")), Lat, &["asmadyati"]); + + assert_has_tip(&[], &kyac(p("gir")), Lat, &["gIryati"]); + assert_has_tip(&[], &kyac(p("pur")), Lat, &["pUryati"]); + assert_has_tip(&[], &kyac(p("div")), Lat, &["divyati"]); + assert_has_tip(&[], &kyac(p("adas")), Lat, &["adasyati"]); + assert_has_tip(&[], &kyac(p("kartf")), Lat, &["kartrIyati"]); + // assert_has_tip(&[], &kyac(p("kartf")), Lat, &["gargIyati"]); + assert_has_tip(&[], &kyac(p("vAc")), Lat, &["vAcyati"]); + assert_has_tip(&[], &kyac(p("kavi")), Lat, &["kavIyati"]); + assert_has_tip(&[], &kyac(p("samiD")), Lat, &["samiDyati"]); +} + +#[test] +fn sk_2663() { + assert_has_tip(&[], &kamyac(p("putra")), Lat, &["putrakAmyati"]); + assert_has_tip(&[], &kamyac(p("yaSas")), Lat, &["yaSaskAmyati"]); + assert_has_tip(&[], &kamyac(p("sarpis")), Lat, &["sarpizkAmyati"]); + assert_has_tip(&[], &kamyac(p("kim")), Lat, &["kiNkAmyati"]); + assert_has_tip(&[], &kamyac(p("svar")), Lat, &["svaHkAmyati"]); +} + +#[test] +fn sk_2664() { + assert_has_tip(&[], &kyac(p("putra")), Lat, &["putrIyati"]); + assert_has_tip(&[], &kyac(p("vizRu")), Lat, &["vizRUyati"]); + assert_has_tip(&[], &kyac(p("prAsAda")), Lat, &["prAsAdIyati"]); + assert_has_tip(&[], &kyac(p("kuwI")), Lat, &["kuwIyati"]); +} + +#[test] +fn skip_sk_2668() {} + +#[test] +fn sk_2670() { + assert_has_ta(&[], &nama(p("kazwa")), Lat, &["kazwAyate"]); + assert_has_ta(&[], &nama(p("satra")), Lat, &["satrAyate"]); + assert_has_ta(&[], &nama(p("kakza")), Lat, &["kakzAyate"]); +} + +#[test] +fn sk_2671() { + assert_has_ta(&[], &nama(p("romanTa")), Lat, &["romanTAyate"]); + assert_has_tip(&[], &nama(p("tapas")), Lat, &["tapasyati"]); +} + +#[test] +fn sk_2672() { + assert_has_ta(&[], &nama(p("bAzpa")), Lat, &["bAzpAyate"]); + assert_has_ta(&[], &nama(p("uzma")), Lat, &["uzmAyate"]); + assert_has_ta(&[], &nama(p("Pena")), Lat, &["PenAyate"]); +} diff --git a/vidyut-prakriya/tests/kaumudi_8.rs b/vidyut-prakriya/tests/kaumudi_8.rs index 8cc0b39..6837a82 100644 --- a/vidyut-prakriya/tests/kaumudi_8.rs +++ b/vidyut-prakriya/tests/kaumudi_8.rs @@ -5,7 +5,9 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pratipadika; -use vidyut_prakriya::args::SamasaType::*; +use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::Unadi; +use vidyut_prakriya::args::Vibhakti; #[test] fn skip_sk_178_to_sk_186() {} @@ -115,7 +117,7 @@ fn sk_212() { assert_has_sup_6s("rAma", Pum, &["rAmasya"]); let pis = create_krdanta("pis", &[], &d("pisf~", Bhvadi), Krt::kvip); - let supis = create_samasa_p("supis", &[Pratipadika::from("su"), pis], Bahuvrihi); + let supis = bahuvrihi(Pratipadika::basic("su"), pis); assert_has_sup_1s(&supis, Pum, &["supIH"]); assert_has_sup_1d(&supis, Pum, &["supisO"]); assert_has_sup_1p(&supis, Pum, &["supisaH"]); @@ -226,13 +228,13 @@ fn sk_237() { #[ignore] #[test] fn sk_238() { - let dvyahan = create_samasa("dvyahan", &["dvi", "ahan"], Tatpurusha); + let dvyahan = tatpurusha("dvi", "ahan", Vibhakti::Prathama); assert_has_sup_7s(&dvyahan, Pum, &["dvyahni", "dvyahani", "dvyahne"]); - let vyahan = create_samasa("vyahan", &["vi", "ahan"], Tatpurusha); + let vyahan = tatpurusha("vi", "ahan", Vibhakti::Prathama); assert_has_sup_7s(&vyahan, Pum, &["vyahni", "vyahani", "vyahne"]); - let sayahan = create_samasa("sAyAhan", &["sAya", "ahan"], Tatpurusha); + let sayahan = tatpurusha("sAya", "ahan", Vibhakti::Prathama); assert_has_sup_7s(&sayahan, Pum, &["sAyAhni", "sAyAhani", "sAyahne"]); let vishvapa = create_upapada_krdanta("viSvapA", "viSva", &[], &d("pA\\", Adadi), Krt::vic); @@ -277,8 +279,15 @@ fn sk_242() { #[test] fn sk_243() { + let vataprami = create_upapada_krdanta( + "vAtapramI", + "vAta", + &["pra"], + &d("mA\\N", Juhotyadi), + Krt::kvip, + ); assert_has_sup_4s("mati", Stri, &["mataye", "matyE"]); - assert_has_sup_4s(&dhatu_prati("vAtapramI"), Pum, &["vAtapramye"]); + assert_has_sup_4s(&vataprami, Pum, &["vAtapramye"]); assert_has_sup_4s("mAtf", Stri, &["mAtre"]); } @@ -371,6 +380,55 @@ fn sk_264() { assert_has_sup_7p("tri", Pum, &["trizu"]); } +#[ignore] +#[test] +fn sk_265() { + assert_has_sup_1d("dvi", Pum, &["dvO"]); + assert_has_sup_2d("dvi", Pum, &["dvO"]); + assert_has_sup_3d("dvi", Pum, &["dvAByAm"]); + assert_has_sup_4d("dvi", Pum, &["dvAByAm"]); + assert_has_sup_5d("dvi", Pum, &["dvAByAm"]); + assert_has_sup_6d("dvi", Pum, &["dvayoH"]); + assert_has_sup_7d("dvi", Pum, &["dvayoH"]); + + let bhavat = create_krdanta("Bavat", &[], &d("BA\\", Adadi), Unadi::qavatu); + assert_has_sup_1s(&bhavat, Pum, &["BavAn"]); + assert_has_sup_1d(&bhavat, Pum, &["BavantO"]); + assert_has_sup_1p(&bhavat, Pum, &["BavantaH"]); + + // TODO: dviH, dvI + let audulomi = taddhitanta("uquloman", T::iY); + assert_has_sup_1s(&audulomi, Pum, &["OqulomiH"]); + assert_has_sup_1d(&audulomi, Pum, &["OqulomI"]); + // TODO: others + assert_has_sup_2s(&audulomi, Pum, &["Oqulomim"]); + assert_has_sup_2d(&audulomi, Pum, &["OqulomI"]); + + let vataprami = create_upapada_krdanta( + "vAtapramI", + "vAta", + &["pra"], + &d("mA\\N", Juhotyadi), + Krt::kvip, + ); + assert_has_sup_1s(&vataprami, Pum, &["vAtapramIH"]); + assert_has_sup_1d(&vataprami, Pum, &["vAtapramyO"]); + assert_has_sup_1p(&vataprami, Pum, &["vAtapramyaH"]); + assert_has_sup_ss(&vataprami, Pum, &["vAtapramIH"]); + assert_has_sup_2s(&vataprami, Pum, &["vAtapramIm"]); + assert_has_sup_2d(&vataprami, Pum, &["vAtapramyO"]); + assert_has_sup_2p(&vataprami, Pum, &["vAtapramIn"]); + assert_has_sup_3s(&vataprami, Pum, &["vAtapramyA"]); + assert_has_sup_3d(&vataprami, Pum, &["vAtapramIByAm"]); + assert_has_sup_4s(&vataprami, Pum, &["vAtapramye"]); + assert_has_sup_5s(&vataprami, Pum, &["vAtapramyaH"]); + assert_has_sup_6s(&vataprami, Pum, &["vAtapramyaH"]); + assert_has_sup_6d(&vataprami, Pum, &["vAtapramyoH"]); + assert_has_sup_7d(&vataprami, Pum, &["vAtapramyoH"]); + assert_has_sup_7d(&vataprami, Pum, &["vAtapramyAm"]); + assert_has_sup_7p(&vataprami, Pum, &["vAtapramIzu"]); +} + #[test] fn skip_sk_266() {} @@ -390,12 +448,13 @@ fn sk_269() { assert_has_sup_6p("bahuSreyasI", Pum, &["bahuSreyasInAm"]); } -#[ignore] #[test] fn sk_270() { assert_has_sup_7s("bahuSreyasI", Pum, &["bahuSreyasyAm"]); assert_has_sup_1s("atilakzmI", Pum, &["atilakzmIH"]); - // TODO: kumArI + + let kumari = nyap("kumArI"); + assert_has_sup_1s(&kumari, Pum, &["kumArI"]); } #[test] diff --git a/vidyut-prakriya/tests/kaumudi_9.rs b/vidyut-prakriya/tests/kaumudi_9.rs index bba1c52..16ebc8c 100644 --- a/vidyut-prakriya/tests/kaumudi_9.rs +++ b/vidyut-prakriya/tests/kaumudi_9.rs @@ -6,14 +6,14 @@ use vidyut_prakriya::args::Linga::*; #[test] fn sk_287() { - let rama = create_stryanta("ramA", "rama"); + let rama = nyap("ramA"); assert_has_sup_1d(&rama, Stri, &["rame"]); assert_has_sup_1p(&rama, Stri, &["ramAH"]); } #[test] fn sk_288() { - let rama = create_stryanta("ramA", "rama"); + let rama = nyap("ramA"); assert_has_sup_ss(&rama, Stri, &["rame"]); assert_has_sup_sd(&rama, Stri, &["rame"]); assert_has_sup_sp(&rama, Stri, &["ramAH"]); @@ -24,7 +24,7 @@ fn sk_288() { #[test] fn sk_289() { - let rama = create_stryanta("ramA", "rama"); + let rama = nyap("ramA"); assert_has_sup_3s(&rama, Stri, &["ramayA"]); assert_has_sup_3d(&rama, Stri, &["ramAByAm"]); assert_has_sup_3p(&rama, Stri, &["ramABiH"]); @@ -32,7 +32,7 @@ fn sk_289() { #[test] fn sk_290() { - let rama = create_stryanta("ramA", "rama"); + let rama = nyap("ramA"); assert_has_sup_4s(&rama, Stri, &["ramAyE"]); assert_has_sup_6s(&rama, Stri, &["ramAyAH"]); assert_has_sup_6d(&rama, Stri, &["ramayoH"]); @@ -67,12 +67,39 @@ fn sk_299() { assert_has_sup_2p("tri", Stri, &["tisraH"]); } -#[ignore] #[test] fn sk_300() { assert_has_sup_6p("tri", Stri, &["tisfRAm"]); assert_has_sup_7p("tri", Stri, &["tisfzu"]); - // TODO: others + + // TODO: more priyatri variants + let priyatri = bahuvrihi("priya", "tri"); + assert_has_sup_1s(&priyatri, Stri, &["priyatisA"]); + assert_has_sup_1d(&priyatri, Stri, &["priyatisrO"]); + assert_has_sup_1p(&priyatri, Stri, &["priyatisraH"]); + assert_has_sup_2s(&priyatri, Stri, &["priyatisram"]); + assert_has_sup_1s(&priyatri, Napumsaka, &["priyatri"]); + + assert_has_sup_1s("gOra", Stri, &["gOrI"]); + assert_has_sup_1d("gOra", Stri, &["gOryO"]); + assert_has_sup_1p("gOra", Stri, &["gOryaH"]); + assert_has_sup_ss("gOra", Stri, &["gOri"]); + assert_has_sup_4s("gOra", Stri, &["gOryE"]); + + assert_has_sup_1s("saKi", Stri, &["saKI"]); + assert_has_sup_1d("saKi", Stri, &["saKyO"]); + assert_has_sup_1p("saKi", Stri, &["saKyaH"]); + + assert_has_sup_1s("lakzmI", Stri, &["lakzmIH"]); + // SezaM gOrIvat + assert_has_sup_1d("lakzmI", Stri, &["lakzmyO"]); + assert_has_sup_1p("lakzmI", Stri, &["lakzmyaH"]); + assert_has_sup_ss("lakzmI", Stri, &["lakzmi"]); + assert_has_sup_4s("lakzmI", Stri, &["lakzmyE"]); + + let stri = nyap("strI"); + assert_has_sup_1s(&stri, Stri, &["strI"]); + assert_has_sup_ss(&stri, Stri, &["stri"]); } #[test] @@ -92,7 +119,6 @@ fn sk_303() { #[test] fn skip_sk_305() {} -#[ignore] #[test] fn sk_306() { assert_has_sup_1s("krozwu", Stri, &["krozwrI"]); @@ -101,5 +127,18 @@ fn sk_306() { assert_has_sup_1s("vaDU", Stri, &["vaDUH"]); assert_has_sup_1s("BU", Stri, &["BUH"]); - assert_has_sup_ss("suBrU", Stri, &["suBrUH"]); + + let subhru = create_bahuvrihi("suBrU", "su", "BrU"); + assert_has_sup_ss(&subhru, Stri, &["suBrUH"]); + // See commentary for "suBru" in the Bhattikavya. + + assert_has_sup_1s("KalapU", Stri, &["KalapUH"]); + + let punarbhu = create_bahuvrihi("punarBU", "punar", "BU"); + assert_has_sup_1s(&punarbhu, Stri, &["punarBUH"]); + + assert_has_sup_ss(&punarbhu, Stri, &["punarBu"]); + assert_has_sup_2s(&punarbhu, Stri, &["punarBvam"]); + assert_has_sup_2d(&punarbhu, Stri, &["punarBvO"]); + assert_has_sup_2p(&punarbhu, Stri, &["punarBvaH"]); } diff --git a/vidyut-prakriya/tests/regressions.rs b/vidyut-prakriya/tests/regressions.rs new file mode 100644 index 0000000..5eab206 --- /dev/null +++ b/vidyut-prakriya/tests/regressions.rs @@ -0,0 +1,26 @@ +//! Derivations that aren't captured in our other tests. +extern crate test_utils; +use test_utils::*; +use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Lakara::*; + +#[test] +fn ambibat() { + assert_has_tip(&[], &d("abi~", Curadi), Lun, &["Ambibat"]); +} + +#[test] +fn aucicchat() { + assert_has_tip(&[], &nic(&d("uCI~", Tudadi)), Lun, &["OcicCat"]); +} + +#[test] +fn urjijiayizati() { + // Given as Urj in sk. + assert_has_tip(&[], &san(&d("Urja~", Curadi)), Lat, &["Urjijayizati"]); +} + +#[test] +fn titikzizati() { + assert_has_ta(&[], &san(&d("tija~\\", Bhvadi)), Lat, &["titikzizate"]); +} diff --git a/vidyut-prakriya/tests/sanadi_tinantas.rs b/vidyut-prakriya/tests/sanadi_tinantas.rs index 15213c2..75689ef 100644 --- a/vidyut-prakriya/tests/sanadi_tinantas.rs +++ b/vidyut-prakriya/tests/sanadi_tinantas.rs @@ -16,7 +16,8 @@ fn create_sanadyanta(upadesha: &str, gana: &str, sanadi: Sanadi) -> Vec .build() .unwrap(); - let args = TinantaArgs::builder() + let args = Tinanta::builder() + .dhatu(dhatu) .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) .vacana(Vacana::Eka) @@ -24,7 +25,7 @@ fn create_sanadyanta(upadesha: &str, gana: &str, sanadi: Sanadi) -> Vec .build() .unwrap(); - let prakriyas = a.derive_tinantas(&dhatu, &args); + let prakriyas = a.derive_tinantas(&args); prakriyas.iter().map(|p| p.text()).collect() } @@ -35,7 +36,7 @@ fn run_sanadi_test_cases(cases: &[(&str, u8, &str)], sanadi: Sanadi) { expected.sort(); let mut actual: Vec<_> = create_sanadyanta(dhatu, &gana.to_string(), sanadi); - if sanadi == Sanadi::Nic { + if sanadi == Sanadi::Ric { // All Nijantas are ubhayapadI, so to simplify the tests, focus on just parasmaipada. actual.retain(|x| x.ends_with("ti")); } @@ -133,5 +134,5 @@ fn san_tinantas() { ("kfpU~\\", 1, "cikxpsati|cikalpizate|cikxpsate"), ]; - run_sanadi_test_cases(cases, Sanadi::San); + run_sanadi_test_cases(cases, Sanadi::san); } diff --git a/vidyut-prakriya/www/static/app.js b/vidyut-prakriya/www/static/app.js index 30dae31..7b88c02 100644 --- a/vidyut-prakriya/www/static/app.js +++ b/vidyut-prakriya/www/static/app.js @@ -18,48 +18,50 @@ * hacky way if that fixes the problem. */ -import init, { Krt, Vidyut, Gana, Lakara, Prayoga, Purusha, Vacana, Pada, Sanadi, Linga, Vibhakti } from "/static/wasm/vidyut_prakriya.js"; +import init, { BaseKrt, Vidyut, Gana, Lakara, Prayoga, Purusha, Vacana, DhatuPada, Sanadi, Linga, Vibhakti } from "/static/wasm/vidyut_prakriya.js"; // Krts that create ordinary nouns. const NOMINAL_KRTS = [ - Krt.GaY, - Krt.lyuw, - Krt.Rvul, - Krt.tfc, - Krt.kvip, + BaseKrt.GaY, + BaseKrt.lyuw, + BaseKrt.Rvul, + BaseKrt.tfc, + BaseKrt.kvip, ]; // Krts that are generally called *participles*. const PARTICIPLE_KRTS = [ - Krt.tavya, - Krt.anIyar, - Krt.yat, - Krt.Ryat, + BaseKrt.tavya, + BaseKrt.anIyar, + BaseKrt.yat, + BaseKrt.Ryat, - Krt.Satf, - Krt.SAnac, + BaseKrt.Satf, + BaseKrt.SAnac, - Krt.kta, - Krt.ktavatu, + BaseKrt.kta, + BaseKrt.ktavatu, - Krt.kvasu, - Krt.kAnac, + BaseKrt.kvasu, + BaseKrt.kAnac, ]; // Krts that create avyayas. const AVYAYA_KRTS = [ - Krt.tumun, - Krt.ktvA, - Krt.Ramul, + BaseKrt.tumun, + BaseKrt.ktvA, + BaseKrt.Ramul, ]; +// What to call these params in the URL. const Params = { Dhatu: "dhatu", Tab: "tab", - Pada: "pada", + DhatuPada: "pada", Prayoga: "prayoga", Sanadi: "sanadi", ActivePada: "activePada", + Upasarga: "upasarga", } // Turn the TSV file sutrapatha.tsv into a map. @@ -103,7 +105,7 @@ function createKrdantasFrom(vidyut, dhatu, upasarga, sanadi, krtList) { }); }); results.push({ - title: Krt[krt], + title: BaseKrt[krt], padas, }); }); @@ -255,7 +257,7 @@ const App = () => ({ setParam(url, Params.ActivePada, null); } - console.log("updateUrlState to: ", url); + console.log("updateUrlState to: ", url.href); history.replaceState(null, document.title, url.toString()); }, @@ -470,12 +472,12 @@ const App = () => ({ const dhatu = this.activeDhatu; const lakaras = Object.values(Lakara).filter(Number.isInteger); - const tinPadas = Object.values(Pada).filter(Number.isInteger); + const tinPadas = Object.values(DhatuPada).filter(Number.isInteger); const prayoga = this.prayoga !== null ? this.prayoga : Prayoga.Kartari; const sanadi = this.sanadi || null;; const upasarga = this.upasarga || null;; - console.log("createTinantas", prayoga, sanadi, upasarga); + console.log("createTinantas", prayoga, this.sanadi, upasarga); let results = []; for (const lakara in lakaras) { let laResults = { @@ -483,7 +485,7 @@ const App = () => ({ }; for (const tinPada in tinPadas) { - const padaKey = Pada[tinPada]; + const padaKey = DhatuPada[tinPada]; const paradigm = this.createParadigm({ dhatu, lakara, diff --git a/vidyut-prakriya/www/templates/index.html b/vidyut-prakriya/www/templates/index.html index d381773..1273e97 100644 --- a/vidyut-prakriya/www/templates/index.html +++ b/vidyut-prakriya/www/templates/index.html @@ -130,7 +130,6 @@

- @@ -142,9 +141,10 @@

diff --git a/vidyut-sandhi/Cargo.toml b/vidyut-sandhi/Cargo.toml index b9b76ea..775d5f8 100644 --- a/vidyut-sandhi/Cargo.toml +++ b/vidyut-sandhi/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] clap = { version = "4.0.12", features = ["derive"] } -compact_str = "0.6.1" +compact_str = "0.7.1" csv = "1.1.6" lazy_static = "1.4.0" rustc-hash = "1.1.0"