From 6ebc5bfd4ec5b136a92ffb86b2f0bd6fa6752bc1 Mon Sep 17 00:00:00 2001 From: Arun Prasad Date: Sat, 16 Sep 2023 18:43:50 -0700 Subject: [PATCH] [prakriya] Refactor dhatu logic Our previous rule ordering made certain derivations impossible. This commit standardizes our rule order as follows: 1. We create a complete sanadi dhatu before adding any other pratyayas. 2. Generally, we apply guna before applying dvitva. Along the way, we found and corrected a variety of small errors and substantially increased our rule coverage and unit test coverage: Rules: ~1094 --> ~1196 Unit tests: 755 --> 973 --- vidyut-prakriya/.gitignore | 1 + vidyut-prakriya/Makefile | 16 +- vidyut-prakriya/README.md | 2 +- vidyut-prakriya/data/dhatupatha.tsv | 2 +- vidyut-prakriya/src/ac_sandhi.rs | 52 +- vidyut-prakriya/src/angasya.rs | 256 +++++--- vidyut-prakriya/src/angasya/abhyasasya.rs | 166 +++-- vidyut-prakriya/src/angasya/asiddhavat.rs | 208 +++++-- vidyut-prakriya/src/angasya/guna_vrddhi.rs | 146 +++-- vidyut-prakriya/src/angasya/sup_adesha.rs | 10 +- vidyut-prakriya/src/ardhadhatuka.rs | 38 +- vidyut-prakriya/src/args/dhatu.rs | 39 -- vidyut-prakriya/src/args/krt.rs | 68 ++- vidyut-prakriya/src/args/sup.rs | 15 + vidyut-prakriya/src/args/taddhita.rs | 145 ++++- vidyut-prakriya/src/ashtadhyayi.rs | 177 +++--- vidyut-prakriya/src/atidesha.rs | 8 + vidyut-prakriya/src/atmanepada.rs | 89 ++- vidyut-prakriya/src/dhatu_gana.rs | 4 +- vidyut-prakriya/src/dhatu_karya.rs | 5 +- vidyut-prakriya/src/dhatupatha.rs | 6 +- vidyut-prakriya/src/dvitva.rs | 149 ++--- vidyut-prakriya/src/errors.rs | 6 +- vidyut-prakriya/src/filters.rs | 3 +- vidyut-prakriya/src/it_agama.rs | 19 +- vidyut-prakriya/src/krt/basic.rs | 136 ++++- vidyut-prakriya/src/krt/unadi_sutras.rs | 95 ++- vidyut-prakriya/src/krt/utils.rs | 57 +- vidyut-prakriya/src/la_karya.rs | 1 + vidyut-prakriya/src/lib.rs | 4 +- vidyut-prakriya/src/prakriya.rs | 55 +- vidyut-prakriya/src/pratipadika_karya.rs | 3 + vidyut-prakriya/src/samjna.rs | 67 ++- vidyut-prakriya/src/samprasarana.rs | 97 ++- vidyut-prakriya/src/sanadi.rs | 61 +- vidyut-prakriya/src/sounds.rs | 34 +- vidyut-prakriya/src/stem_gana.rs | 4 +- vidyut-prakriya/src/taddhita.rs | 12 + vidyut-prakriya/src/taddhita/basic.rs | 497 +++++++++++++++ vidyut-prakriya/src/taddhita/gana.rs | 343 +++++++++++ vidyut-prakriya/src/taddhita/utils.rs | 79 +++ vidyut-prakriya/src/taddhita_gana.rs | 181 ------ vidyut-prakriya/src/taddhita_pratyaya.rs | 225 ------- vidyut-prakriya/src/tag.rs | 10 + vidyut-prakriya/src/term.rs | 148 ++++- vidyut-prakriya/src/tin_pratyaya.rs | 43 +- vidyut-prakriya/src/tripadi/pada_8_2.rs | 74 ++- vidyut-prakriya/src/tripadi/pada_8_3.rs | 8 +- vidyut-prakriya/src/tripadi/pada_8_4.rs | 6 +- vidyut-prakriya/src/uttarapade.rs | 20 + vidyut-prakriya/src/vikarana.rs | 74 ++- vidyut-prakriya/test_utils/src/lib.rs | 126 +++- vidyut-prakriya/tests/basic_krdantas.rs | 6 +- vidyut-prakriya/tests/basic_tinantas.rs | 7 +- vidyut-prakriya/tests/pada_1_1.rs | 191 +++++- vidyut-prakriya/tests/pada_1_2.rs | 82 ++- vidyut-prakriya/tests/pada_1_3.rs | 292 ++++++++- vidyut-prakriya/tests/pada_1_4.rs | 135 ++++- vidyut-prakriya/tests/pada_2_3.rs | 39 +- vidyut-prakriya/tests/pada_2_4.rs | 81 ++- vidyut-prakriya/tests/pada_3_1.rs | 121 +++- vidyut-prakriya/tests/pada_3_2.rs | 17 +- vidyut-prakriya/tests/pada_3_3.rs | 51 +- vidyut-prakriya/tests/pada_3_4.rs | 192 +++--- vidyut-prakriya/tests/pada_4_1.rs | 381 +++++++++++- vidyut-prakriya/tests/pada_4_4.rs | 24 + vidyut-prakriya/tests/pada_5_1.rs | 34 +- vidyut-prakriya/tests/pada_5_2.rs | 43 +- vidyut-prakriya/tests/pada_5_3.rs | 56 +- vidyut-prakriya/tests/pada_5_4.rs | 92 +++ vidyut-prakriya/tests/pada_6_1.rs | 252 +++++++- vidyut-prakriya/tests/pada_6_3.rs | 39 +- vidyut-prakriya/tests/pada_6_4.rs | 665 ++++++++++++++++++--- vidyut-prakriya/tests/pada_7_1.rs | 243 ++++---- vidyut-prakriya/tests/pada_7_2.rs | 206 ++++--- vidyut-prakriya/tests/pada_7_3.rs | 141 +++-- vidyut-prakriya/tests/pada_7_4.rs | 547 +++++++++++++++-- vidyut-prakriya/tests/pada_8_2.rs | 320 +++++++++- vidyut-prakriya/tests/pada_8_3.rs | 15 +- vidyut-prakriya/tests/pada_8_4.rs | 29 +- vidyut-prakriya/tests/regressions.rs | 52 +- vidyut-prakriya/tests/sanadi_tinantas.rs | 6 +- vidyut-prakriya/tests/unadi_sutras.rs | 54 +- 83 files changed, 6754 insertions(+), 1749 deletions(-) create mode 100644 vidyut-prakriya/.gitignore create mode 100644 vidyut-prakriya/src/taddhita.rs create mode 100644 vidyut-prakriya/src/taddhita/basic.rs create mode 100644 vidyut-prakriya/src/taddhita/gana.rs create mode 100644 vidyut-prakriya/src/taddhita/utils.rs delete mode 100644 vidyut-prakriya/src/taddhita_gana.rs delete mode 100644 vidyut-prakriya/src/taddhita_pratyaya.rs create mode 100644 vidyut-prakriya/src/uttarapade.rs create mode 100644 vidyut-prakriya/tests/pada_4_4.rs create mode 100644 vidyut-prakriya/tests/pada_5_4.rs diff --git a/vidyut-prakriya/.gitignore b/vidyut-prakriya/.gitignore new file mode 100644 index 0000000..b1b3aa4 --- /dev/null +++ b/vidyut-prakriya/.gitignore @@ -0,0 +1 @@ +www/static/* diff --git a/vidyut-prakriya/Makefile b/vidyut-prakriya/Makefile index 2491e14..57c7adb 100644 --- a/vidyut-prakriya/Makefile +++ b/vidyut-prakriya/Makefile @@ -53,28 +53,28 @@ test_tinantas: cargo build --release ../target/release/test_tinantas \ --test-cases test-files/tinantas-basic-kartari.csv \ - --hash "72f94a7fa706cb5b2c96b0f74baa17f1a0c263d96cb92edc669f244dfabafcb2" + --hash "ab8ff253c90d44461bd71c9681d748141d77685758282ea04484966fb1014bfa" ../target/release/test_tinantas \ - --test-cases test-files/tinantas-nic-kartari.csv \ - --hash "c16ff79b6041e25a3297a614611515537020712341febb340e30ace459a8104b" + --test-cases test-files/tinantas-nic-kartari.csv \ + --hash "f8a3b4c50eb88eda52db0a6936ff694168d1a80408a015d71561ab88b0e43269" ../target/release/test_tinantas \ --test-cases test-files/tinantas-san-kartari.csv \ - --hash "ba174c9268b8be00262dd1f856161b2cb505b515c4e232feb70cb711eb6ce652" + --hash "04bfbbd22493ae53c7d15c753131242d3923c4d4d5e1aee847665cb87bb2d9f1" ../target/release/test_tinantas \ --test-cases test-files/tinantas-yan-kartari.csv \ - --hash "1645ee474a8e370b6cd1a5d487092f2cc84864afd706e2a1ddabea6a8e4c49e3" + --hash "2679e81f6a1e3a2957df5a4fdd6b8bd9666d42d1fb79ab5122ad02bd3e8dd7f2" ../target/release/test_tinantas \ --test-cases test-files/tinantas-basic-karmani.csv \ - --hash "a2bbcd572c04973eee057d58a0caf93ea84fb8eb18845633ce4ef271a0abdffd" + --hash "cfb9bf65e38289abc3119f839e41615ecd2bb7f548a8ef78a45cd3d24c183d59" test_krdantas: cargo build --release ../target/release/test_krdantas \ --test-cases test-files/krdantas-ktvA.csv \ - --hash "8b7e855313d13de73b34c55e1c41daad262575365d2a5748c2469de09a3df15a" + --hash "e8be9f718fa56dd602be71166d1bcfd24da054e77dd2cd628dedda1b004bc4f8" ../target/release/test_krdantas \ --test-cases test-files/krdantas-kta.csv \ - --hash "b13cefedbb913354a12b47ff6ae4187c335e2ebe73066b601ac7eeb32c10ea2a" + --hash "223db03e3c5bd4492919cf8fd27d09fd23c0660449df6596bcf6c6dbe9c45caa" test_subantas: cargo run --bin test_subantas -- \ diff --git a/vidyut-prakriya/README.md b/vidyut-prakriya/README.md index 26b7ac9..ea90312 100644 --- a/vidyut-prakriya/README.md +++ b/vidyut-prakriya/README.md @@ -122,7 +122,7 @@ can take in the comments on the `Rule` type. We suggest using `ashtadhyayi.com` to learn more about these rules. The right column shows the in-progress prakriya. We use an output convention -that is common on other Ashtadhyayi websites. The encoding foromat for this +that is common on other Ashtadhyayi websites. The encoding format for this text is SLP1, which is the encoding format we use throughout the crate. [sv]: https://github.com/drdhaval2785/SanskritVerb diff --git a/vidyut-prakriya/data/dhatupatha.tsv b/vidyut-prakriya/data/dhatupatha.tsv index 3a900b2..d9756b2 100644 --- a/vidyut-prakriya/data/dhatupatha.tsv +++ b/vidyut-prakriya/data/dhatupatha.tsv @@ -1636,7 +1636,7 @@ code dhatu artha 06.0165 mila~^ saNgame 06.0166 mu\cx~^ mokzaRe 06.0167 lu\px~^ Cedane -06.0168 vidx~^ lABe +06.0168 vi\dx~^ lABe 06.0169 li\pa~^ upadehe 06.0170 zi\ca~^ kzaraRe 06.0171 kftI~ Cedane diff --git a/vidyut-prakriya/src/ac_sandhi.rs b/vidyut-prakriya/src/ac_sandhi.rs index 668798f..7a594e7 100644 --- a/vidyut-prakriya/src/ac_sandhi.rs +++ b/vidyut-prakriya/src/ac_sandhi.rs @@ -22,6 +22,7 @@ lazy_static! { static ref EC: Set = s("ec"); static ref VAL: Set = s("val"); static ref HAL: Set = s("hal"); + static ref YAN: Set = s("yaR"); } pub fn try_lopo_vyor_vali(p: &mut Prakriya) { @@ -37,9 +38,11 @@ pub fn try_lopo_vyor_vali(p: &mut Prakriya) { let t = 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. + // // For now, just check if the term is a dhatu. let is_upadesha_adi = t.is_dhatu() && (t.has_adi('v') || t.has_adi('y')); - vyor_vali && !is_upadesha_adi + vyor_vali && !is_upadesha_adi && !t.is_pratipadika() }, |p, _, i| { set_at(p, i, ""); @@ -92,10 +95,21 @@ pub fn apply_general_ac_sandhi(p: &mut Prakriya) { }, ); + // HACK: ignore sandhi between upasarga and dhatu so that we can correctly derive prARinat, + // etc. + fn is_upasarga_sanadi_dhatu(p: &Prakriya, i: usize) -> bool { + get_at(p, i).expect("present").is_upasarga() + && p.terms().last().expect("present").is_dhatu() + } + char_rule( p, xy(|x, y| AK.contains(x) && AK.contains(y) && al::savarna(x).contains(y)), |p, text, i| { + if is_upasarga_sanadi_dhatu(p, i) { + return false; + } + let x = text.as_bytes()[i] as char; set_at(p, i, &al::to_dirgha(x).expect("should be ac").to_string()); set_at(p, i + 1, ""); @@ -165,14 +179,19 @@ pub fn apply_general_ac_sandhi(p: &mut Prakriya) { p, xy(|x, y| A.contains(x) && AC.contains(y)), |p, text, i| { + 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) { - set_at(p, j, al::to_vrddhi(y).expect("should be set")); + set_at(p, j, al::to_vrddhi(y).expect("should have vrddhi")); set_at(p, i, ""); p.step("6.1.88"); } else { - set_at(p, j, al::to_guna(y).expect("should be set")); + set_at(p, j, al::to_guna(y).expect("should have guna")); set_at(p, i, ""); p.step("6.1.87"); } @@ -361,7 +380,30 @@ fn hacky_apply_ni_asiddhavat_rules(p: &mut Prakriya) -> Option<()> { Some(()) } -pub fn run_common(p: &mut Prakriya) { +/// Runs antaranga ac-sandhi rules. +/// +/// (Example: div -> dyU + sa -> dudyUzati) +pub fn run_antaranga(p: &mut Prakriya) -> Option<()> { + for i in 0..p.terms().len() { + let cur = p.get(i)?; + if cur.has_upadha(&*IK) && cur.has_antya(&*AC) { + let x = cur.upadha()?; + let res = match x { + 'i' | 'I' => "y", + 'u' | 'U' => "v", + 'f' | 'F' => "r", + 'x' | 'X' => "l", + _ => panic!("Unexpected res"), + }; + p.op_term("6.1.77", i, |t| t.set_upadha(res)); + } + } + + p.maybe_save_sthanivat(); + Some(()) +} + +pub fn run_common(p: &mut Prakriya) -> Option<()> { try_ver_aprktasya(p); for i in 0..p.terms().len() { @@ -372,4 +414,6 @@ pub fn run_common(p: &mut Prakriya) { hacky_apply_ni_asiddhavat_rules(p); try_sut_kat_purva(p); + + Some(()) } diff --git a/vidyut-prakriya/src/angasya.rs b/vidyut-prakriya/src/angasya.rs index 7c6eeca..01f24dc 100644 --- a/vidyut-prakriya/src/angasya.rs +++ b/vidyut-prakriya/src/angasya.rs @@ -16,6 +16,7 @@ mod asiddhavat; mod guna_vrddhi; mod sup_adesha; +use crate::args::Lakara; pub use asiddhavat::try_cinvat_for_bhave_and_karmani_prayoga; use crate::ac_sandhi; @@ -32,6 +33,7 @@ use crate::sounds::{s, Set}; use crate::stem_gana; use crate::tag::Tag as T; use crate::term::Term; +use compact_str::CompactString; use lazy_static::lazy_static; lazy_static! { @@ -74,7 +76,10 @@ fn try_do_dirgha(p: &mut Prakriya, i_anga: usize) -> Option<()> { } else if anga.has_u("kramu~") && n.has_u("ktvA") { // krantvA, krAntvA p.op_optional("6.4.18", op::t(i_anga, |t| t.set_upadha("A"))); - } else if (anga.has_antya(&*AC) || anga.has_u_in(&["ha\\na~", "ga\\mx~"])) && n.has_u("san") { + } else if (anga.has_antya(&*AC) || anga.has_u_in(&["ha\\na~", "ga\\mx~", "gami~"])) + && n.has_u("san") + { + // Also include "gami~" to match adhi-i -> adhi-gam let code = "6.4.16"; if anga.has_antya(&*AC) { let sub = al::to_dirgha(anga.antya()?)?; @@ -160,10 +165,6 @@ pub fn try_run_dirgha_for_sarvanamasthane_asambuddhau( let sub = al::to_dirgha(anga.upadha()?)?; p.op_term("6.4.8", i, op::upadha(&sub.to_string())); } - } else if anga.ends_with("as") && sau && !anga.is_dhatu() { - // TODO: atu- - let sub = al::to_dirgha(anga.upadha()?)?; - p.op_term("6.4.14", 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)?)?; @@ -183,6 +184,32 @@ pub fn try_run_dirgha_for_sarvanamasthane_asambuddhau( Some(()) } +/// Runs various rules that cause dirgha-adesha in the anga. +/// This specific dirgha-adesha must occur before inserting num-agama. +/// +/// Example: gomat -> gomAt -> gomAnt -> gomAn +fn try_dirgha_adesha_before_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 sau = sup.has_u("su~"); + let is_atu = anga.has_tag(T::udit) && anga.ends_with("at"); + + if sup.has_tag(T::Sarvanamasthana) && !sup.has_tag(T::Sambuddhi) { + if (is_atu || anga.ends_with("as")) && sau && !anga.is_dhatu() { + let sub = al::to_dirgha(anga.upadha()?)?; + p.op_term("6.4.14", i_anga, op::upadha(&sub.to_string())); + } + } + + 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())?; @@ -217,17 +244,11 @@ fn try_dirgha_adesha_for_sup(p: &mut Prakriya) -> Option<()> { Some(()) } -/// Runs rules that cause dirgha-adesha in the anga. -/// -/// 6.4.2 - 6.4.19 -fn try_dirgha_adesha(p: &mut Prakriya) { - try_dirgha_adesha_for_sup(p); -} - /// Applies rules that replace an initial "J" in a pratyaya with the appropriate sounds. /// /// (7.1.3 - 7.1.7) -fn maybe_do_jha_adesha(p: &mut Prakriya, i: usize) -> Option<()> { +pub fn maybe_do_jha_adesha(p: &mut Prakriya) -> Option<()> { + let i = p.terms().len() - 1; let tin = p.get_if(i, |t| t.has_adi('J'))?; let i_base = p.find_prev_where(i, |t| !t.is_empty())?; @@ -251,8 +272,8 @@ fn maybe_do_jha_adesha(p: &mut Prakriya, i: usize) -> Option<()> { // Serate p.op("7.1.6", add_rut); it_samjna::run(p, i).ok()?; - } else if base.has_u("vida~") && base.has_gana_int(2) { - // vidrate + } else if base.has_u("vida~") && base.has_gana(Adadi) { + // vidate, vidrate if p.op_optional("7.1.7", add_rut) { it_samjna::run(p, i).ok()?; } @@ -300,8 +321,6 @@ pub fn try_pratyaya_adesha(p: &mut Prakriya) -> Option<()> { } } else if let Some(sub) = replace_pha_dha_and_others(last) { p.op_term("7.1.2", i, op::adi(sub)); - } else if last.has_adi('J') { - maybe_do_jha_adesha(p, i); } else if last.has_adi('W') { // Run 7.3.50 because it has no clear place otherwise. p.op_term("7.3.50", i, |t| t.set_adi("ik")); @@ -351,7 +370,7 @@ fn try_shiti(p: &mut Prakriya) -> Option<()> { if anga.has_antya('o') && n.has_u("Syan") { // Syati p.op_term("7.3.71", i, op::antya("")); - } else if anga.has_u_in(gana::SHAM_ADI) && n.has_u("Syan") && anga.has_gana_int(4) { + } else if anga.has_u_in(gana::SHAM_ADI) && n.has_u("Syan") && anga.has_gana(Divadi) { // Check ganas to avoid `Bramu~ anavasTAne` (BrAmyati). p.op_term("7.3.74", i, op::upadha("A")); } else if anga.has_u_in(&["zWivu~", "klamu~"]) @@ -372,7 +391,7 @@ fn try_shiti(p: &mut Prakriya) -> Option<()> { } else if anga.has_u_in(&["izu~", "ga\\mx~", "ya\\ma~"]) { // icCati, gacCati, yacCati p.op_term("7.3.77", i, op::antya("C")); - } else if anga.has_u_in(pa_ghra) && !anga.has_gana_int(2) && !anga.has_gana_int(3) { + } else if anga.has_u_in(pa_ghra) && !anga.has_gana(Adadi) && !anga.has_gana(Juhotyadi) { // Check ganas above to avoid `pA rakzaRe` (pAti), `f gatO` (iyarti) let to_piba_jighra = |p: &mut Prakriya| { let anga = p.get(i).expect("ok"); @@ -399,7 +418,18 @@ fn try_shiti(p: &mut Prakriya) -> Option<()> { } else if anga.has_u_in(&["jYA\\", "janI~\\"]) { // jAnAti, jAyate p.op_term("7.3.79", i, op::text("jA")); - } else if anga.has_u_in(gana::PU_ADI) && (anga.has_gana(Svadi) || anga.has_gana(Kryadi)) { + } + + Some(()) +} + +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 _n = p.get_if(i_n, |t| t.has_tag(T::Sit))?; + + let anga = p.get(i)?; + if anga.has_u_in(gana::PU_ADI) && (anga.has_gana(Svadi) || anga.has_gana(Kryadi)) { // punAti, stfRAti, riRAti // All of these dhatus end in vowels. p.op_term("7.3.80", i, |t| { @@ -445,7 +475,7 @@ fn try_add_agamas_to_sup(p: &mut Prakriya) -> Option<()> { } else if anga.has_text("tri") { // trayaH p.op_term("7.1.53", i_anga, op::text("traya")); - } else if anga.is_hrasva() || anga.has_tag(T::StriNyap) { + } else if anga.is_hrasva() || anga.has_tag(T::Nadi) || anga.has_tag(T::StriNyap) { p.op("7.1.54", |p| op::insert_agama_before(p, i_last, "nu~w")); it_samjna::run(p, i_last).ok()?; } else if anga.has_tag(T::Sat) || anga.has_text("catur") { @@ -497,11 +527,20 @@ fn try_add_num_agama_for_dhatu(p: &mut Prakriya) -> Option<()> { let anga = p.get(i)?; let n = p.view(i + 1)?; let liti = n.has_lakshana("li~w"); - if anga.has_u("qula\\Ba~\\z") { + if anga.has_u("qula\\Ba~\\z") && anga.has_text("laB") { let yi = n.has_adi('y'); let has_upasarga = p.find_prev_where(i, |t| t.is_upasarga()).is_some(); - if !has_upasarga && n.has_u_in(&["ciR", "Ramu~l"]) { + if has_upasarga && i == 1 && p.has(i - 1, |t| t.has_u_in(&["su", "dur"])) { + // sulABa, durlABa + p.step("7.1.68"); + } else if n.has_u_in(&["Kal", "GaY"]) { + if has_upasarga { + // pralamBa, ... + p.op_term("7.1.67", i, op::mit("n")); + } + // Otherwise, we get lABa, etc. + } else if !has_upasarga && n.has_u_in(&["ciR", "Ramu~l"]) { p.op_optional("7.1.69", op::t(i, op::mit("n"))); } else if n.has_adi(&*AC) && !n.has_u("Sap") && !liti { p.op_term("7.1.64", i, op::mit("n")); @@ -511,13 +550,13 @@ fn try_add_num_agama_for_dhatu(p: &mut Prakriya) -> Option<()> { p.op_optional("7.1.66", op::t(i, op::mit("n"))); } } else if n.has_adi(&*AC) { - if anga.has_u_in(&["ra\\Da~", "jaBI~\\"]) { + if anga.has_text("raD") || (anga.has_text("jaB") && anga.has_u("jaBI~\\")) { if anga.has_u("ra\\Da~") && n.first()?.is_it_agama() && !liti { p.step("7.1.62"); } else { p.op_term("7.1.61", i, op::mit("n")); } - } else if anga.has_u("ra\\Ba~\\") && !n.has_u("Sap") && !liti { + } else if anga.has_u("ra\\Ba~\\") && anga.has_text("raB") && !n.has_u("Sap") && !liti { p.op_term("7.1.63", i, op::mit("n")); } } @@ -537,7 +576,7 @@ fn try_add_num_agama_for_dhatu(p: &mut Prakriya) -> Option<()> { /// /// Skipped: 7.3.97 ("bahulam chandasi") /// TODO: 7.3.99 - 100 -pub fn iit_agama(p: &mut Prakriya) -> Option<()> { +pub fn try_add_iit_agama(p: &mut Prakriya) -> Option<()> { let i_last = p.terms().len() - 1; let i_anga = p.find_prev_where(i_last, |t| !t.is_empty() && !t.is_agama())?; let i_pratyaya_start = p.find_next_where(i_anga, |t| !t.is_empty())?; @@ -553,7 +592,8 @@ pub fn iit_agama(p: &mut Prakriya) -> Option<()> { let mut rule = None; if anga.has_text("brU") && piti { rule = Some("7.3.93"); - } else if anga.has_u("yaN") && piti { + } else if p.has(i_anga + 1, |t| t.has_u("yaN")) && piti { + // HACK: use `i_anga + 1` to point to yaN, which is empty due to luk. rule = maybe_rule(p, "7.3.94"); } else if anga.has_u_in(&["tu\\", "ru", "zwu\\Y", "Samu~", "ama~"]) { rule = maybe_rule(p, "7.3.95"); @@ -637,6 +677,9 @@ fn try_change_dhatu_before_y(p: &mut Prakriya) -> Option<()> { let dhatu = p.get(i)?; let n = p.view(i_n)?; + let mut temp = CompactString::new(""); + temp.replace_range(.., &dhatu.text); + let akrt_sarva = !n.has_tag_in(&[T::Sarvadhatuka, T::Krt]); let has_upasarga = i > 0 && p.has(i - 1, |t| t.has_tag(T::Upasarga)); let yi_kniti = n.has_adi('y') && n.is_knit(); @@ -645,6 +688,7 @@ fn try_change_dhatu_before_y(p: &mut Prakriya) -> Option<()> { p.op_term("7.4.21", i, op::text("Se")); } else if dhatu.has_u("SIN") && yi_kniti { p.op_term("7.4.22", i, op::text("Say")); + p.set(i, |t| t.force_save_sthanivat()); } else if has_upasarga && yi_kniti && dhatu.has_u("Uha~\\") { // Example: sam[u]hyate p.op_term("7.4.23", i, op::adi("u")); @@ -785,12 +829,14 @@ fn unknown(p: &mut Prakriya, i: usize) -> Option<()> { let anga = p.get(i)?; let n = p.view(i + 1)?; - if anga.has_u("SIN") { + if anga.has_u("SIN") && anga.has_text("SI") { if n.is_knit() && n.has_adi('y') { p.op_term("7.4.22", i, op::antya("ay")); + p.set(i, |t| t.force_save_sthanivat()); } else if n.has_tag(T::Sarvadhatuka) { let sub = al::to_guna(anga.antya()?)?; p.op_term("7.4.22", i, op::antya(sub)); + p.set(i, |t| t.force_save_sthanivat()); } } @@ -912,7 +958,7 @@ fn try_change_cu_to_ku(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } -fn dhatu_rt_adesha(p: &mut Prakriya, i: usize) -> Option<()> { +fn try_dhatu_rt_adesha(p: &mut Prakriya, i: usize) -> Option<()> { let dhatu = p.get_if(i, |t| t.is_dhatu())?; if dhatu.has_antya('F') { @@ -921,10 +967,13 @@ fn dhatu_rt_adesha(p: &mut Prakriya, i: usize) -> Option<()> { } else { p.op_term("7.1.100", i, op::antya("ir")); } + } else if dhatu.has_upadha('F') { + p.op_term("7.1.101", i, op::upadha("ir")); + } else { + return None; } Some(()) - // HACK: 7.1.101 is performed before dvitva. } /// Runs rules that lengthen the last `a` of the anga when certain suffixes follow. @@ -1090,6 +1139,7 @@ fn try_sic_vrddhi(p: &mut Prakriya) -> Option<()> { Some(()) } +/// Tries replacement of f/F with f, which blocks guna. fn try_cani_before_guna(p: &mut Prakriya) -> Option<()> { let i = p.find_first(T::Dhatu)?; @@ -1103,8 +1153,12 @@ fn try_cani_before_guna(p: &mut Prakriya) -> Option<()> { None => false, }; + // In anticipation of a caN-vikarana that we will add later, also apply this rule if we will + // apply cani in the future. (acikIrtat, acIkftat) + let will_be_cani = is_nici && p.has_lakara(Lakara::Lun); + // 7.4.7 blocks guna. - if dhatu.has_upadha(&*FF) && is_nici && is_cani { + if dhatu.has_upadha(&*FF) && is_nici && (is_cani || will_be_cani) { p.op_optional( "7.4.7", op::t(i, |t| { @@ -1117,18 +1171,11 @@ fn try_cani_before_guna(p: &mut Prakriya) -> Option<()> { Some(()) } -pub fn hacky_before_dvitva(p: &mut Prakriya) { - try_cani_before_guna(p); - - for i in 0..p.terms().len() { - if p.has(i, |t| t.is_dhatu() && t.has_upadha('F')) { - p.op_term("7.1.101", i, op::upadha("ir")); - } - } -} - /// Runs rules that condition on a following caN-pratyaya (luN-vikarana). /// +/// For notes on ordering, see S. C. Vasu's commentary on this rule. Briefly, these rules should +/// apply before dvitva. +/// /// (7.4.1 - 7.4.6) fn try_cani_after_guna(p: &mut Prakriya) -> Option<()> { // Our dhatu search should also supported duplicated ac-Adi roots, e.g. uDras -> u + Da + Dras. @@ -1153,6 +1200,28 @@ fn try_cani_after_guna(p: &mut Prakriya) -> Option<()> { return Some(()); } + let dhatu = p.get(i)?; + let mut done = false; + if i > 0 && dhatu.has_u("pA\\") && dhatu.has_gana(Bhvadi) { + // apIpyat + p.op("7.4.4", |p| { + p.set(i, |t| t.set_antya("")); + p.set(i - 1, |t| t.set_antya("I")); + }); + done = true; + } else if i > 0 && dhatu.has_u("zWA\\") { + // atizWapat + p.op_term("7.4.5", i, |t| t.set_antya("i")); + done = true; + } else if i > 0 && dhatu.has_u("GrA\\") { + // ajiGripat, ajiGrapat + done = p.op_optional("7.4.6", op::t(i, |t| t.set_antya("i"))); + } + + if done { + return Some(()); + } + let dhatu = p.get(i)?; if dhatu.has_upadha(&*AC) && !dhatu.has_upadha(&*FF) { // Ignore 'f' because it is handled by 7.4.7. @@ -1172,7 +1241,7 @@ fn try_cani_after_guna(p: &mut Prakriya) -> Option<()> { Some(()) } -/// Runs rules conditioned on a following aN-pratyaya (luN-vikarana). +/// Runs rules that change the anga when an aN-pratyaya (luN-vikarana) follows. /// /// (7.4.16 - 7.4.20) fn try_change_anga_before_an(p: &mut Prakriya) -> Option<()> { @@ -1185,21 +1254,26 @@ fn try_change_anga_before_an(p: &mut Prakriya) -> Option<()> { let dhatu = p.get(i)?; if dhatu.has_antya(&*FF) || dhatu.has_text("dfS") { + // asarat, adarSat if dhatu.has_text("dfS") { p.op_term("7.4.16", i, op::text("darS")); } else { p.op_term("7.4.16", i, op::antya("ar")); } } else if dhatu.has_u("asu~") { + // AsTat p.op("7.4.17", |p| { p.insert_after(i, Term::make_agama("Tu~k")); it_samjna::run(p, i + 1).expect("ok"); }); } else if dhatu.has_text("Svi") { + // aSvat p.op_term("7.4.18", i, op::antya("a")); } else if dhatu.has_text("pat") { + // apaptat p.op_term("7.4.19", i, op::mit("p")); } else if dhatu.has_text("vac") { + // avocat p.op_term("7.4.20", i, op::mit("u")); } @@ -1236,7 +1310,10 @@ fn try_ksa_lopa(p: &mut Prakriya) -> Option<()> { fn try_add_agama_before_ni(p: &mut Prakriya) -> Option<()> { let i = p.find_first(T::Dhatu)?; let dhatu = p.get(i)?; - let ni = p.get(i + 1)?; + + // Check explicitly that ni-pratyaya is the *last* term so that we don't try applying these + // rules again after adding a tin/krt pratyaya. + let ni = p.terms().last()?; if !ni.is_ni_pratyaya() { return None; @@ -1478,7 +1555,57 @@ fn try_pratyaya_adesha_for_dhatu(p: &mut Prakriya) -> Option<()> { Some(()) } -pub fn run_before_dvitva(_p: &mut Prakriya) -> Option<()> { +pub fn run_before_dvitva(p: &mut Prakriya) -> Option<()> { + try_add_iit_agama(p); + try_shiti(p); + + try_add_num_agama_for_dhatu_before_asiddhavat(p); + for i in 0..p.terms().len() { + asiddhavat::run_before_guna(p, i); + } + + // Must follow asiddhavat rules 6.4.37 and 6.4.42. + for i in 0..p.terms().len() { + try_do_dirgha(p, i); + } + // Must follow `try_do_dirgha` (6.4.2). + try_pvadinam_hrasva(p); + + // Agama can block guna. + try_add_agama_before_ni(p); + // tuk-Agama can block guna. + try_add_tuk_agama(p); + // Rit-tva can block guna. + try_add_or_remove_nit(p); + + // num-Agama must come after asiddhavat rule 6.4.24, which causes na-lopa. + // Exception: naS num-Agama, which is deleted in 6.4.32; + try_add_num_agama_for_dhatu(p); + + try_sic_vrddhi(p); + try_cani_before_guna(p); + + p.debug("==== Guna-vrddhi ===="); + guna_vrddhi::run(p); + + try_change_dhatu_before_y(p); + try_cchvoh(p); + + // Must precede ft-AdeSa (f -> ir) + try_change_anga_before_an(p); + + // Substitutions for `f` and `F` + for index in 0..p.terms().len() { + try_dhatu_rt_adesha(p, index); + } + + for i in 0..p.terms().len() { + asiddhavat::run_after_guna(p, i); + } + + // Must run before dvitva. + try_cani_after_guna(p); + Some(()) } @@ -1489,10 +1616,15 @@ pub fn run_after_dvitva(p: &mut Prakriya) -> Option<()> { try_add_agamas_to_sup(p); samjna::try_run_for_pada_or_bha(p); asiddhavat::bhasya(p); + try_dirgha_adesha_before_num_agama(p); try_add_num_agama_for_sarvanamasthana(p); sup_adesha::run_after_bhasya(p); try_anga_adesha_after_vibhakti_changes(p); + for i in 0..p.terms().len() { + asiddhavat::run_after_dvitva(p, i); + } + // TODO: move this rule to a better place. { let i = p.terms().len() - 1; @@ -1510,30 +1642,12 @@ pub fn run_after_dvitva(p: &mut Prakriya) -> Option<()> { // Must come before asiddhavat rule 6.4.78 (e.g. "iyarti", ekahalmadhya) abhyasasya::run(p); - try_add_num_agama_for_dhatu_before_asiddhavat(p); - for i in 0..p.terms().len() { - asiddhavat::run_before_guna(p, i); - } - - // Must follow asiddhavat rules 6.4.37 and 6.4.42. - for i in 0..p.terms().len() { - try_do_dirgha(p, i); - } - - try_shiti(p); - - // num-Agama must come after asiddhavat rule 6.2.24, which causes na-lopa. - // Exception: naS num-Agama, which is deleted in 6.4.32; - try_add_num_agama_for_dhatu(p); - try_sic_vrddhi(p); - try_add_agama_before_ni(p); - - // Must occur before guna and after 7.3.77 (gam -> gacC). + // ADDED for ciccheda, etc. try_add_tuk_agama(p); - try_cchvoh(p); + // must apply before guna for knUy --> knopayati ac_sandhi::try_lopo_vyor_vali(p); - try_add_or_remove_nit(p); + // try_add_or_remove_nit(p); for i in 0..p.terms().len() { unknown(p, i); @@ -1542,12 +1656,7 @@ pub fn run_after_dvitva(p: &mut Prakriya) -> Option<()> { try_didhi_vevi_lopa(p, i); } - guna_vrddhi::run(p); - - try_change_dhatu_before_y(p); try_dhatu_changes_for_ti_kiti(p); - // Rules for various lun-vikaranas. - try_change_anga_before_an(p); // Asiddhavat must run before cani for "Ner aniTi" asiddhavat::run_for_ni(p); @@ -1556,16 +1665,15 @@ pub fn run_after_dvitva(p: &mut Prakriya) -> Option<()> { try_change_cu_to_ku(p, i); } - try_cani_after_guna(p); abhyasasya::run_for_sani_or_cani(p); for index in 0..p.terms().len() { try_ato_dirgha(p, index); - asiddhavat::run_after_guna(p, index); - dhatu_rt_adesha(p, index); + asiddhavat::run_final(p, index); + try_dhatu_rt_adesha(p, index); } - try_dirgha_adesha(p); + try_dirgha_adesha_for_sup(p); Some(()) } diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index b69a74a..6bdf817 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -18,6 +18,7 @@ use compact_str::CompactString; use lazy_static::lazy_static; lazy_static! { + static ref AA: Set = s("a"); static ref AC: Set = s("ac"); static ref ANUNASIKA: Set = s("Yam"); static ref UU: Set = s("u"); @@ -118,12 +119,24 @@ fn try_abhyasa_lopa_and_dhatu_change_before_san(p: &mut Prakriya) -> Option<()> /// `i` is the index of an abhyasa.. fn run_for_sani_or_cani_at_index(p: &mut Prakriya, i: usize) -> Option<()> { + const SMR_DR: &[&str] = &[ + "smf", + "dF", + "YitvarA~\\", + "praTa~", + "mrada~\\", + "stFY", + // TODO: include both spaS dhAtus? + "spaSa~^", + "spaSa~", + ]; + let i_abhyasta = p.find_next_where(i, |t| t.has_tag(T::Abhyasta))?; - let abhyasa = p.get(i)?; let anga = p.get(i_abhyasta)?; - let is_laghu = anga.is_laghu(); + // quick HACK for jAgr + let is_laghuni = anga.is_laghu() && !anga.text.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()) @@ -131,33 +144,43 @@ fn run_for_sani_or_cani_at_index(p: &mut Prakriya, i: usize) -> Option<()> { let is_cani = p .find_next_where(i_abhyasta + 1, |t| t.has_u("caN")) .is_some(); - let is_laghu_cani = is_ni && is_laghu && is_cani && !has_at_lopa; + let is_laghu_cani = is_ni && is_laghuni && is_cani && !has_at_lopa; let is_sanvat = is_laghu_cani || p.find_next_where(i, |t| t.has_u("san")).is_some(); - let smf_df = &["smf", "dF", "tvar", "praT", "mrad", "stF", "spaS"]; - let sravati_etc = &["sru\\", "Sru\\", "dru\\", "pru\\N", "plu\\N", "cyu\\N"]; - - // Run rules that generally apply to san. - if is_sanvat { - if abhyasa.has_antya('a') { - p.op_term("7.4.79", i, op::antya("i")); - } else if abhyasa.has_antya(&*UU) && anga.has_adi(&*PU_YAN_J) && anga.get_at(1)? == 'a' { - p.op_term("7.4.80", i, op::antya("i")); - } else if anga.has_u_in(sravati_etc) && anga.has_upadha('a') { - // Example: sru -> sisrAvayizyati - // Note that this rule must run after guna for the upadha check to be meaningful. - p.op_optional("7.4.81", op::t(i, op::antya("i"))); + const SRU_ADI: &[&str] = &["sru\\", "Sru\\", "dru\\", "pru\\N", "plu\\N", "cyu\\N"]; + + let abhyasa = p.get(i)?; + let dhatu = p.get(i + 1)?; + if dhatu.has_u_in(SMR_DR) && is_cani { + // asasmarat, adadarat, + p.op_term("7.4.95", i, op::antya("a")); + } else { + if is_sanvat { + // Run rules that generally apply to san. + if abhyasa.has_antya('a') { + p.op_term("7.4.79", i, op::antya("i")); + } else if abhyasa.has_antya(&*UU) && anga.has_adi(&*PU_YAN_J) && anga.has_at(1, &*AA) { + p.op_term("7.4.80", i, op::antya("i")); + } else if anga.has_u_in(SRU_ADI) && anga.has_upadha('a') { + // Example: sru -> sisrAvayizyati + // Note that this rule must run after guna for the upadha check to be meaningful. + p.op_optional("7.4.81", op::t(i, op::antya("i"))); + } } - } - if is_laghu_cani { - let abhyasa = p.get(i)?; - let dhatu = p.get(i + 1)?; - if dhatu.has_text_in(smf_df) { - p.op_term("7.4.95", i, op::antya("a")); - } else if !dhatu.is_samyogadi() { - if let Some(sub) = al::to_dirgha(abhyasa.antya()?) { - p.op_term("7.4.94", i, op::antya(&sub.to_string())); + if is_ni && is_cani { + let abhyasa = p.get(i)?; + let dhatu = p.get(i + 1)?; + if has_at_lopa && dhatu.has_u("gaRa") { + p.op_optional("7.4.97", op::t(i, op::antya("I"))); + } else if dhatu.has_text_in(&["vezw", "cezw"]) { + p.op_optional("7.4.96", op::t(i, op::antya("a"))); + } else if is_laghu_cani { + if !dhatu.is_samyogadi() { + if let Some(sub) = al::to_dirgha(abhyasa.antya()?) { + p.op_term("7.4.94", i, op::antya(&sub.to_string())); + } + } } } } @@ -246,7 +269,8 @@ fn try_general_rules(p: &mut Prakriya, i: usize) -> Option<()> { let dhatu = p.get(i_dhatu)?; let last = p.terms().last()?; - if dhatu.has_u("i\\R") && last.has_tag(T::kit) { + if dhatu.has_u("i\\R") && last.has_tag(T::kit) && last.has_lakshana("li~w") { + // IyatuH, IyuH p.op_term("7.4.69", i, op::adi("I")); } @@ -349,16 +373,20 @@ fn try_rules_for_slu(p: &mut Prakriya, i: usize) -> Option<()> { } /// Runs rules that modify the abhyAsa for yaNanta dhAtus. -fn try_rules_for_yan(p: &mut Prakriya, i: usize) -> Option<()> { - p.find_last_where(|t| t.has_u("yaN"))?; +fn try_rules_for_yan(p: &mut Prakriya, i_abhyasa: usize) -> Option<()> { + let i_yan = p.find_last_where(|t| t.has_u("yaN"))?; - let i_dhatu = i + 1; - let abhyasa = p.get(i)?; + let i_dhatu = i_abhyasa + 1; + let abhyasa = p.get(i_abhyasa)?; + if i_yan < i_dhatu { + // e.g. if deriving "boBUyAYcakre", where "ya" comes before "kf". + return None; + } if !abhyasa.has_antya('a') { - // Avaid guna for 'a' because it causes no change to the result. + // Avoid guna for 'a' because it causes no change to the result. let sub = al::to_guna(abhyasa.antya()?)?; - p.op_term("7.4.82", i, op::antya(sub)); + p.op_term("7.4.82", i_abhyasa, op::antya(sub)); } let add_agama = |rule, p: &mut Prakriya, i_dhatu, agama| { @@ -366,9 +394,18 @@ fn try_rules_for_yan(p: &mut Prakriya, i: usize) -> Option<()> { it_samjna::run(p, i_dhatu).ok(); }; - let abhyasa = p.get(i)?; + let optional_add_agama = |rule, p: &mut Prakriya, i_dhatu, agama| -> bool { + let added = p.op_optional(rule, |p| op::insert_agama_before(p, i_dhatu, agama)); + if added { + it_samjna::run(p, i_dhatu).ok(); + } + added + }; + + let abhyasa = p.get(i_abhyasa)?; let dhatu = p.get(i_dhatu)?; - let vanc_adi = &[ + let is_yan_luk = p.has(i_yan, |t| t.is_empty()); + const VANCU_SRANSU: &[&str] = &[ "vancu~", "sransu~\\", "Dvansu~\\", @@ -378,14 +415,26 @@ fn try_rules_for_yan(p: &mut Prakriya, i: usize) -> Option<()> { "pa\\da~\\", "ska\\ndi~r", ]; - if dhatu.has_u_in(vanc_adi) { + const JAPA_JABHA: &[&str] = &[ + "japa~", "jaBI~\\", "da\\ha~", "da\\nSa~", "Ba\\njo~", "paSa~", + ]; + + if dhatu.has_u_in(VANCU_SRANSU) { add_agama("7.4.84", p, i_dhatu, "nIk"); } else if abhyasa.has_antya('a') && dhatu.has_antya(&*ANUNASIKA) { // Should treat as anusvAra per commentaries, otherwise we can't derive yaMyamyate. add_agama("7.4.85", p, i_dhatu, "Mu~k"); - } else if dhatu.has_text_in(&["jap", "jaB", "dah", "daS", "Banj", "paS"]) { + } else if dhatu.has_u_in(JAPA_JABHA) { + if dhatu.has_u("da\\nSa~") { + // > daśīti daśa iti daṃśiḥ ayaṃ nakāralopārtham eva nirdiṣṭaḥ। tena yaṅlukyapi + // > nakāralopo bhavati। + // -- KV on 7.4.86. + // + // TODO: not sure where to put this. + p.set(i_dhatu, |t| t.set_text("daS")); + } add_agama("7.4.86", p, i_dhatu, "nu~k"); - } else if dhatu.has_text_in(&["car", "Pal"]) { + } else if dhatu.has_u_in(&["cara~", "Pala~"]) { add_agama("7.4.87", p, i_dhatu, "nu~k"); // Use `i_dhatu + 1` because 7.4.87 above shifted the index. @@ -394,26 +443,47 @@ fn try_rules_for_yan(p: &mut Prakriya, i: usize) -> Option<()> { if dhatu.has_upadha('a') { p.op_term("7.4.88", i_dhatu, op::upadha("u")); } - } else if dhatu.has_upadha('f') { - add_agama("7.4.90", p, i_dhatu, "rIk"); + } else if dhatu.text.contains('f') { + // varIvfScyate, ... + // (Check for "contains and not antya" to allow pfcC, vfSc, ...) + let mut added = false; + if is_yan_luk { + added = optional_add_agama("7.4.91:ruk", p, i_dhatu, "ru~k"); + if !added { + added = optional_add_agama("7.4.91:rik", p, i_dhatu, "rik"); + } + } + if !added { + let dhatu = p.get(i_dhatu)?; + if dhatu.has_upadha('f') { + // varIvftyate, varIvftIti, ... + add_agama("7.4.90", p, i_dhatu, "rIk"); + } else if dhatu.has_antya('f') { + add_agama("7.4.92", p, i_dhatu, "rIk"); + } else { + add_agama("7.4.90.v1", p, i_dhatu, "rIk"); + } + } } else if abhyasa.has_antya('a') { - p.op_term("7.4.83", i, op::antya("A")); + p.op_term("7.4.83", i_abhyasa, op::antya("A")); } Some(()) } -fn run_at_index(p: &mut Prakriya, i: usize) { +fn run_at_index(p: &mut Prakriya, i_abhyasa: usize) { // TODO: expand for abhyasa after dhatu. - let i_dhatu = i + 1; + let i_dhatu = i_abhyasa + 1; if !p.has(i_dhatu, |t| t.is_dhatu()) { return; } - try_general_rules(p, i); - try_rules_for_lit(p, i); - try_rules_for_slu(p, i); - try_rules_for_yan(p, i); + try_general_rules(p, i_abhyasa); + try_rules_for_lit(p, i_abhyasa); + try_rules_for_slu(p, i_abhyasa); + try_rules_for_yan(p, i_abhyasa); + + p.set(i_abhyasa, |t| t.add_tag(T::Complete)); } /// Runs the abhyasa rules for all abhyasas in the prakriya. @@ -424,10 +494,10 @@ fn run_at_index(p: &mut Prakriya, i: usize) { pub fn run(p: &mut Prakriya) -> Option<()> { try_abhyasa_lopa_and_dhatu_change_before_san(p); - let mut i = p.find_first(T::Abhyasa)?; + let mut i = p.find_first_where(|t| t.is_abhyasa() && !t.has_tag(T::Complete))?; loop { run_at_index(p, i); - i = p.find_next_where(i, |t| t.has_tag(T::Abhyasa))?; + i = p.find_next_where(i, |t| t.is_abhyasa() && !t.has_tag(T::Complete))?; } } diff --git a/vidyut-prakriya/src/angasya/asiddhavat.rs b/vidyut-prakriya/src/angasya/asiddhavat.rs index 2f37769..facf0e0 100644 --- a/vidyut-prakriya/src/angasya/asiddhavat.rs +++ b/vidyut-prakriya/src/angasya/asiddhavat.rs @@ -32,6 +32,7 @@ lazy_static! { static ref UU: Set = s("u"); static ref I_U: Set = s("i u"); static ref AC: Set = s("ac"); + static ref YAN: Set = s("yaR"); static ref HAL: Set = s("hal"); static ref JHAL: Set = s("Jal"); static ref MAHAPRANA: Set = s("K G C J W Q T D P B"); @@ -122,8 +123,10 @@ pub fn try_cinvat_for_bhave_and_karmani_prayoga(p: &mut Prakriya) -> Option<()> /// Runs rules conditioned on a following knit ArdhadhAtuka suffix. /// -/// (6.4.63 - 6.4.69) -fn run_before_knit_ardhadhatuka(p: &mut Prakriya, i: usize) -> Option<()> { +/// Constraints: must run before dvitva for jehIyate (hIya -> jehIya), etc. +/// +/// (6.4.63 - 6.4.69, excluding 6.4.64) +fn run_for_kniti_ardhadhatuke_after_guna(p: &mut Prakriya, i: usize) -> Option<()> { let dhatu = p.get(i)?; let n = p.view(i + 1)?; @@ -131,13 +134,10 @@ fn run_before_knit_ardhadhatuka(p: &mut Prakriya, i: usize) -> Option<()> { let kniti_ardha = n.is_knit() && n.has_tag(T::Ardhadhatuka); if kniti_ardha && dhatu.has_u("dI\\N") && n.has_adi(&*AC) { + // upadidIyi, upadidIyAte, ... op::append_agama("6.4.63", p, i, "yu~w"); // No change to `n` index (`i + 1`) needed since `yu~w` is an agama and will will be // included in `n`. - } else if aat && n.has_adi(&*AC) && (kniti_ardha || n.first()?.is_it_agama()) { - p.op_term("6.4.64", i, op::antya("")); - } else if aat && n.has_u("yat") { - p.op_term("6.4.65", i, op::antya("I")); } else if aat && kniti_ardha { let ghu_ma = dhatu.has_tag(T::Ghu) || dhatu.has_u_in(&["mA\\", "mA\\N", "me\\N"]) @@ -146,6 +146,7 @@ fn run_before_knit_ardhadhatuka(p: &mut Prakriya, i: usize) -> Option<()> { || (dhatu.has_u("pA\\") && dhatu.has_gana(Gana::Bhvadi)); if n.has_adi(&*HAL) && ghu_ma && !dhatu.has_tag(T::FlagNaLopa) { if n.has_lakshana("li~N") { + // deyAt, DeyAt, meyAt, ... p.op_term("6.4.67", i, op::antya("e")); } else if n.has_u("lyap") { if dhatu.has_u("me\\N") { @@ -167,13 +168,36 @@ fn run_before_knit_ardhadhatuka(p: &mut Prakriya, i: usize) -> Option<()> { } if n.has_u("lyap") { + // pradAya, praDAya, pramAya, ... p.step("6.4.69"); } else if n.has_lakshana("li~N") { + // gleyAt/glAyAt;, mleyAt/mlAyAt, ... p.op_optional("6.4.68", op::t(i, op::antya("e"))); } } } + p.maybe_save_sthanivat(); + Some(()) +} + +/// Runs rules conditioned on a following knit ArdhadhAtuka suffix. +/// +/// Constraints: must run after dvitva. +fn run_for_kniti_ardhadhatuke_after_dvitva(p: &mut Prakriya, i: usize) -> Option<()> { + let dhatu = p.get(i)?; + let n = p.view(i + 1)?; + + let aat = dhatu.has_antya('A'); + let kniti_ardha = n.is_knit() && n.has_tag(T::Ardhadhatuka); + + if aat && n.has_adi(&*AC) && (kniti_ardha || n.first()?.is_it_agama()) { + // papiTa, tastTita, ... + // By 1.1.59 (dvirvacane 'ci), this rule should be applied after dvitva. + p.op_term("6.4.64", i, op::antya("")); + // 6.4.65 runs before guNa (dIya -> deya). + } + Some(()) } @@ -383,7 +407,7 @@ fn try_et_adesha_and_abhyasa_lopa_for_lit(p: &mut Prakriya, i: usize) -> Option< if is_eka_hal_madhya && is_a && is_lit && is_anadeshadi { if kniti { - // lalaBe -> leBex + // lalaBe -> leBe p.op("6.4.120", op_et_abhyasa_lopa); } else { // SaSakiTa -> SekiTa @@ -526,7 +550,8 @@ fn try_antya_nalopa(p: &mut Prakriya, i: usize) -> Option<()> { let is_anudatta = anga.has_tag(T::Anudatta); let is_tanadi = anga.has_u_in(gana::TAN_ADI); - let jhali_kniti = n.has_adi(&*JHAL) && is_knit(&n); + let kniti = is_knit(&n); + let jhali_kniti = n.has_adi(&*JHAL) && kniti; if anga.has_u("ha\\na~") && n.last()?.has_text("hi") { // jahi @@ -535,7 +560,7 @@ fn try_antya_nalopa(p: &mut Prakriya, i: usize) -> Option<()> { // TODO: other kvi-pratyayas? p.op_term("6.4.40", i, op::antya("")); } else if anga.has_u_in(&["jana~", "janI~\\", "zaRa~", "zaRu~^", "Kanu~^"]) { - if n.has_adi('y') { + if n.has_adi('y') && kniti { // sanyAt, sAyAt // "janeḥ śyani 'jñājanorjā' (7.3.79) iti nityaṃ jādeśo bhavati." // - kashikavrtti @@ -671,8 +696,12 @@ pub fn run_before_guna(p: &mut Prakriya, i: usize) -> Option<()> { p.op_term("6.4.114.v1", i, op::text("daridr")); } - try_run_kniti_for_dhatu(p, i); - run_before_knit_ardhadhatuka(p, i); + let dhatu = p.get(i)?; + let n = p.view(i + 1)?; + let aat = dhatu.has_antya('A'); + if aat && n.has_u("yat") { + p.op_term("6.4.65", i, op::antya("I")); + } Some(()) } @@ -828,12 +857,70 @@ fn try_kr_rule(p: &mut Prakriya, i: usize) -> Option<()> { /// /// (6.4.129 - 6.4.175) pub fn bhasya(p: &mut Prakriya) -> Option<()> { + const PRIYA_ADI: &[&str] = &[ + "priya", + "sTira", + "sPira", + "uru", + "bahula", + "guru", + "vfdDa", + "tfpra", + "dIrGa", + "vfndAraka", + ]; + const PRA_ADI: &[&str] = &[ + "pra", "sTa", "sPa", "var", "baMh", "gar", "varz", "trap", "drAG", "vfnd", + ]; let i = p.find_last(T::Bha)?; let bha = p.get(i)?; let next = p.get(i + 1)?; + let taddhita = next.is_taddhita(); + + if next.has_u_in(&["izWan", "imani~c", "Iyasu~n"]) { + if bha.has_text_in(&["sTUla", "dUra", "yuvan", "hrasva", "kzipra", "kzudra"]) { + // sTavizWa, ... + p.op_term("6.4.156", i, |t| { + // `rfind` to match the 'v' of `yuvan` instead of the 'y'. + let i_yan = t.text.rfind(|c| YAN.contains(c)).expect("ok"); + t.text.replace_range(i_yan.., ""); + let i_ac = t.text.find(|c| AC.contains(c)).expect("ok"); + let c = t.get_at(i_ac).expect("ok"); + t.set_at(i_ac, al::to_guna(c).expect("ok")); + }); + } else if let Some(sub) = op::yatha(&bha.text, PRIYA_ADI, PRA_ADI) { + // priya -> prezWa, ... + p.op_term("6.4.157", i, op::text(sub)); + } else if bha.has_text("bahu") { + // BUyAn, ... + let istha = p.has(i + 1, |t| t.has_u("izWan")); + p.op("6.4.158", |p| { + p.set(i, |t| t.set_text("BU")); + if !istha { + p.set(i + 1, |t| t.set_adi("")); + } + }); + if istha { + // BUyizWa + op::insert_agama_before(p, i + 1, "yi~w"); + p.step("6.4.159"); + it_samjna::run(p, i + 1).expect("ok"); + } + } else if bha.has_text("jya") { + // jyAyas + p.op_term("6.4.160", i + 1, |t| t.set_adi("A")); + } else { + // pawu -> pawizWa, pawiman, ... + p.op_term("6.4.155", i, op::ti("")); - if bha.has_text("pAd") { + let bha = p.get(i)?; + if bha.has_adi(&*HAL) && bha.is_laghu() && bha.text.contains('f') { + // pfTu -> praTizWa, praTiman, ... + p.op_term("6.4.161", i, |t| t.find_and_replace_text("f", "ra")); + } + } + } else if bha.has_text("pAd") { p.op_term("6.4.130", i, op::text("pad")); } else if bha.has_u("kvasu~") { p.op_term("6.4.131", i, op::text("us")); @@ -841,39 +928,63 @@ pub fn bhasya(p: &mut Prakriya) -> Option<()> { op::adesha("6.4.132", p, i, "Uh"); } else if bha.has_text_in(&["Svan", "yuvan", "maGavan"]) && !next.has_tag(T::Taddhita) { p.op_term("6.4.133", i, |t| t.find_and_replace_text("va", "u")); - } else if bha.ends_with("an") { - let mut blocked = false; - let n = bha.text.len(); - if n >= 4 - && (bha.get_at(n - 3)? == 'm' || bha.get_at(n - 3)? == 'v') - && HAL.contains(bha.get_at(n - 4)?) - { - p.step("6.4.137"); - blocked = true; - } else if next.has_u_in(&["Ni", "SI"]) { - blocked = p.op_optional("6.4.135", |_| {}); - } - if !blocked { - p.op_term("6.4.134", i, op::upadha("")); - } - } - - let bha = p.get(i)?; - if bha.has_antya('A') && bha.is_dhatu() { - p.op_term("6.4.140", i, op::antya("")); - } - - let bha = p.get(i)?; - let next = p.get(i + 1)?; - let taddhita = next.is_taddhita(); - if bha.has_antya('n') && taddhita { - if bha.has_text("ahan") { - if next.has_u_in(&["wac", "KA"]) { - p.op_term("6.4.145", i, op::ti("")); + } else if bha.has_antya('n') { + if taddhita { + let ani = next.has_u("aR"); + if bha.has_u_in(&[ + "sabrahmacArin", + "pIWasarpin", + "kalApin", + "kuTumin", + "tEtilin", + "jAjalin", + "lANgalin", + "SilAlin", + "SiKaRqin", + "sukarasadman", + "suparvan", + ]) { + p.op_term("6.4.144.v1", i, op::ti("")); + } else if ani && bha.ends_with("in") { + let n = bha.text.len(); + if bha.has_text_in(&["gATin", "vidaTin", "keSin", "gaRin", "paRin"]) { + // gATina, vEdATina, ... + p.step("6.4.165"); + } else if n >= 4 && bha.has_at(n - 4, &*HAL) && bha.has_at(n - 3, &*HAL) { + // SANKina, ... + p.step("6.4.166"); + } else { + // sANkUwina, ... + p.step("6.4.164"); + } + } else if ani && bha.ends_with("an") { + p.step("6.4.167"); + } else if bha.has_text("ahan") { + if next.has_u_in(&["wac", "KA"]) { + p.op_term("6.4.145", i, op::ti("")); + } + } else { + // This takes priority over 6.4.134 below. + p.op_term("6.4.144", i, op::ti("")); + } + } else if bha.ends_with("an") { + let mut blocked = false; + let n = bha.text.len(); + if n >= 4 + && (bha.text.ends_with("man") || bha.text.ends_with("van")) + && HAL.contains(bha.get_at(n - 4)?) + { + p.step("6.4.137"); + blocked = true; + } else if next.has_u_in(&["Ni", "SI"]) { + blocked = p.op_optional("6.4.135", |_| {}); + } + if !blocked { + p.op_term("6.4.134", i, op::upadha("")); } - } else { - p.op_term("6.4.144", i, op::ti("")); } + } else if bha.has_antya('A') && bha.is_dhatu() { + p.op_term("6.4.140", i, op::antya("")); } else if bha.has_antya(&*UU) && taddhita { if next.has_tag(T::Qit) && !bha.has_text("kadrU") { p.op_term("6.4.147", i, |t| t.set_antya("")); @@ -898,6 +1009,17 @@ pub fn bhasya(p: &mut Prakriya) -> Option<()> { } pub fn run_after_guna(p: &mut Prakriya, i: usize) -> Option<()> { + run_for_kniti_ardhadhatuke_after_guna(p, i); + Some(()) +} + +pub fn run_after_dvitva(p: &mut Prakriya, i: usize) -> Option<()> { + run_for_kniti_ardhadhatuke_after_dvitva(p, i); + try_run_kniti_for_dhatu(p, i); + Some(()) +} + +pub fn run_final(p: &mut Prakriya, i: usize) -> Option<()> { run_for_final_i_or_u(p, i); try_run_kniti(p, i); diff --git a/vidyut-prakriya/src/angasya/guna_vrddhi.rs b/vidyut-prakriya/src/angasya/guna_vrddhi.rs index 4dc8d83..c29d759 100644 --- a/vidyut-prakriya/src/angasya/guna_vrddhi.rs +++ b/vidyut-prakriya/src/angasya/guna_vrddhi.rs @@ -4,7 +4,7 @@ use crate::prakriya::Prakriya; use crate::sounds as al; use crate::sounds::{s, Set}; use crate::tag::Tag as T; -use crate::term::{Term, TermView}; +use crate::term::Term; use lazy_static::lazy_static; lazy_static! { @@ -24,25 +24,52 @@ fn op_antya_guna(t: &mut Term) { } /// Tests whether a term can use guna and vrddhi in the general case. -fn can_use_guna_or_vrddhi(anga: &Term, n: &TermView) -> bool { - // 1.1.5 kNiti ca - let kniti = n.is_knit(); - - // 1.1.6 dIdhI-vevI-iTAm - let didhi_vevi_itam = anga.has_u_in(&["dIDIN", "vevIN"]) || anga.is_it_agama(); - - let blocked = anga.has_tag_in(&[T::FlagAtLopa, T::FlagGunaApavada]); - let is_pratyaya = n.has_tag(T::Pratyaya); - - !didhi_vevi_itam && !kniti && !blocked && is_pratyaya +fn can_use_guna_or_vrddhi_opt(p: &Prakriya, i_anga: usize) -> Option { + let anga = p.get(i_anga)?; + let i_next = p.find_next_where(i_anga, |t| !t.is_empty() && !t.has_u("pu~k"))?; + let n = p.view(i_next)?; + + if anga.has_tag_in(&[T::FlagAtLopa, T::FlagGunaApavada]) { + Some(false) + } else if p.has(i_anga + 1, |t| t.is_dhatu() && t.is_empty()) && n.has_tag(T::Ardhadhatuka) { + // 1.1.4 na DAtulopa ArDaDAtuke + Some(false) + } else if n.is_knit() { + // 1.1.5 kNiti ca + Some(false) + } else if anga.has_u_in(&["dIDIN", "vevIN"]) || anga.is_it_agama() { + // 1.1.6 dIdhI-vevI-iTAm + Some(false) + } else { + // Otherwise, 1.1.3 iko guNavRddhI + Some(n.has_tag(T::Pratyaya)) + } +} - // Otherwise, 1.1.3 iko guNavRddhI +fn can_use_guna_or_vrddhi(p: &Prakriya, i: usize) -> bool { + return can_use_guna_or_vrddhi_opt(p, i).unwrap_or(true); } +/// Tries rules that cause vrddhi when a taddhita-pratyaya follows. fn try_taddhita_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { + const DVARA_ADI: &[&str] = &[ + "dvAra", "svara", "svADyAya", "vyalkaSa", "svasti", "svar", "sPyakfta", "Svas", "Svan", + "sva", + ]; + let anga = p.get(i)?; let n = p.get_if(i + 1, |t| t.is_taddhita())?; + if anga.has_text_in(&["devikA", "SiMSapA", "dityavAh", "dIrGasatra", "Sreyas"]) { + // dAvikA, ... + let adi_ac = anga.text.find(al::is_ac)?; + p.op_term("7.3.1", i, |t| { + t.set_at(adi_ac, "A"); + }); + + return Some(()); + } + let rule = if n.has_tag_in(&[T::Yit, T::Rit]) { Some("7.2.117") } else if n.has_tag(T::kit) { @@ -52,12 +79,24 @@ fn try_taddhita_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { }; if let Some(rule) = rule { - let adi_ac = anga.text.find(al::is_ac)?; - let ac = anga.get_at(adi_ac)?; - let vrddhi = al::to_vrddhi(ac)?; - p.op_term(rule, i, |t| { - t.set_at(adi_ac, vrddhi); - }); + if anga.has_u_in(DVARA_ADI) { + // dvAra -> dOvArika, ... + p.op_term("7.3.4", i, |t| { + let i_yan = t.text.rfind(|c| c == 'y' || c == 'v').expect("ok"); + if t.text.get(i_yan..i_yan + 1) == Some("y") { + t.text.insert(i_yan, 'E'); + } else { + t.text.insert(i_yan, 'O'); + } + }); + } else { + let adi_ac = anga.text.find(al::is_ac)?; + let ac = anga.get_at(adi_ac)?; + let vrddhi = al::to_vrddhi(ac)?; + p.op_term(rule, i, |t| { + t.set_at(adi_ac, vrddhi); + }); + } } Some(()) @@ -71,7 +110,7 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { let anga = p.get(i)?; let n = p.view(i + 1)?; - if !n.has_tag_in(&[T::Yit, T::Rit]) || !can_use_guna_or_vrddhi(anga, &n) { + if !n.has_tag_in(&[T::Yit, T::Rit]) || !can_use_guna_or_vrddhi(p, i) { // 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") { @@ -118,7 +157,7 @@ fn try_nnit_vrddhi(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } -/// Tries rules that replace an anga's vowel with its corresponding vrddhi. +/// 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<()> { @@ -127,7 +166,9 @@ fn try_vrddhi_adesha(p: &mut Prakriya, i: usize) -> Option<()> { let n = p.view(i_n)?; if dhatu.has_text("mfj") && !n.is_knit() { - p.op_term("7.2.114", i, op::text("mArj")); + if can_use_guna_or_vrddhi(p, i) { + p.op_term("7.2.114", i, op::text("mArj")); + } } else if n.first()?.is_taddhita() { try_taddhita_vrddhi(p, i); } else { @@ -140,15 +181,11 @@ 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| { - // HACK: allow yaN for beBiditf, etc. (6.4.49) - (!t.is_empty() && !t.has_u("pu~k")) || t.has_u("yaN") - })?; + let j = p.find_next_where(i, |t| !t.is_empty() && !t.has_u("pu~k"))?; let anga = p.get_if(i, |t| !t.is_agama() && !t.has_tag(T::FlagGunaApavada))?; let n = p.view(j)?; - let can_use_guna = can_use_guna_or_vrddhi(anga, &n); let is_sarva_ardha = n.has_tag_in(&[T::Sarvadhatuka, T::Ardhadhatuka]); let piti_sarvadhatuke = n.all(&[T::pit, T::Sarvadhatuka]); let is_ik = anga.has_antya(&*IK); @@ -171,6 +208,7 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { } else if is_sarva_ardha { let anga = p.get(i)?; let n = p.view(j)?; + let can_use_guna = can_use_guna_or_vrddhi(p, i); // Exceptions if anga.has_text_in(&["BU", "sU"]) && n.has_tag(T::Tin) && piti_sarvadhatuke { @@ -201,6 +239,7 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { let is_laghu_upadha = anga.has_upadha(&*HRASVA); let is_puganta = p.has(i + 1, |t| t.has_u("pu~k")); + // HACK to ignore antya A and avoid applying guna to it. if can_use_guna && (is_puganta || is_laghu_upadha) { if anga.is_abhyasta() && piti_sarvadhatuke && n.has_adi(&*AC) { // e.g. nenijAma @@ -209,16 +248,21 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { let code = "7.3.86"; if is_puganta { let sub = al::to_guna(anga.antya()?)?; - p.op_term(code, i, |t| { - t.set_antya(sub); - t.add_tag(T::FlagGuna); - }); + // Ignore 'a/A' by "iko gunavRddhI" + if !(sub == "a" || sub == "A") { + p.op_term(code, i, |t| { + t.set_antya(sub); + t.add_tag(T::FlagGuna); + }); + } } else { let sub = al::to_guna(anga.upadha()?)?; - p.op_term(code, i, |t| { - t.set_upadha(sub); - t.add_tag(T::FlagGuna); - }); + if !(sub == "a" || sub == "A") { + p.op_term(code, i, |t| { + t.set_upadha(sub); + t.add_tag(T::FlagGuna); + }); + } } } } else if is_ik && can_use_guna { @@ -237,8 +281,10 @@ fn try_guna_adesha(p: &mut Prakriya, i: usize) -> Option<()> { /// - must run after guna/vrddhi have been tried. /// /// (7.4.10 - 7.4.12) -fn try_r_guna_before_lit(p: &mut Prakriya) -> Option<()> { - let i = p.find_first(T::Dhatu)?; +fn try_r_guna_before_lit(p: &mut Prakriya, i: usize) -> Option<()> { + if !p.has(i, |t| t.is_dhatu()) { + return None; + } if !p.terms().last()?.has_lakshana("li~w") { return None; @@ -265,7 +311,7 @@ fn try_r_guna_before_lit(p: &mut Prakriya) -> Option<()> { let anga = p.get(i)?; if anga.has_antya('f') && anga.is_samyogadi() { p.op_term("7.4.10", i, do_ar_guna); - } else if anga.has_antya('F') || anga.has_u_in(&["fCa~", "f\\"]) { + } else if anga.has_antya('F') || (anga.has_u_in(&["fCa~", "f\\"]) && anga.has_adi('f')) { if anga.has_u("fCa~") { p.op_term("7.4.11", i, op::adi("ar")); } else { @@ -294,15 +340,14 @@ fn run_for_index(p: &mut Prakriya, i: usize) -> Option<()> { let i_n = p.find_next_where(i, |t| !t.is_empty())?; let n = p.get(i_n)?; - if anga.has_text("jAgf") - && !n.has_u_in(&["kvin", "ciR", "Ral"]) - && !p.view(i_n)?.has_tag(T::Nit) - { - // jAgf-guna takes priority over vrddhi. - p.op_term("7.3.85", i, |t| { - t.set_antya("ar"); - t.add_tag(T::FlagGuna); - }); + if anga.has_u("jAgf") && !n.has_u_in(&["kvin", "ciR", "Ral"]) && !p.view(i_n)?.has_tag(T::Nit) { + // jAgf-guna takes priority over vrddhi. Skip if already applied (e.g. for jAgf + Ric). + if anga.has_antya('f') { + p.op_term("7.3.85", i, |t| { + t.set_antya("ar"); + t.add_tag(T::FlagGuna); + }); + } } else { // Vrddhi takes priority over guna. For example, Ric is Ardhadhatuka (guna) // and Rit (vrddhi), but it will cause vrddhi if possible. @@ -314,11 +359,12 @@ fn run_for_index(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } -pub fn run(p: &mut Prakriya) { +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); } - // Alternative to guna-adesha - try_r_guna_before_lit(p); + p.maybe_save_sthanivat(); + Some(()) } diff --git a/vidyut-prakriya/src/angasya/sup_adesha.rs b/vidyut-prakriya/src/angasya/sup_adesha.rs index bfc4d02..1777eb2 100644 --- a/vidyut-prakriya/src/angasya/sup_adesha.rs +++ b/vidyut-prakriya/src/angasya/sup_adesha.rs @@ -278,7 +278,7 @@ fn try_taa_adesha(p: &mut Prakriya, i_anga: usize, i: usize) -> Option<()> { Some(()) } -pub fn try_misc_rules(p: &mut Prakriya, i_anga: usize, i_sup: usize) -> Option<()> { +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~"); @@ -307,6 +307,8 @@ pub fn try_misc_rules(p: &mut Prakriya, i_anga: usize, i_sup: usize) -> Option<( // paTA, ... p.op_term("7.1.88", i_anga, op::ti("")); } + } else if anga.has_text("pums") { + p.op_term("7.1.89", i_anga, |t| t.set_text("pumas")); } Some(()) } @@ -321,7 +323,9 @@ pub fn run_before_bhasya(p: &mut Prakriya) -> Option<()> { let is_napumsaka = p.has_tag(T::Napumsaka); let is_jas_shas = sup.has_u_in(&["jas", "Sas"]); - if is_aap(anga) && sup.has_text("O") { + if anga.has_tag(T::Sat) && is_jas_shas { + p.op_term("7.1.22", i_sup, op::luk); + } else if is_aap(anga) && sup.has_text("O") { op::adesha("7.1.18", p, i_sup, "SI"); } else if is_napumsaka && sup.has_text("O") { op::adesha("7.1.19", p, i_sup, "SI"); @@ -329,8 +333,6 @@ pub fn run_before_bhasya(p: &mut Prakriya) -> Option<()> { op::adesha("7.1.20", p, i_sup, "Si"); } else if anga.has_text("azwA") && anga.has_u("azwan") && is_jas_shas { op::adesha("7.1.21", p, i_sup, "OS"); - } else if anga.has_tag(T::Sat) && is_jas_shas { - p.op_term("7.1.22", i_sup, op::luk); } else if is_napumsaka && sup.has_u_in(&["su~", "am"]) { try_napumsaka_su_am_adesha(p, i_anga, i_sup); } else { diff --git a/vidyut-prakriya/src/ardhadhatuka.rs b/vidyut-prakriya/src/ardhadhatuka.rs index 64e6946..3a59e77 100644 --- a/vidyut-prakriya/src/ardhadhatuka.rs +++ b/vidyut-prakriya/src/ardhadhatuka.rs @@ -154,7 +154,7 @@ fn try_dhatu_adesha_before_vikarana(p: &mut Prakriya, la: Option) -> Opt op::adesha("2.4.53", p, i, "va\\ci~"); } else if dhatu.has_u("aja~") && !n.has_u_in(&["GaY", "ap"]) { let mut run = true; - if n.has_u("lyuw") { + if n.has_u("lyu~w") { if p.is_allowed("2.4.57") { run = false; } else { @@ -181,7 +181,8 @@ fn try_dhatu_adesha_before_vikarana(p: &mut Prakriya, la: Option) -> Opt let will_yasut = la == Some(Lakara::AshirLin) && p.has_tag(T::Parasmaipada); let is_lit_ajadi = la == Some(Lakara::Lit) && p.terms().last()?.has_adi(&*AC); let will_have_valadi = !(will_yasut || is_lit_ajadi); - if n.has_adi(&*VAL) && will_have_valadi { + if n.has_adi(&*VAL) && will_have_valadi && !n.has_text("vu~") { + // HACK: ignore Rvul, since it will be replaced with -aka. if p.is_allowed("2.4.56.v2") { p.step("2.4.56.v2"); run = false; @@ -218,6 +219,10 @@ fn dhatu_adesha_after_vikarana(p: &mut Prakriya) -> Option<()> { } } + if p.has(i + 1, |t| t.has_u("yaN")) && p.has(i + 2, |t| t.has_u("ac")) { + p.op_term("2.4.74", i + 1, op::lopa); + } + Some(()) } @@ -257,7 +262,7 @@ fn try_aa_adesha(p: &mut Prakriya) -> Option<()> { let dhatu = p.get(i)?; let n = p.view(i + 1)?; let ashiti_lyapi = !n.has_tag(T::Sit) || n.has_u("lyap"); - let nici = n.has_u("Ric"); + let nau = n.has_u("Ric"); if dhatu.has_u_in(&["mI\\Y", "qumi\\Y", "dI\\N"]) && ashiti_lyapi && will_cause_guna(&n) { p.op_term("6.1.50", i, op::antya("A")); @@ -270,23 +275,26 @@ fn try_aa_adesha(p: &mut Prakriya) -> Option<()> { // līyateriti yakā nirdeśo na tu śyanā. līlīṅorātvaṃ vā syādejviṣaye // lyapi ca. (SK) p.op_optional("6.1.51", op::t(i, op::antya("A"))); - } else if dhatu.has_u("sPura~") && nici { + } else if dhatu.has_u("sPura~") && nau { p.op_optional("6.1.54", op::t(i, op::upadha("A"))); - } else if dhatu.has_u_in(&["ciY", "ci\\Y"]) && nici { + } else if dhatu.has_u_in(&["ciY", "ci\\Y"]) && nau { p.op_optional("6.1.54", op::t(i, op::antya("A"))); - } else if dhatu.has_u("vI\\") && dhatu.has_gana(Gana::Adadi) && nici { + } else if dhatu.has_u("vI\\") && dhatu.has_gana(Gana::Adadi) && nau { // Check gana to avoid aj -> vI p.op_optional("6.1.55", op::t(i, op::antya("A"))); - } else if dhatu.has_u("YiBI\\") && p.has_tag(T::FlagHetuBhaya) { - p.op_optional("6.1.56", op::t(i, op::antya("A"))); - } else if dhatu.has_text("smi") && n.has_u("Ric") { - p.op_optional("6.1.57", op::t(i, op::antya("A"))); + } else if nau && p.has_tag(T::FlagHetuBhaya) { + if dhatu.has_u("YiBI\\") { + p.op_optional("6.1.56", op::t(i, op::antya("A"))); + } else if dhatu.has_text("smi") { + p.op_optional("6.1.57", op::t(i, op::antya("A"))); + } } Some(()) } -pub fn run_am_agama(p: &mut Prakriya) -> Option<()> { +/// Runs rules that try adding am-Agama to a dhatu when certain pratyayas follow. +pub fn try_add_am_agama(p: &mut Prakriya) -> Option<()> { let i = p.find_first(T::Dhatu)?; let n = p.view(i + 1)?; @@ -294,8 +302,10 @@ pub fn run_am_agama(p: &mut Prakriya) -> Option<()> { if n.has_adi(&*JHAL) && !n.has_tag(T::kit) { if dhatu.has_text_in(&["sfj", "dfS"]) { + // srazwA, drazwA p.op_term("6.1.58", i, op::mit("a")); } else if dhatu.has_tag(T::Anudatta) && dhatu.has_upadha('f') { + // traptA, tarpitA, tarptA p.op_optional("6.1.59", op::t(i, op::mit("a"))); } } @@ -322,7 +332,11 @@ pub fn run_before_vikarana( /// Replaces the dhAtu based on the following suffix. /// /// These rules must run after the vikarana is added and before dvitva. -pub fn run_before_dvitva(p: &mut Prakriya) { +pub fn run_before_dvitva(p: &mut Prakriya) -> Option<()> { dhatu_adesha_after_vikarana(p); try_aa_adesha(p); + + p.maybe_save_sthanivat(); + + Some(()) } diff --git a/vidyut-prakriya/src/args/dhatu.rs b/vidyut-prakriya/src/args/dhatu.rs index afe1db6..7fdd2e6 100644 --- a/vidyut-prakriya/src/args/dhatu.rs +++ b/vidyut-prakriya/src/args/dhatu.rs @@ -45,45 +45,6 @@ enum_boilerplate!(Gana, { Curadi => "10", }); -impl Gana { - /// Parses the given integer as a `Gana`. - pub fn from_int(value: u8) -> Result { - use Gana::*; - let ret = match value { - 1 => Bhvadi, - 2 => Adadi, - 3 => Juhotyadi, - 4 => Divadi, - 5 => Svadi, - 6 => Tudadi, - 7 => Rudhadi, - 8 => Tanadi, - 9 => Kryadi, - 10 => Curadi, - _ => return Err(Error::gana_parse_error(value)), - }; - Ok(ret) - } -} - -impl From for u8 { - fn from(value: Gana) -> u8 { - use Gana::*; - match value { - Bhvadi => 1, - Adadi => 2, - Juhotyadi => 3, - Divadi => 4, - Svadi => 5, - Tudadi => 6, - Rudhadi => 7, - Tanadi => 8, - Kryadi => 9, - Curadi => 10, - } - } -} - /// Defines an antargana. /// /// The dhatus in the Dhatupatha are organized in ten large *gaṇa*s or classes. Within these larger diff --git a/vidyut-prakriya/src/args/krt.rs b/vidyut-prakriya/src/args/krt.rs index 1291e80..79ae1bb 100644 --- a/vidyut-prakriya/src/args/krt.rs +++ b/vidyut-prakriya/src/args/krt.rs @@ -11,6 +11,8 @@ use wasm_bindgen::prelude::wasm_bindgen; #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] #[wasm_bindgen] pub enum Krt { + /// -a + a, /// -a ac, /// -a @@ -41,6 +43,10 @@ pub enum Krt { Uka, /// -a ka, + /// -am + kamul, + /// -as (visfpaH, ...) + kasun, /// -Ana (cakrARa, ...) kAnac, /// -i (udaDi, ...) @@ -87,6 +93,8 @@ pub enum Krt { kvin, /// (empty suffix) kvip, + /// -a (priyaMvada, vaSaMvada) + Kac, /// -a (Izatkara, duzkara, sukara, ...) Kal, /// -a @@ -101,8 +109,14 @@ pub enum Krt { Nvanip, /// -Ana cAnaS, + /// -anta, + Jac, + /// -a + wa, /// -a wak, + /// -a + qa, /// -u qu, /// -a @@ -115,6 +129,8 @@ pub enum Krt { Ryat, /// -ana Ryuw, + /// (empty) + Rvi, /// -aka Rvuc, /// -aka @@ -163,8 +179,10 @@ pub enum Krt { lyuw, /// -van vanip, - /// -vaca + /// -vara varac, + /// (empty suffix) + vic, /// -aka vuY, /// -aka @@ -178,6 +196,24 @@ pub enum Krt { // unAdi-pratyayas // =============== + /// -ama (praTama) + amac, + /// -ala (maNgala) + alac, + /// -Ayya + Ayya, + /// -itnu + itnuc, + /// -iTi + iTin, + /// -iza + wizac, + /// -izWu + izWuc, + /// -izWa + izWac, + /// -isa + isan, /// -u (kAru) uR, /// -atu (kratu) @@ -212,16 +248,8 @@ pub enum Krt { yatuc, /// -ali alic, - /// -izWu - izWuc, - /// -izWa - izWac, - /// -isa - isan, /// -sya syan, - /// -iTi - iTin, /// -uli uli, /// -as (use trailing `_` since `as` is a reserved keyword in Rust.) @@ -233,6 +261,7 @@ pub enum Krt { } enum_boilerplate!(Krt, { + a => "a", ac => "ac", aR => "aR", atfn => "atf~n", @@ -249,6 +278,8 @@ enum_boilerplate!(Krt, { Uka => "Uka", cAnaS => "cAnaS", ka => "ka", + kamul => "kamu~l", + kasun => "kasu~n", kAnac => "kAnac", ki => "ki", kin => "kin", @@ -272,19 +303,23 @@ enum_boilerplate!(Krt, { kvin => "kvi~n", kvip => "kvi~p", ksnu => "ksnu", + Kac => "Kac", Kal => "Kal", Ga => "Ga", GaY => "GaY", GinuR => "Ginu~R", Gurac => "Gurac", Nvanip => "Nvani~p", + wa => "wa", wak => "wak", + qa => "qa", qu => "qu", Ra => "Ra", Ramul => "Ramu~l", Rini => "Rini~", Ryat => "Ryat", Ryuw => "Ryu~w", + Rvi => "Rvi~", Rvuc => "Rvu~c", Rvul => "Rvu~l", tavya => "tavya", @@ -310,6 +345,7 @@ enum_boilerplate!(Krt, { lyuw => "lyu~w", vanip => "vani~p", varac => "varac", + vic => "vi~c", vuY => "vu~Y", vun => "vu~n", zAkan => "zAkan", @@ -318,6 +354,14 @@ enum_boilerplate!(Krt, { // unAdi-pratyayas // =============== + amac => "amac", + alac => "alac", + Ayya => "Ayya", + itnuc => "itnuc", + iTin => "iTin", + izWuc => "izWuc", + izWac => "izWac", + isan => "isan", uR => "uR", // TODO: why do we keep the initial 'k' here? kan => "a~kan", @@ -327,7 +371,9 @@ enum_boilerplate!(Krt, { ksaran => "ksaran", ksi => "ksi", ksu => "ksu", + Jac => "Jac", YuR => "YuR", + wizac => "wizac", tan => "tan", tun => "tun", sa => "sa", @@ -336,11 +382,7 @@ enum_boilerplate!(Krt, { katnic => "katnic", yatuc => "yatuc", alic => "alic", - izWuc => "izWuc", - izWac => "izWac", - isan => "isan", syan => "syan", - iTin => "iTin", uli => "uli", asa => "asa", Asa => "Asa", diff --git a/vidyut-prakriya/src/args/sup.rs b/vidyut-prakriya/src/args/sup.rs index d94d4bd..c4e3576 100644 --- a/vidyut-prakriya/src/args/sup.rs +++ b/vidyut-prakriya/src/args/sup.rs @@ -117,6 +117,11 @@ impl Pratipadika { self.tags.contains(Tag::Dhatu) } + /// Returns whether this pratipadika is udit. + pub fn is_udit(&self) -> bool { + self.tags.contains(Tag::udit) + } + /// Returns whether this pratipadika ends in a pratyaya. pub fn is_pratyaya(&self) -> bool { self.tags.contains(Tag::Pratyaya) @@ -134,6 +139,7 @@ pub struct PratipadikaBuilder { text: Option, is_nyap: bool, is_dhatu: bool, + is_udit: bool, is_pratyaya: bool, } @@ -156,6 +162,12 @@ impl PratipadikaBuilder { self } + /// Sets whether this pratipadika should be treated as ending in a dhatu. + pub fn is_udit(&mut self, yes: bool) -> &mut Self { + self.is_udit = yes; + self + } + /// Sets whether this pratipadika should be treated as ending in a dhatu. pub fn is_pratyaya(&mut self, yes: bool) -> &mut Self { self.is_pratyaya = yes; @@ -183,6 +195,9 @@ impl PratipadikaBuilder { if self.is_dhatu { tags.insert(Tag::Dhatu); } + if self.is_udit { + tags.insert(Tag::udit); + } if self.is_dhatu { tags.insert(Tag::Pratyaya); } diff --git a/vidyut-prakriya/src/args/taddhita.rs b/vidyut-prakriya/src/args/taddhita.rs index fa6f126..07fff3f 100644 --- a/vidyut-prakriya/src/args/taddhita.rs +++ b/vidyut-prakriya/src/args/taddhita.rs @@ -10,70 +10,213 @@ use wasm_bindgen::prelude::wasm_bindgen; #[allow(dead_code, non_camel_case_types)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] #[wasm_bindgen] -#[allow(missing_docs)] pub enum Taddhita { + /// -aka akac, + /// -a aR, + /// -a + aY, + /// -a at, + /// -Ara + Arak, + /// -i iY, + /// -iman + imanic, + /// -ila + ilac, + /// -izWa izWan, + /// -Iyas Iyasun, + /// -era, + Erak, + /// -ka + kan, + /// -kalpa + kalpap, + /// -kftvas + kftvasuc, + /// -Ina Ka, + /// -Ina + KaY, + /// -iya Ga, + /// -iya Gac, + /// -iya + Gas, + /// -Ayana + cPaY, + /// -Iya Ca, + /// -Iya, + CaR, + /// -Iya, + Cas, + /// -ya + Yya, + /// -a + waq, + /// -ika Wak, + /// -ika + WaY, + /// -mat + qmatup, + /// -aka + qvun, + /// -eya Qak, + /// -eya + QaY, + /// -era + Qrak, + /// -tama tamap, + /// -tara tarap, + /// -ta (becomes -tA) tal, + /// -tas + tasi, + /// -tas tasil, + /// -tika + tikan, + /// -tra tral, + /// -tva tva, + /// -Tam Tamu, + /// -TA TAl, + /// -dA dA, + /// -dAnIm dAnIm, + /// -deSya + deSya, + /// -deSIya + deSIyar, + /// -dhA + DA, + /// -na + na, + /// -Ayana Pak, + /// -Ayana + PaY, + /// -Ayani PiY, + /// -mat matup, + /// -ma + map, + /// -maya + mayaw, + /// -ya yaY, + /// -ya yat, + /// -yu + yus, + /// -rUpa + rUpap, + /// -rhi rhil, + /// -la + lac, + /// -in vini, + /// -aka + vuY, + /// -Sa + Sa, + /// -Sas + Sas, + /// -ika + zWan, + /// -sAt + sAti, + /// -s + suc, + /// -ha ha, } enum_boilerplate!(Taddhita, { akac => "akac", + aY => "aY", aR => "aR", at => "at", + Arak => "Arak", iY => "iY", + imanic => "imani~c", + ilac => "ilac", izWan => "izWan", Iyasun => "Iyasu~n", + Erak => "Erak", + kan => "kan", + kalpap => "kalpap", + kftvasuc => "kftvasu~c", Ka => "Ka", + KaY => "KaY", Ga => "Ga", Gac => "Gac", + Gas => "Gas", + cPaY => "cPaY", Ca => "Ca", + CaR => "CaR", + Cas => "Cas", + Yya => "Yya", + waq => "waq", Wak => "Wak", + WaY => "WaY", + qmatup => "qmatu~p", + qvun => "qvu~n", Qak => "Qak", + QaY => "QaY", + Qrak => "Qrak", tamap => "tamap", tarap => "tarap", tal => "tal", + tasi => "tasi~", tasil => "tasi~l", + tikan => "tikan", tral => "tral", tva => "tva", Tamu => "Tamu~", TAl => "TAl", dA => "dA", dAnIm => "dAnIm", + deSya => "deSya", + deSIyar => "deSIyar", + DA => "DA", + na => "na", matup => "matu~p", + map => "map", + mayaw => "mayaw", Pak => "Pak", + PaY => "PaY", PiY => "PiY", yaY => "yaY", yat => "yat", + yus => "yus", rhil => "rhil", + lac => "lac", + rUpap => "rUpap", vini => "vini~", + vuY => "vuY", + Sa => "Sa", + Sas => "Sas", + zWan => "zWan", + sAti => "sAti~", + suc => "su~c", ha => "ha", }); diff --git a/vidyut-prakriya/src/ashtadhyayi.rs b/vidyut-prakriya/src/ashtadhyayi.rs index 5f6014f..31eece4 100644 --- a/vidyut-prakriya/src/ashtadhyayi.rs +++ b/vidyut-prakriya/src/ashtadhyayi.rs @@ -1,15 +1,15 @@ /*! The Ashtadhyayi and its rules. -The main struct here is `Ashtadhyayi`, which accepts different config options that controls how -words are derived in the system. +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::ac_sandhi; use crate::angasya; use crate::ardhadhatuka; use crate::args::{ - Dhatu, KrdantaArgs, Krt, Lakara, Linga, Pratipadika, Prayoga, Sanadi, SubantaArgs, - TaddhitantaArgs, TinantaArgs, + Dhatu, KrdantaArgs, Krt, Lakara, Linga, Pratipadika, Prayoga, SubantaArgs, TaddhitantaArgs, + TinantaArgs, }; use crate::atidesha; use crate::atmanepada; @@ -28,10 +28,12 @@ use crate::samprasarana; use crate::sanadi; use crate::stritva; use crate::sup_karya; -use crate::taddhita_pratyaya; +use crate::taddhita; use crate::tag::Tag; +use crate::term::Term; use crate::tin_pratyaya; use crate::tripadi; +use crate::uttarapade; use crate::vikarana; /// Adds a dhatu to the prakriya and runs basic follow-up tasks, such as: @@ -41,17 +43,23 @@ use crate::vikarana; /// - adding any necessary sanAdi-pratyayas. fn add_dhatu(p: &mut Prakriya, dhatu: &Dhatu, is_ardhadhatuka: bool) -> Result<()> { dhatu_karya::run(p, dhatu)?; - sanadi::run(p, is_ardhadhatuka, dhatu.sanadi()); - if dhatu.sanadi() == &[Sanadi::San] || dhatu.sanadi() == &[Sanadi::Yan] { + sanadi::try_add_specific_sanadi_pratyayas(p, is_ardhadhatuka); + if p.terms().last().expect("ok").is_pratyaya() { samjna::run(p); - ardhadhatuka::run_before_vikarana(p, None, true); - run_various_dhatu_tasks(p); - angasya::run_after_dvitva(p); - dvitva::run(p); - samprasarana::run_for_abhyasa(p); - ac_sandhi::run_common(p); - tripadi::run(p); + run_rules(p, None, false)?; + } + + for s in dhatu.sanadi() { + sanadi::try_add_general_sanadi_pratyaya(p, *s); + samjna::run(p); + // Needed for BIzayate, etc. + atmanepada::run(p); + run_rules(p, None, false)?; + } + + if !dhatu.sanadi().is_empty() { + p.debug("~~~~~~~~~~~~~~ completed sanadi-dhatu ~~~~~~~~~~~~~~~~~~") } Ok(()) @@ -64,14 +72,6 @@ fn add_lakara_and_decide_pada(p: &mut Prakriya, lakara: Lakara) { atmanepada::run(p); } -fn try_add_vikaranas(p: &mut Prakriya, la: Option, is_ardhadhatuka: bool) -> Result<()> { - ardhadhatuka::run_before_vikarana(p, la, is_ardhadhatuka); - vikarana::run(p)?; - samjna::run(p); - - Ok(()) -} - /// Runs rules that potentially add a lakara. /// /// Certain krt-pratyayas are allowed only if they replace a specific lakara. To accommodate those @@ -115,26 +115,72 @@ fn run_various_dhatu_tasks(p: &mut Prakriya) { // Now finish it_agama and atidesha it_agama::run_after_attva(p); atidesha::run_after_attva(p); - - // Converts F to ir/ur - angasya::hacky_before_dvitva(p); } -/// Runs tasks common to the end of a prakriya. These include: -/// - sandhi -/// - various rules within the `angasya` section. -/// - the tripAdi. -fn finish_prakriya(p: &mut Prakriya) { +fn run_rules(p: &mut Prakriya, lakara: Option, is_ardhadhatuka: bool) -> Result<()> { + 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)); + if let Some(lakara) = lakara { + if is_lit_or_ashirlin { + tin_pratyaya::try_general_siddhi(p, lakara); + tin_pratyaya::try_siddhi_for_jhi(p, lakara); + } + } + + p.debug("==== Vikaranas ===="); + ardhadhatuka::run_before_vikarana(p, lakara, is_ardhadhatuka); + vikarana::run(p)?; + samjna::run(p); + + if let Some(lakara) = lakara { + if !is_lit_or_ashirlin { + tin_pratyaya::try_general_siddhi(p, lakara); + } + } + + p.debug("==== Dhatu tasks ===="); + run_various_dhatu_tasks(p); + // Must follow tin-siddhi and it-Agama, which could change the first sound of the pratyaya. - ardhadhatuka::run_am_agama(p); + ardhadhatuka::try_add_am_agama(p); - angasya::iit_agama(p); + p.debug("==== Dvitva (dvirvacane 'ci) ===="); + dvitva::try_dvirvacane_aci(p); + let used_dvirvacane_aci = p.find_last_where(Term::is_abhyasta).is_some(); + if used_dvirvacane_aci { + samprasarana::run_for_abhyasa(p); + } + + // If Ji causes dvitva, that dvitva will be performed in `try_dvirvacane_aci` above. + // So by this point, it's safe to replace Ji. (See 3.4.109, which replaces Ji if it follows a + // term called `abhyasta`.) + if let Some(lakara) = lakara { + if !is_lit_or_ashirlin { + tin_pratyaya::try_siddhi_for_jhi(p, lakara); + } + } + uttarapade::run(p); + angasya::maybe_do_jha_adesha(p); ac_sandhi::try_sup_sandhi_before_angasya(p); + angasya::run_before_dvitva(p); + + p.debug("==== Dvitva (default) ===="); + dvitva::run(p); + if !used_dvirvacane_aci { + samprasarana::run_for_abhyasa(p); + } + + p.debug("==== After dvitva ===="); angasya::run_after_dvitva(p); ac_sandhi::try_sup_sandhi_after_angasya(p); ac_sandhi::run_common(p); + + p.debug("==== Tripadi ===="); tripadi::run(p); + + Ok(()) } fn derive_tinanta(mut prakriya: Prakriya, dhatu: &Dhatu, args: &TinantaArgs) -> Result { @@ -144,6 +190,7 @@ fn derive_tinanta(mut prakriya: Prakriya, dhatu: &Dhatu, args: &TinantaArgs) -> 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. @@ -155,49 +202,13 @@ fn derive_tinanta(mut prakriya: Prakriya, dhatu: &Dhatu, args: &TinantaArgs) -> add_dhatu(p, dhatu, is_ardhadhatuka)?; add_lakara_and_decide_pada(p, lakara); + // Try adding am-pratyaya and the corresponding dhatu before tin-adesha, since doing so affects + // the pada. + vikarana::try_add_am_pratyaya_for_lit(p); tin_pratyaya::adesha(p, purusha, vacana); samjna::run(p); - // Do lit-siddhi and AzIrlin-siddhi first to support the valAdi vArttika for aj -> vi. - let is_lit_or_ashirlin = matches!(lakara, Lakara::Lit | Lakara::AshirLin); - if is_lit_or_ashirlin { - tin_pratyaya::siddhi(p, lakara, vacana); - } - - try_add_vikaranas(p, Some(lakara), is_ardhadhatuka)?; - - // --- Code below this line needs to be cleaned up. --- - - if !lakara.is_sarvadhatuka() || dhatu.sanadi().contains(&Sanadi::Yan) { - run_various_dhatu_tasks(p) - } - - angasya::run_before_dvitva(p); - - dvitva::run(p); - samprasarana::run_for_abhyasa(p); - - if !is_lit_or_ashirlin { - tin_pratyaya::siddhi(p, lakara, vacana); - } - - if lakara.is_sarvadhatuka() { - run_various_dhatu_tasks(p) - } - - // --- Code above this line needs to be cleaned up. --- - - // Must follow tin-siddhi and it-Agama, which could change the first sound of the pratyaya. - ardhadhatuka::run_am_agama(p); - - angasya::iit_agama(p); - - ac_sandhi::try_sup_sandhi_before_angasya(p); - angasya::run_after_dvitva(p); - - ac_sandhi::try_sup_sandhi_after_angasya(p); - ac_sandhi::run_common(p); - tripadi::run(p); + run_rules(p, Some(lakara), is_ardhadhatuka)?; Ok(prakriya) } @@ -209,14 +220,11 @@ fn derive_subanta( ) -> Result { let p = &mut prakriya; - // Prepare pratipadika pratipadika_karya::run(p, pratipadika, args.linga()); stritva::run(p); - - // Create subanta sup_karya::run(p, args); samjna::run(p); - finish_prakriya(p); + run_rules(p, None, false)?; Ok(prakriya) } @@ -227,6 +235,7 @@ fn derive_krdanta(mut prakriya: Prakriya, dhatu: &Dhatu, args: &KrdantaArgs) -> add_dhatu(p, dhatu, krt.is_ardhadhatuka())?; maybe_add_lakara_for_krt(p, krt); + vikarana::try_add_am_pratyaya_for_lit(p); let added = krt::run(p, krt); if !added { @@ -237,11 +246,7 @@ fn derive_krdanta(mut prakriya: Prakriya, dhatu: &Dhatu, args: &KrdantaArgs) -> stritva::run(p); samjna::run(p); - try_add_vikaranas(p, None, true)?; - run_various_dhatu_tasks(p); - dvitva::run(p); - samprasarana::run_for_abhyasa(p); - finish_prakriya(p); + run_rules(p, None, true)?; Ok(prakriya) } @@ -257,7 +262,7 @@ fn derive_taddhitanta( pratipadika_karya::run(p, pratipadika, Linga::Pum); samjna::run(p); - let added = taddhita_pratyaya::run(p, taddhita); + let added = taddhita::run(p, taddhita); if !added { return Err(Error::Abort(prakriya)); } @@ -265,8 +270,8 @@ fn derive_taddhitanta( linganushasanam::run(p); stritva::run(p); samjna::run(p); - angasya::try_pratyaya_adesha(p); - finish_prakriya(p); + + run_rules(p, None, false)?; Ok(prakriya) } @@ -304,13 +309,13 @@ pub struct Ashtadhyayi { // - `extended` -- if set, enable rare rules that are less useful, such as 8.4.48 (aco // rahAbhyAM dve), which creates words like *kAryyate*, *brahmmA*, etc. // - `disable` -- if set, disable the rules provided. To implement this, we should make - // `Prakriya::step` private and add a check statement with `Prakriya::op`. + // `Prakriya::step` private and add a check statement in `Prakriya::op`. log_steps: bool, } // TODO: better error handling. impl Ashtadhyayi { - /// Creates an interface with sane defaults. + /// Creates a basic interface with sane defaults. pub fn new() -> Self { Ashtadhyayi { log_steps: true } } diff --git a/vidyut-prakriya/src/atidesha.rs b/vidyut-prakriya/src/atidesha.rs index 71a9f46..10448dc 100644 --- a/vidyut-prakriya/src/atidesha.rs +++ b/vidyut-prakriya/src/atidesha.rs @@ -80,6 +80,14 @@ fn try_add_nit(p: &mut Prakriya, i: usize) -> Option<()> { if gan_kutadi && !n.has_tag_in(&[T::Rit, T::Yit]) { wrap.add_nit("1.2.1", i_n); + } else if cur.has_u("vyaca~") + && n.last()?.is_krt() + && !n.has_tag_in(&[T::Rit, T::Yit]) + && !n.has_u("asi~") + { + // vyaceḥ kuṭāditvamanasīti tu neha pravartate, anasīti paryudāsena kṛnmātraviṣayatvāt + // -- SK 655 + wrap.add_nit("1.2.1.v1", i_n); } else if cur.has_u_in(&["o~vijI~\\", "o~vijI~"]) && iti { // Just for these `vij` dhatus, according to the Kashika. wrap.add_nit("1.2.2", i_n); diff --git a/vidyut-prakriya/src/atmanepada.rs b/vidyut-prakriya/src/atmanepada.rs index 31e9934..fffbd5c 100644 --- a/vidyut-prakriya/src/atmanepada.rs +++ b/vidyut-prakriya/src/atmanepada.rs @@ -4,16 +4,17 @@ //! Rules to determine parasmaipada/Atmanepada. //! //! The terms *parasmaipada* and *Atmanepada* properly refer to the substitutions for the various -//! lakAras. But we haven't made any substitutions yet. So, how can we apply these *pada* -//! designations at this stage? +//! lakAras. But at this stage in the prakriya, we haven't made any substitutions yet. So, how can +//! we apply these *pada* designations at this stage? //! //! The answer is that we attach these designations *to the prakriyA* to set the derivation //! context. Then when we introduce the correct tiN suffix, we will assign *parasmaipada* or -//! *Atmanepada* to it as appropriate. +//! *Atmanepada* to that pratyaya as appropriate. use crate::args::Gana; -use crate::dhatu_gana::{DYUT_ADI, VRDBHYAH}; -use crate::prakriya::{Code, Prakriya}; +use crate::dhatu_gana::{DYUT_ADI, VRT_ADI}; +use crate::prakriya::Rule::Kaumudi; +use crate::prakriya::{Code, Prakriya, Rule}; use crate::tag::Tag as T; const GAMY_RCCHI: &[(&str, Gana)] = &[ @@ -34,10 +35,15 @@ fn op_parasmaipada(p: &mut Prakriya) { p.add_tag(T::Parasmaipada); } +/// An extension of `Prakriya` with useful methods specific to deciding atmanepada and +/// parasmaipada. struct PadaPrakriya<'a> { + /// The original `Prakriya`. p: &'a mut Prakriya, + /// The index of the dhatu. i_dhatu: usize, } + impl<'a> PadaPrakriya<'a> { fn new(p: &'a mut Prakriya, i_dhatu: usize) -> Self { PadaPrakriya { p, i_dhatu } @@ -57,8 +63,21 @@ impl<'a> PadaPrakriya<'a> { has_dhatu && has_upasarga } + fn has_all_upasargas(&self, upasargas: &[&str]) -> bool { + let n = upasargas.len(); + if self.i_dhatu < n { + // Not enough room for upasargas + false + } else { + upasargas + .iter() + .enumerate() + .all(|(i, text)| self.p.has(self.i_dhatu + i - n, |t| t.has_text(text))) + } + } + /// Checks whether the prakriya has any of the given upasargas and any of the given - /// dhatu-upadeshas. + /// dhatu-upadeshas + ganas. fn is_exactly(&self, upasargas: &[&str], upadeshas: &[(&str, Gana)]) -> bool { let i_dhatu = self.i_dhatu; let has_dhatu = upadeshas @@ -79,7 +98,7 @@ impl<'a> PadaPrakriya<'a> { } /// Optionally marks this prakriya as AtmanepadI. - fn optional_atma(&mut self, rule: Code) { + fn optional_atma(&mut self, rule: impl Into) { self.p.op_optional(rule, op_atmanepada); } @@ -105,7 +124,7 @@ pub fn run(p: &mut Prakriya) -> Option<()> { let i = p.find_last_where(|t| t.is_dhatu() && !t.has_u("san"))?; let has_upasargas = p.find_prev_where(i, |t| t.has_tag(T::Upasarga)).is_some(); - if p.any(&[T::Bhave, T::Karmani]) { + if p.is_bhave_or_karmani() { p.op("1.3.13", op_atmanepada); return None; } @@ -113,20 +132,14 @@ pub fn run(p: &mut Prakriya) -> Option<()> { let mut pp = PadaPrakriya::new(p, i); let la = pp.p.terms().last()?; - let vidhi_lin = la.has_u("li~N") && !pp.p.has_tag(T::Ashih); + let is_vidhi_lin = la.has_u("li~N") && !pp.p.has_tag(T::Ashih); // Needed for rules 1.3.60 and 1.3.61 below. // TODO: remove hack for san. - let is_sarvadhatuka = (vidhi_lin || la.has_u_in(&["la~w", "lo~w", "la~N"])) + let is_sarvadhatuka = (is_vidhi_lin || la.has_u_in(&["la~w", "lo~w", "la~N"])) && !pp.p.has(i + 1, |t| t.has_u("san")); // Needed for rule 1.3.61 below. let is_lun_lin = la.has_u_in(&["lu~N", "li~N"]); - // Most of these rules can be expressed in a simple shorthand. The last field in each in each - // tuple is whether the pada is always Atmanepada (A), always parasmaipada (P), or dependent on - // some semantic condition (U). - // - // Rules that can't easily be modeled in this format are further below. - let has_san = pp.p.find_first_where(|t| t.has_u("san") && t.is_pratyaya()) .is_some(); @@ -167,6 +180,13 @@ pub fn run(p: &mut Prakriya) -> Option<()> { pp.optional_atma("1.3.29.v1"); } else if pp.is(&["ni", "sam", "upa", "vi"], &["hve\\Y"]) { pp.atma("1.3.30"); + } else if has_upasargas && dhatu.has_u_in(&["asu~", "Uha~\\"]) { + let code = "1.3.30.v1"; + if dhatu.has_u("asu~") { + pp.optional_atma(code); + } else { + pp.optional_para(code); + } } else if pp.is(&["AN"], &["hve\\Y"]) { pp.optional_atma("1.3.31"); // 1.3.32 - 1.3.37 can be handled with 1.3.72. @@ -183,7 +203,15 @@ pub fn run(p: &mut Prakriya) -> Option<()> { // TODO: diff between this and 1.3.38? pp.optional_atma("1.3.43"); } - // 1.3.44 - 1.3.46 can be handled with 1.3.76. + } else if pp.is(&["apa"], &["jYA\\"]) { + pp.optional_atma("1.3.44"); + // 1.3.45 can be handled with 1.3.76. + } else if pp.is(&["sam", "prati"], &["jYA\\"]) { + pp.optional_atma("1.3.46"); + } else if pp.has_all_upasargas(&["sam", "pra"]) && dhatu.has_u("vada~") { + pp.optional_atma("1.3.48"); + } else if pp.has_all_upasargas(&["vi", "pra"]) && dhatu.has_u("vada~") { + pp.optional_atma("1.3.49"); } else if pp.is(&[], &["vada~"]) { pp.optional_atma("1.3.47"); // 1.3.48 - 1.3.50 can be handled with 1.3.47. @@ -224,13 +252,12 @@ pub fn run(p: &mut Prakriya) -> Option<()> { pp.optional_atma("1.3.66"); } else if dhatu.has_u("Ric") && i > 0 && pp.p.has(i - 1, |t| t.has_u_in(&["YiBI\\", "zmi\\N"])) { - let is_atma = pp.p.op_optional("1.3.68", |p| { + // If this option is declined, we'll use the general rule below (1.3.74). Thus we get + // BAyayati/BAyayate per the normal rules and BApayate/BIzayate if 1.3.68 is accepted. + pp.p.op_optional("1.3.68", |p| { op_atmanepada(p); p.add_tag(T::FlagHetuBhaya); }); - if !is_atma { - pp.para("1.3.68"); - } } else if pp.is(&["apa"], &["vad"]) { // TODO: 1.3.67 - 1.3.71. // 1.3.72 is further below. @@ -257,7 +284,7 @@ pub fn run(p: &mut Prakriya) -> Option<()> { pp.optional_para("1.3.85"); } 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(VRDBHYAH) && dhatu.has_gana(Gana::Bhvadi) && sya_san() { + } else if dhatu.has_u_in(VRT_ADI) && dhatu.has_gana(Gana::Bhvadi) && sya_san() { pp.optional_para("1.3.92"); } else if dhatu.has_u("kfpU~\\") && (sya_san() || la.has_u("lu~w")) { pp.optional_para("1.3.93"); @@ -268,7 +295,7 @@ pub fn run(p: &mut Prakriya) -> Option<()> { let dhatu = pp.p.get(i)?; if dhatu.has_text("sasj") { // "ayam Atmanepadyapi" (Kaumudi) - pp.optional_atma("si-kO.2291"); + pp.optional_atma(Kaumudi("2291")); } // General rules @@ -276,13 +303,18 @@ pub fn run(p: &mut Prakriya) -> Option<()> { let dhatu = pp.p.get(i)?; if pp.p.any(&[T::Parasmaipada, T::Atmanepada]) { // Matched above already - } else if dhatu.has_tag_in(&[T::Nit, T::anudattet]) { + } else if dhatu.has_tag_in(&[T::Nit, T::anudattet]) && !dhatu.is_empty() { + // Check `is_empty` is to skip yaN-luk. // eDate pp.atma("1.3.12"); } else if dhatu.has_tag_in(&[T::Yit, T::svaritet]) { // karoti, kurute pp.optional_atma("1.3.72"); - } else if pp.p.terms().len() == 3 && pp.p.get(1)?.has_u("Ric") { + } else if pp + .p + .find_last_where(|t| t.is_pratyaya() && t.has_u("Ric")) + .is_some() + { // corayati, corayate pp.optional_atma("1.3.74"); } @@ -293,7 +325,12 @@ pub fn run(p: &mut Prakriya) -> Option<()> { pp.para("1.3.78"); } - debug_assert!(p.any(&[T::Parasmaipada, T::Atmanepada])); + // If the prakriya has a lakAra, check that we have assigned a pada. + // Otherwise (e.g. for sanAdi dhatus), skip this check. + let la = pp.p.terms().last()?; + if la.has_tag(T::La) { + debug_assert!(p.any(&[T::Parasmaipada, T::Atmanepada])); + } Some(()) } diff --git a/vidyut-prakriya/src/dhatu_gana.rs b/vidyut-prakriya/src/dhatu_gana.rs index 6bb9828..c0889a0 100644 --- a/vidyut-prakriya/src/dhatu_gana.rs +++ b/vidyut-prakriya/src/dhatu_gana.rs @@ -271,7 +271,7 @@ pub const PHAN_ADI: &[&str] = &[ /// /// For usage, see 7.1.59. pub const MUC_ADI: &[&str] = &[ - "mu\\cx~^", "lu\\px~^", "vidx~^", "li\\pa~^", "zi\\ca~^", "kftI~", "Ki\\da~", + "mu\\cx~^", "lu\\px~^", "vi\\dx~^", "li\\pa~^", "zi\\ca~^", "kftI~", "Ki\\da~", "piSa~", // TODO: include Pul? // "Pula~", @@ -311,7 +311,7 @@ pub const PU_ADI: &[&str] = &[ "blI\\", ]; -pub const VRDBHYAH: &[&str] = &["vftu~\\", "vfDu~\\", "SfDu~\\", "SfDu~^", "syandU~\\"]; +pub const VRT_ADI: &[&str] = &["vftu~\\", "vfDu~\\", "SfDu~\\", "SfDu~^", "syandU~\\"]; /// These dhatus use san-pratyaya with a long abhyAsa. /// (3.1.6) diff --git a/vidyut-prakriya/src/dhatu_karya.rs b/vidyut-prakriya/src/dhatu_karya.rs index 05dd7ea..f2f90f2 100644 --- a/vidyut-prakriya/src/dhatu_karya.rs +++ b/vidyut-prakriya/src/dhatu_karya.rs @@ -201,6 +201,7 @@ pub fn run(p: &mut Prakriya, dhatu: &Dhatu) -> Result<()> { // For 8.4.18. p.set(0, |t| t.add_tag(T::FlagShanta)); } + p.maybe_save_sthanivat(); try_add_prefixes(p, dhatu); @@ -215,13 +216,13 @@ pub fn run(p: &mut Prakriya, dhatu: &Dhatu) -> Result<()> { #[cfg(test)] mod tests { use super::*; - use crate::args::Gana; 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::from_int(gana.parse().expect("defined")).expect("valid")) + .gana(gana.to_string().parse().expect("ok")) .build() .expect("ok"); diff --git a/vidyut-prakriya/src/dhatupatha.rs b/vidyut-prakriya/src/dhatupatha.rs index 3e799cb..0dedff0 100644 --- a/vidyut-prakriya/src/dhatupatha.rs +++ b/vidyut-prakriya/src/dhatupatha.rs @@ -80,7 +80,11 @@ pub fn create_dhatu(upadesha: impl AsRef, gana: Gana, number: u16) -> Resul fn create_entry(code: &str, upadesha: &str, artha: &str) -> Result { let (gana, number) = code.split_once('.').ok_or(Error::InvalidFile)?; - let gana = Gana::from_int(gana.parse()?)?; + 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)?; diff --git a/vidyut-prakriya/src/dvitva.rs b/vidyut-prakriya/src/dvitva.rs index 7b97215..2c859b2 100644 --- a/vidyut-prakriya/src/dvitva.rs +++ b/vidyut-prakriya/src/dvitva.rs @@ -1,9 +1,12 @@ +/// Runs rules that perform `dvitva` (doubling) on the dhAtu. +/// +/// TODO: the code here is repetitive and can be consolidated with a bit more thought. +use crate::ac_sandhi; use crate::filters as f; use crate::operators as op; use crate::prakriya::{Code, Prakriya}; use crate::sounds as al; use crate::sounds::{s, Set}; -/// Runs rules that perform `dvitva` (doubling) on the dhAtu. use crate::tag::Tag as T; use crate::term::Term; use compact_str::CompactString; @@ -12,7 +15,10 @@ use lazy_static::lazy_static; lazy_static! { static ref AC: Set = s("ac"); static ref HAL: Set = s("hal"); - static ref NDR: Set = s("n d r"); + // As a quick HACK, also allow N, Y, R, and M, since these have been produced by the asiddha + // section. + static ref NDR: Set = s("n d r N Y R M"); + static ref HACKY_NASAL: Set = s("N Y R M"); } /// Runs dvitva rules for roots that begin with vowels, e.g. UrRu. @@ -31,7 +37,7 @@ fn try_dvitva_for_ajadi_dhatu(rule: Code, p: &mut Prakriya, i: usize) -> Option< None => return None, }; let mut third = Term::make_upadesha(&temp); - third.set_text(&dhatu.text[1..]); + third.set_text(&dhatu.sthanivat()[1..]); // 6.1.3 na ndrAH saMyogAdayaH while third.is_samyogadi() && NDR.contains(third.adi()?) { @@ -42,7 +48,7 @@ fn try_dvitva_for_ajadi_dhatu(rule: Code, p: &mut Prakriya, i: usize) -> Option< let abhyasa = Term::make_text(&third.text); p.set(i, |t| t.text.truncate(t.text.len() - abhyasa.text.len())); if p.has(i, |t| t.has_u("UrRuY")) { - third.set_text("nu"); + third.set_adi("n"); } p.insert_after(i, abhyasa); @@ -52,7 +58,7 @@ fn try_dvitva_for_ajadi_dhatu(rule: Code, p: &mut Prakriya, i: usize) -> Option< p.set(i, |t| t.add_tag(T::Abhyasta)); p.set(i + 1, |t| t.add_tag(T::Abhyasta)); - p.set(i + 2, |t| t.add_tag(T::Abhyasta)); + p.set(i + 2, |t| t.add_tags(&[T::Abhyasta, T::Dvitva])); if p.has(i + 3, |t| t.is_ni_pratyaya()) { p.set(i + 3, |t| t.add_tag(T::Abhyasta)); } @@ -61,52 +67,6 @@ fn try_dvitva_for_ajadi_dhatu(rule: Code, p: &mut Prakriya, i: usize) -> Option< Some(()) } -/// Runs dvitva rules for roots that begin with vowels and , e.g. anj + i -> AYjijit -fn try_dvitva_for_ajadi_ni_dhatu(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { - // Example: - let i_ni = i + 1; - let dhatu = p.get(i)?; - let ni = p.get(i_ni)?; - - let mut text = CompactString::from(""); - text.push_str(&dhatu.text[1..]); - text.push_str(&ni.text); - let mut third = Term::make_text(&text); - - // 6.1.3 na ndrAH saMyogAdayaH - while third.is_samyogadi() && NDR.contains(third.adi()?) { - third.set_adi(""); - } - // The structure here is workaround for a Rust compile issue. - if ni.has_u("Ric") { - third.set_u("Ric"); - } else { - third.set_u("RiN"); - } - third.add_tag(T::Dhatu); - - let abhyasa = Term::make_text(&third.text); - p.set(i, |t| { - t.text.truncate(t.text.len() - abhyasa.text.len() + 1) - }); - third.set_antya(""); - - p.insert_after(i, abhyasa); - p.insert_after(i + 1, third); - p.step(rule); - p.op_term("6.1.4", i + 1, op::add_tag(T::Abhyasa)); - - p.op("6.1.5", |p| { - // Set abhyasta for: first, abhyasa, third, and ni. - p.set(i, op::add_tag(T::Abhyasta)); - p.set(i + 1, op::add_tag(T::Abhyasta)); - p.set(i + 2, op::add_tag(T::Abhyasta)); - p.set(i + 3, op::add_tag(T::Abhyasta)); - }); - - Some(()) -} - /// Finds the character span that should be duplicated in the given text. fn find_abhyasa_span(text: &CompactString) -> Option<(usize, usize)> { let mut start = None; @@ -140,38 +100,46 @@ 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 text = CompactString::from(""); + let mut p_text = CompactString::from(""); for t in p.terms() { if t.is_upasarga() { continue; } - text.push_str(&t.text); + if !t.sthanivat().is_empty() { + p_text.push_str(&t.sthanivat()); + } else { + p_text.push_str(&t.text); + } } - let (start, end) = find_abhyasa_span(&text)?; + let (start, end) = find_abhyasa_span(&p_text)?; // debug_assert!(start == 1); - let ac = Term::make_text(&text[0..start]); - let abhyasa = Term::make_text(&text[start..=end]); + let ac = Term::make_text(&p_text[0..start]); + let abhyasa = Term::make_text(&p_text[start..=end]); let i_ac = i_dhatu; p.insert_before(i_ac, ac); p.insert_after(i_ac, abhyasa); - // und i za - // un di d i za + // Example: und i za --> un di d i za let i_dhatu = i_ac + 2; p.set(i_dhatu, |t| t.set_adi("")); - while p.has(i_dhatu, |t| t.is_samyogadi() && t.has_adi(&*NDR)) { + while p.has(i_dhatu, |t| { + (t.is_samyogadi() && t.has_adi(&*NDR)) || t.has_adi('M') + }) { p.set(i_dhatu, |t| t.set_adi("")); } + if p.has(i_ac, |t| t.has_antya(&*HACKY_NASAL)) { + p.set(i_ac, op::antya("n")); + } p.step(rule); p.op_term("6.1.4", i_ac + 1, |t| t.add_tag(T::Abhyasa)); p.op("6.1.5", |p| { p.set(i_ac, op::add_tag(T::Abhyasta)); p.set(i_ac + 1, op::add_tag(T::Abhyasta)); - p.set(i_dhatu, op::add_tag(T::Abhyasta)); + p.set(i_dhatu, |t| t.add_tags(&[T::Abhyasta, T::Dvitva])); if p.has(i_dhatu, |t| t.has_u("UrRuY")) { p.set(i_dhatu, |t| t.set_text("nu")); } @@ -181,6 +149,10 @@ fn try_dvitva_for_sanadi_ajadi(rule: Code, p: &mut Prakriya, i_dhatu: usize) -> } fn try_dvitva(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { + // First, run ac-sandhi (for div -> dudyUzati, etc.) + ac_sandhi::run_antaranga(p); + p.maybe_save_sthanivat(); + let i_n = p.find_next_where(i, |t| { !(t.is_agama() && t.has_tag(T::kit) && !t.is_it_agama()) })?; @@ -189,17 +161,18 @@ fn try_dvitva(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { if dhatu.has_adi(&*AC) && next.last()?.is_pratyaya() - && next.last()?.has_u_in(&["san", "Ric", "yaN"]) + && next.last()?.has_u_in(&["san", "Ric", "yaN", "RiN"]) { try_dvitva_for_sanadi_ajadi(rule, p, i); - } else if dhatu.has_adi(&*AC) - && dhatu.has_antya(&*HAL) - && next.last()?.has_u_in(&["Ric", "RiN"]) - { - try_dvitva_for_ajadi_ni_dhatu(rule, p, i); } else if f::is_eka_ac(dhatu) || al::is_hal(dhatu.adi()?) { + let mut abhyasa = Term::make_text(""); + abhyasa.set_text(&dhatu.sthanivat()); + // TODO: correctly double jAgR - p.insert_before(i, Term::make_text(&dhatu.text)); + if dhatu.text.starts_with("tC") { + abhyasa.set_adi(""); + } + p.insert_before(i, abhyasa); p.step(rule); let i_abhyasa = i; @@ -207,7 +180,7 @@ fn try_dvitva(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { p.op_term("6.1.4", i_abhyasa, op::add_tag(T::Abhyasa)); p.set(i_abhyasa, |t| t.add_tag(T::Abhyasta)); - p.set(i_dhatu, |t| t.add_tag(T::Abhyasta)); + p.set(i_dhatu, |t| t.add_tags(&[T::Abhyasta, T::Dvitva])); if p.has(i_dhatu + 1, |t| t.is_ni_pratyaya()) { p.set(i_dhatu + 1, |t| t.add_tag(T::Abhyasta)); } @@ -223,6 +196,9 @@ fn try_dvitva(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { /// /// - `i` should point to a dhatu. fn run_at_index(p: &mut Prakriya, i: usize) -> Option<()> { + let dhatu = p.get_mut(i)?; + debug_assert!(dhatu.is_dhatu()); + let jaksh_adi = &[ "jakza~", "jAgf", "daridrA", "cakAsf~", "SAsu~", "dIDIN", "vevIN", ]; @@ -248,7 +224,10 @@ fn run_at_index(p: &mut Prakriya, i: usize) -> Option<()> { } else { try_dvitva("6.1.8", p, i); } - } else if n.last()?.has_u_in(&["san", "yaN"]) { + } else if p + .find_next_where(i, |t| t.has_u_in(&["san", "yaN"])) + .is_some() + { try_dvitva("6.1.9", p, i); } else if n.has_tag(T::Slu) { try_dvitva("6.1.10", p, i); @@ -260,9 +239,39 @@ fn run_at_index(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } +/// Runs dvitva rule only if the pratyaya that causes dvitva starts with a vowel. +/// +/// For more details, see rule 1.1.59 ("dvirvacane 'ci"). +pub fn try_dvirvacane_aci(p: &mut Prakriya) -> Option<()> { + // Select !pratyaya to avoid sanAdi, which are also labeled as Dhatu. + let filter = |t: &Term| t.is_dhatu() && !t.has_tag_in(&[T::Dvitva, T::Pratyaya]); + + // Loop for cases like jihriyAmbaBUva, where dvitva occurs twice. + let mut num_loops = 0; + let mut i = p.find_first_where(filter)?; + loop { + let i_n = p.find_next_where(i, |t| !t.is_empty())?; + + // Run only if the next term starts with a vowel. + // Check for `Ji` as well, which starts with a vowel. + // Exclude it_agama so that we can derive `aririzati` etc. + let n = p.get(i_n)?; + if (n.has_adi(&*AC) && !n.is_it_agama()) || n.has_text("Ji") { + run_at_index(p, i); + } + + num_loops += 1; + if num_loops > 10 { + panic!("Infinite loop {:?}", p.terms()); + } + + i = p.find_next_where(i, filter)?; + } +} + pub fn run(p: &mut Prakriya) -> Option<()> { // Select !pratyaya to avoid sanAdi, which are also labeled as Dhatu. - let filter = |t: &Term| t.is_dhatu() && !t.has_tag_in(&[T::Abhyasta, T::Pratyaya]); + let filter = |t: &Term| t.is_dhatu() && !t.has_tag_in(&[T::Dvitva, T::Pratyaya]); // Loop for cases like jihriyAmbaBUva, where dvitva occurs twice. let mut num_loops = 0; diff --git a/vidyut-prakriya/src/errors.rs b/vidyut-prakriya/src/errors.rs index 5a1e4c4..1892dbe 100644 --- a/vidyut-prakriya/src/errors.rs +++ b/vidyut-prakriya/src/errors.rs @@ -66,10 +66,6 @@ impl Error { Error::ParseError(value.to_string()) } - pub(crate) fn gana_parse_error(value: u8) -> Self { - Error::GanaParseError(value) - } - pub(crate) fn missing_required_field(field: &'static str) -> Self { Error::MissingRequiredField(field) } @@ -90,7 +86,7 @@ impl fmt::Display for 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-samjan."), + UnknownIt(c) => write!(f, "`{c}` could not be parsed as an it-samjna."), EmptyUpadesha(s) => write!(f, "The term `{s}` unexpectedly has an empty upadesha."), MissingRequiredField(s) => write!(f, "Please define the `{s}` field."), ParseError(v) => write!(f, "Could not parse `{v}` into an enum value."), diff --git a/vidyut-prakriya/src/filters.rs b/vidyut-prakriya/src/filters.rs index e1e6e22..c9ec222 100644 --- a/vidyut-prakriya/src/filters.rs +++ b/vidyut-prakriya/src/filters.rs @@ -7,6 +7,7 @@ whether a given rule can apply. For most use cases, we recommend using the helper methods on `Term`, which have a more readable calling convention. */ +use crate::args::Gana; use crate::sounds::{s, Set}; use crate::term::Term; use lazy_static::lazy_static; @@ -23,5 +24,5 @@ pub fn is_eka_ac(t: &Term) -> bool { /// Returns whether this term is the dhAtu `as` in the sense of `asti`. pub fn is_asti(t: &Term) -> bool { - t.has_u("asa~") && t.has_gana_int(2) + t.has_u("asa~") && t.has_gana(Gana::Adadi) } diff --git a/vidyut-prakriya/src/it_agama.rs b/vidyut-prakriya/src/it_agama.rs index 3d903da..5bbef73 100644 --- a/vidyut-prakriya/src/it_agama.rs +++ b/vidyut-prakriya/src/it_agama.rs @@ -26,6 +26,7 @@ Order of operations: a following `sya`, `si~c`, etc. */ +use crate::args::Gana::*; use crate::dhatu_gana as gana; use crate::filters as f; use crate::it_samjna; @@ -456,7 +457,7 @@ fn try_ardhadhatuke_2(wrap: &mut ItPrakriya, i: usize) -> Option<()> { let i_n = wrap.p.find_next_where(i, |t| !t.is_empty())?; let anga = wrap.p.get(i)?; let n = wrap.p.view(i + 1)?; - let antya_para = wrap.p.terms().last()?.has_tag(T::Parasmaipada); + let has_parasmaipada = wrap.p.has_tag(T::Parasmaipada); let se = n.has_adi('s'); let krta_crta = &["kft", "cft", "Cfd", "tfd", "nft"]; @@ -481,13 +482,14 @@ fn try_ardhadhatuke_2(wrap: &mut ItPrakriya, i: usize) -> Option<()> { wrap.optional_anit("7.2.48"); } else if anga.has_text_in(krta_crta) && se && !n.has_u("si~c") { wrap.optional_anit("7.2.57"); - } else if anga.has_text("gam") && antya_para && se { + } else if anga.has_text("gam") && has_parasmaipada && se { // gamizyati wrap.set("7.2.58", i_n); - } else if anga.has_u_in(gana::VRDBHYAH) && anga.has_gana_int(1) && antya_para && se { + } else if anga.has_u_in(gana::VRT_ADI) && anga.has_gana(Bhvadi) && has_parasmaipada && se { // vartsyati (vfd), vartsyati (vfD), Sftsyati, syantsyati wrap.anit("7.2.59"); - } else if anga.has_u("kfpU~\\") && antya_para && (se || n.has_u("tAsi~")) { + } else if anga.has_u("kfpU~\\") && has_parasmaipada && (se || n.has_u("tAsi~")) { + // kalpsyati, kalpizyate (but not kalpizyati) wrap.anit("7.2.60"); } else if anga.has_text_in(&["snu", "kram"]) && n.has_adi(&*VAL) { // prasnozIzwa, prakraMsIzwa @@ -628,7 +630,6 @@ fn try_lengthen_it_agama(p: &mut Prakriya, i: usize) -> Option<()> { p.op_term("7.2.37", i, op::text("I")); p.step("cinvat"); } - p.dump(); } else if dhatu.has_antya('F') || dhatu.has_text("vf") { if last.has_lakshana("li~N") { p.step("7.2.39"); @@ -668,6 +669,14 @@ pub fn run_before_attva(p: &mut Prakriya) -> Option<()> { if cur.has_tag(T::FlagIttva) { continue; } + + // Skip it-Agama rules for Ji-pratyaya, which at this point hasn't been replaced. + // But when it is replaced, it will always start with a vowel. + let i_n = wrap.p.find_next_where(i, |t| !t.is_empty())?; + if wrap.p.has(i_n, |t| t.has_u("Ji")) { + continue; + } + wrap.p.set(i, |t| t.add_tag(T::FlagIttva)); run_before_attva_for_term(&mut wrap, i); diff --git a/vidyut-prakriya/src/krt/basic.rs b/vidyut-prakriya/src/krt/basic.rs index c696e23..1306d9a 100644 --- a/vidyut-prakriya/src/krt/basic.rs +++ b/vidyut-prakriya/src/krt/basic.rs @@ -62,7 +62,9 @@ own control flow. For details, please see the docs for those functions. use crate::args::Gana; use crate::args::Krt; +use crate::args::Taddhita; use crate::dhatu_gana as gana; +use crate::it_samjna; use crate::krt::utils::KrtPrakriya; use crate::operators as op; use crate::prakriya::Prakriya; @@ -83,6 +85,22 @@ fn is_nandi_grahi_pacadi(p: &KrtPrakriya, i: usize) -> bool { // TODO: add the others. const NAND_ADI: &[&str] = &["nand", "jalp", "ram", "dfp"]; + #[allow(unused)] + const GRAH_ADI: &[[&str; 2]] = &[ + ["", "grah"], + ["ud", "sah"], + ["ud", "das"], + ["ud", "BAs"], + ["", "sTA"], + ["", "mantr"], + ["sam", "mard"], + ["ni", "rakz"], + ["ni", "Sru"], + ["ni", "vas"], + ["ni", "vap"], + ["ni", "SA"], + ]; + const PAC_ADI: &[&str] = &[ "pac", "vac", "vap", "vad", "cal", "tap", "pat", "nadaw", "Bazaw", "vas", "garat", "plavaw", "cIraw", "mAhaw", "jara", "mara", "kzara", "kzama", "sUdaw", "devaw", "moraw", @@ -379,6 +397,10 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { let dhatu = wrap.get(i)?; if dhatu.has_antya('u') || dhatu.has_antya('U') { wrap.optional_try_add("3.1.125", K::Ryat); + } else if dhatu.has_u("ha\\na~") { + wrap.optional_try_add_with("3.1.97.v2", K::yat, |p, i| { + p.set(i, |t| t.set_text("vaD")); + }); } // General rules (obligatory) @@ -387,6 +409,8 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { if dhatu.has_upadha('a') && dhatu.has_antya(&*PU) { // Sapya, laBya, japya wrap.try_add("3.1.98", K::yat); + } else if dhatu.has_u_in(&["taka~", "Sasu~\\", "cate~^", "yatI~\\", "janI~\\"]) { + wrap.try_add("3.1.97.v1", K::yat); } else if dhatu.has_antya('f') || dhatu.has_antya('F') || dhatu.has_antya(&*HAL) { wrap.try_add("3.1.124", K::Ryat); } else if dhatu.has_antya(&*AC) { @@ -410,17 +434,23 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { // "a" (3.1.134 - ???) K::ac | K::Sa | K::ka | K::Ra => { + // These are all bhvAdi dhAtus, so also check for `Bhvadi` to avoid other dhatus. let pa_ghra = &["pA\\", "GrA\\", "DmA\\", "De\\w", "df\\Si~r"]; - if dhatu.has_u_in(pa_ghra) && dhatu.has_gana(Gana::Bhvadi) { - // These are all bhvAdi dhAtus, so enforce `Bhvadi` to avoid other dhatus. + if upasarge && dhatu.has_u_in(pa_ghra) && dhatu.has_gana(Gana::Bhvadi) { wrap.try_add("3.1.137", K::Sa); + } else if dhatu.has_u_in(&[ + "li\\pa~^", "vi\\dx~^", "pF", "vida~", "cita~", "sAti", "zaha~\\", + ]) { + wrap.try_add("3.1.138", K::Sa); } else if dhatu.has_upadha(&*IK) || dhatu.has_u_in(&["JYA\\", "prI\\Y", "kF"]) { // vikzipa, viliKa, buDa wrap.try_add("3.1.135", K::ka); } else if upasarge && dhatu.has_antya('A') { wrap.try_add("3.1.136", K::ka); - } else if is_nandi_grahi_pacadi(&wrap, i) { + } else if krt == K::ac { + // ajvidhiḥ sarvadhātubhyaḥ paṭhyante ca pacādayaḥ। aṇbādhanārtham eva + // syāt sidhyanti śvapacādayaḥ। wrap.try_add("3.1.134", K::ac); } else if dhatu.has_u_in(&["wudu\\", "RI\\Y"]) && !upasarge { wrap.try_add("3.1.142", K::Ra); @@ -459,6 +489,20 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { } } + K::wa => { + if dhatu.has_u("cara~") { + // TODO: upapada + wrap.try_add("3.2.16", krt); + } + } + + K::Kac => { + if dhatu.has_u("vada~") { + // TODO: restrict + wrap.try_add("3.2.38", krt); + } + } + K::kvin => { if dhatu.has_text("spfS") { wrap.try_add("3.2.58", krt); @@ -485,9 +529,25 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { } } - K::manin | K::kvanip | K::vanip => { + K::Rvi => { + if dhatu.has_u("Ba\\ja~^") { + wrap.try_add("3.2.62", krt); + } + } + + K::manin | K::kvanip | K::vanip | K::vic => { + let code = "3.2.75"; if krt == K::manin && dhatu.has_text("Bas") { - wrap.try_add("3.2.75", krt); + wrap.try_add(code, krt); + } else if krt == K::vic && dhatu.has_text("riz") { + wrap.try_add(code, krt); + } + } + + K::qa => { + if dhatu.has_u("janI~\\") { + // TODO: upapada + wrap.try_add("3.2.97", krt); } } @@ -619,18 +679,38 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { } K::GaY => { - // TODO: move with other a-pratyayas? - let dhatu = wrap.get(i)?; - if dhatu.has_text_in(&["pad", "ruj", "viS", "spfS"]) { - wrap.try_add("3.3.16", K::GaY); - } else if dhatu.has_text("sf") { - wrap.try_add("3.3.17", K::GaY); + if wrap.has_prefix("ava") && dhatu.has_u_in(&["tF", "stFY"]) { + wrap.try_add("3.3.120", K::GaY); } else { - wrap.try_add("3.3.18", K::GaY); + // TODO: move with other a-pratyayas? + let dhatu = wrap.get(i)?; + if dhatu.has_text_in(&["pad", "ruj", "viS", "spfS"]) { + wrap.try_add("3.3.16", K::GaY); + } else if dhatu.has_text("sf") { + wrap.try_add("3.3.17", K::GaY); + } else { + wrap.try_add("3.3.18", K::GaY); + } } } - K::ktri => {} + K::ap => { + if dhatu.has_u("aja~") && i > 0 && wrap.p.has(i - 1, |t| t.has_u_in(&["sam", "ud"])) { + wrap.try_add("3.3.69", krt); + } + } + + K::ktri => { + if dhatu.has_tag(T::qvit) { + if wrap.try_add("3.3.88", krt) { + // TODO: put this somewhere else? + wrap.p.op("4.4.20", |p| { + p.push(Taddhita::map.to_term()); + }); + it_samjna::run(wrap.p, i + 2).expect("should never fail"); + } + } + } K::aTuc => { if dhatu.has_tag(T::wvit) { @@ -657,6 +737,14 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { wrap.try_add_with("3.3.94", krt, |p, _| p.add_tag(T::Stri)); } + K::a => { + if dhatu.is_pratyaya() { + wrap.try_add_with("3.3.102", krt, |p, _| p.add_tag(T::Stri)); + } else if dhatu.is_guru() && dhatu.has_antya(&*HAL) { + wrap.try_add_with("3.3.103", krt, |p, _| p.add_tag(T::Stri)); + } + } + K::yuc => { if dhatu.has_u_in(&["Ric", "Asa~\\", "SranTa~"]) { wrap.try_add_with("3.3.107", krt, |p, _| p.add_tag(T::Stri)); @@ -673,18 +761,30 @@ fn try_add_krt(p: &mut Prakriya, krt: Krt) -> Option { K::Ga => {} - K::Kal => {} + K::Kal => { + // TODO: restrict + wrap.try_add("3.3.126", krt); + } K::ktic => { wrap.try_add("3.3.174", krt); } - + K::kamul | K::Ramul => { + if krt == K::kamul { + wrap.try_add("3.4.12", krt); + } else { + // TODO: move this rule somewhere else? + wrap.try_add("3.4.22", krt); + } + } + K::kasun => { + if dhatu.has_u_in(&["sf\\px~", "u~tfdi~^r"]) { + wrap.try_add("3.4.17", krt); + } + } K::ktvA => { wrap.try_add("3.4.21", krt); } - K::Ramul => { - wrap.try_add("3.4.22", krt); - } _ => (), } diff --git a/vidyut-prakriya/src/krt/unadi_sutras.rs b/vidyut-prakriya/src/krt/unadi_sutras.rs index aa00515..95d5f45 100644 --- a/vidyut-prakriya/src/krt/unadi_sutras.rs +++ b/vidyut-prakriya/src/krt/unadi_sutras.rs @@ -1,9 +1,44 @@ +/*! +The Unadipatha and its rules. + +The Unadipatha contains around 750 sutras that are divided into 5 sections. These sutras define +miscellaneous krt-pratyayas that cause limited or unusual changes. In essence, the Unadipatha is +a collection of ad-hoc derivations, some of which feel more speculative than others. + +The pratyayas in the Unadipatha enter the Ashtadhyayi through rule 3.3.1: + +> 3.1.1 उणादयो बहुलम् +> (The affixes uṇ, etc. apply variously.) + + +### Design notes + +Our module below is a work-in-progress sketch and uses the version of the text available [on +ashtadhyayi.com][unadi]. + +For now, we have stored Unadi pratyayas on our `Krt` enum. Points in favor of this decision: + +- Unadi pratyayas are "just" krt pratyayas, so it makes sense to store them in the same way. +- Storing all krt pratyayas in the same way is simpler for downstream code. For example, storing + them in a separate enum variant causes complications for our WebAssembly bindings, which expect + flat C-style enums. + +Points against: + +- There is a real difference between general krt pratyayas and unAdi pratyayas. Roughly, the + unAdi list is much larger and much less interesting for most applications. +- Our system cannot distinguish between these two kinds of pratyayas, which affects how + downstream code interacts with this project. + +As this module develops, we will probably split the Unadi pratyayas into their own enum. + +[unadi]: https://ashtadhyayi.com/unaadi +*/ use crate::args::Krt; use crate::krt::utils::KrtPrakriya; use crate::prakriya::{Prakriya, Rule}; use crate::tag::Tag as T; -/// A work-in-progress sketch of the uNAdi sutras. pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { use Krt as K; use Rule::Unadi; @@ -17,7 +52,7 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { } // Pre-calculate some common properties. - let _upasarge = prev.map_or(false, |t| t.is_upasarga()); + let upasarge = prev.map_or(false, |t| t.is_upasarga()); let _supi = prev.map_or(false, |t| t.has_tag(T::Sup)); // For convenience below, wrap `Prakriya` in a new `KrtPrakriya` type that contains `krt` and @@ -25,23 +60,30 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { let mut wrap = KrtPrakriya::new(p, krt); let dhatu = wrap.get(i)?; - // For convenience below, wrap `Prakriya` in a new `KrtPrakriya` type that contains `krt` and - // records whether or not any of these rules were applied. + let has_upasarga = |text| i > 0 && wrap.p.has(i, |t| t.has_text(text)); + match krt { K::uR => { if dhatu.has_u_in(&[ "qukf\\Y", "vA\\", "pA\\", "ji\\", "qumi\\Y", "zvada~\\", "sA\\Da~", "aSU~\\", ]) { + // kAru, vAyu, ... wrap.try_add(Unadi("1.1"), krt); } } K::YuR => { if dhatu.has_u("tF") { + // tAlu wrap.try_add_with(Unadi("1.5"), krt, |p, i| { p.set(i, |t| t.set_antya("l")); }); } } + K::wizac => { + if dhatu.has_u_in(&["ava~", "maha~"]) { + wrap.try_add(Unadi("1.45"), krt); + } + } K::tun => { if dhatu.has_u_in(&[ "zi\\Y", "tanu~^", "ga\\mx~", "masI~", "zaca~\\", "ava~", "quDA\\Y", "kru\\Sa~", @@ -51,6 +93,7 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { } K::katu => { if dhatu.has_u("qukf\\Y") { + // kratu wrap.try_add(Unadi("1.77"), krt); } } @@ -71,6 +114,7 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { } K::sara => { if dhatu.has_u("aSU~\\") { + // akzara wrap.try_add(Unadi("3.70"), krt); } } @@ -78,9 +122,33 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { if dhatu.has_u_in(&[ "hase~", "mf\\N", "gF", "i\\R", "vA\\", "ama~", "damu~", "lUY", "pUY", "DurvI~", ]) { + // hasta, ... wrap.try_add(Unadi("3.86"), krt); } } + + K::Jac => { + if dhatu.has_text_in(&["jF", "viS"]) { + // jaranta, veSanta + wrap.try_add(Unadi("3.126"), krt); + } else if dhatu.has_text_in(&["ruh", "nand", "jIv"]) + || (upasarge && has_upasarga("pra") && dhatu.has_text("an")) + { + wrap.try_add_with(Unadi("3.127"), krt, |p, i| { + p.set(i + 1, |t| t.add_tag(T::zit)); + }); + // rohanta, nadanta ... + } else if dhatu + .has_text_in(&["tF", "BU", "vah", "vas", "BAs", "sAD", "ganq", "manq", "ji"]) + { + // taranta, Bavanta, ... + // TODO: nandayanta + wrap.try_add_with(Unadi("3.128"), krt, |p, i| { + p.set(i + 1, |t| t.add_tag(T::zit)); + }); + } + } + K::ksi => { if dhatu.has_u_in(&["pluza~", "kuza~", "Su\\za~"]) { wrap.try_add(Unadi("3.155"), krt); @@ -92,6 +160,7 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { } K::ksu => { if dhatu.has_u("izu~") { + // ikzu wrap.try_add(Unadi("3.157"), krt); } } @@ -118,6 +187,7 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { wrap.try_add(code, krt); } K::alic if dhatu.has_u("anjU~") => { + // aYjali wrap.try_add(code, krt); } K::izWuc if dhatu.has_u("vana~") => { @@ -126,16 +196,20 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { K::izWac if dhatu.has_u("anjU~") => { wrap.try_add(code, krt); } - K::isan if dhatu.has_u("f\\") && wrap.p.has(i + 1, |t| t.has_u("Ric")) => { + K::isan if dhatu.has_u("f\\") && wrap.p.has(i + 2, |t| t.has_u("Ric")) => { + // `i + 2` to skip pu~k (ar + p + i) wrap.try_add(code, krt); } K::syan if dhatu.has_u("madI~") => { + // matsya wrap.try_add(code, krt); } K::iTin if dhatu.has_u("ata~") => { + // atiTi wrap.try_add(code, krt); } K::uli if dhatu.has_u("anga") => { + // aNguli wrap.try_add(code, krt); } K::asa if dhatu.has_u("ku\\") => { @@ -159,6 +233,17 @@ pub fn try_add_unadi(p: &mut Prakriya, krt: Krt) -> Option { K::zwran => { wrap.try_add(Unadi("4.158"), krt); } + K::amac => { + if dhatu.has_u("praTa~\\") { + wrap.try_add(Unadi("5.68"), krt); + } else if dhatu.has_u("cara~") { + wrap.try_add(Unadi("5.69"), krt); + } + } + K::alac if dhatu.has_u("magi~") => { + // maNgala + wrap.try_add(Unadi("5.70"), krt); + } _ => (), } diff --git a/vidyut-prakriya/src/krt/utils.rs b/vidyut-prakriya/src/krt/utils.rs index 511928e..ab640b1 100644 --- a/vidyut-prakriya/src/krt/utils.rs +++ b/vidyut-prakriya/src/krt/utils.rs @@ -79,13 +79,6 @@ impl<'a> KrtPrakriya<'a> { } } - /// If there's a match, adds the given `krt` pratyaya. - /// - /// This method does nothing if a krt pratyaya has already been added. - pub fn try_add(&mut self, rule: impl Into, krt: Krt) -> bool { - self.try_add_with(rule, krt, |_p, _i| {}) - } - /// If there's a match, replace the `lakAra` of the dhatu. /// /// This method does nothing if a krt pratyaya has already been added. @@ -100,21 +93,6 @@ impl<'a> KrtPrakriya<'a> { } } - /// If there's a match, optionally adds the given `krt` pratyaya. - /// - /// This method does nothing if a krt pratyaya has already been added. - pub fn optional_try_add(&mut self, rule: impl Into + Copy, krt: Krt) -> bool { - if krt == self.krt && !self.has_krt { - if self.p.is_allowed(rule) { - self.try_add_with(rule, krt, |_p, _i| {}); - return true; - } else { - self.p.decline(rule); - } - } - false - } - /// If there's a match, adds the given `krt` pratyaya then runs `func`. /// /// This method does nothing if a krt pratyaya has already been added. @@ -139,4 +117,39 @@ impl<'a> KrtPrakriya<'a> { false } } + + /// If there's a match, adds the given `krt` pratyaya. + /// + /// This method does nothing if a krt pratyaya has already been added. + pub fn try_add(&mut self, rule: impl Into, krt: Krt) -> bool { + self.try_add_with(rule, krt, |_p, _i| {}) + } + + /// If there's a match, optionally adds the given `krt` pratyaya then runs `func`. + /// + /// This method does nothing if a krt pratyaya has already been added. + pub fn optional_try_add_with( + &mut self, + rule: impl Into + Copy, + krt: Krt, + func: impl Fn(&mut Prakriya, usize), + ) -> bool { + if krt == self.krt && !self.has_krt { + // TODO: resolve inconsistency with TaddhitaPratyaya::optional_try_add_with. + if self.p.is_allowed(rule) { + self.try_add_with(rule, krt, func); + return true; + } else { + self.p.decline(rule); + } + } + false + } + + /// If there's a match, optionally adds the given `krt` pratyaya. + /// + /// This method does nothing if a krt pratyaya has already been added. + pub fn optional_try_add(&mut self, rule: impl Into + Copy, krt: Krt) -> bool { + self.optional_try_add_with(rule, krt, |_p, _i| {}) + } } diff --git a/vidyut-prakriya/src/la_karya.rs b/vidyut-prakriya/src/la_karya.rs index b029d86..d65db96 100644 --- a/vidyut-prakriya/src/la_karya.rs +++ b/vidyut-prakriya/src/la_karya.rs @@ -7,6 +7,7 @@ use crate::term::Term; fn add_la(rule: Code, p: &mut Prakriya, i: usize, la: &str) { let mut la = Term::make_upadesha(la); la.add_tag(T::Pratyaya); + la.add_tag(T::La); p.insert_after(i, la); p.step(rule); diff --git a/vidyut-prakriya/src/lib.rs b/vidyut-prakriya/src/lib.rs index 3adcb1f..c53ca3c 100644 --- a/vidyut-prakriya/src/lib.rs +++ b/vidyut-prakriya/src/lib.rs @@ -59,10 +59,10 @@ mod sanadi; mod stem_gana; mod stritva; mod sup_karya; -mod taddhita_gana; -mod taddhita_pratyaya; +mod taddhita; mod tin_pratyaya; mod tripadi; +mod uttarapade; mod vikarana; pub mod wasm; diff --git a/vidyut-prakriya/src/prakriya.rs b/vidyut-prakriya/src/prakriya.rs index 4884656..f5ed441 100644 --- a/vidyut-prakriya/src/prakriya.rs +++ b/vidyut-prakriya/src/prakriya.rs @@ -1,3 +1,4 @@ +use crate::args::Lakara; use crate::tag::Tag; use crate::term::{Term, TermView}; use compact_str::CompactString; @@ -22,6 +23,8 @@ pub enum Rule { Unadi(&'static str), /// A sutra from the Paniniya-Linganushasanam. Linganushasana(&'static str), + /// A quotation from the Vaiyakarana-siddhanta-kaumudi. + Kaumudi(&'static str), } // Since Ashtadhyayi rules are by far the most common, assume by default that static strings refer @@ -41,6 +44,7 @@ pub struct Step { impl Step { /// The rule that produced the current step. + // TODO: render different `Rule` types differently. pub fn rule(&self) -> Code { match self.rule { Rule::Ashtadhyayi(x) => x, @@ -48,11 +52,15 @@ impl Step { Rule::Dhatupatha(x) => x, Rule::Unadi(x) => x, Rule::Linganushasana(x) => x, + Rule::Kaumudi(x) => x, } } - /// The result of this step. This result is a simple string representation and might change in - /// the future. + /// The result of applying `rule`. + /// + /// For now, `result` is a simple string. In the future, we might convert this into a richer + /// structure with more information about the specific change. For example, we might explicitly + /// indicate which term in the result was changed. pub fn result(&self) -> &String { &self.result } @@ -88,6 +96,7 @@ pub struct Prakriya { history: Vec, config: Config, rule_decisions: Vec, + lakara: Option, } /// Public API @@ -126,6 +135,7 @@ impl Prakriya { history: Vec::new(), config: Config::new(), rule_decisions: Vec::new(), + lakara: None, } } @@ -169,6 +179,8 @@ impl Prakriya { self.terms.get_mut(i) } + /// Returns the term at index `i` if it matches the condition in `filter` or `None` if the term + /// does not exist or fails the condition. pub(crate) fn get_if(&self, i: usize, filter: impl Fn(&Term) -> bool) -> Option<&Term> { if let Some(t) = self.get(i) { if filter(t) { @@ -178,6 +190,11 @@ impl Prakriya { None } + /// Returns whether the given prakriya express bhAve/karmani prayoga. + pub(crate) fn is_bhave_or_karmani(&self) -> bool { + self.any(&[Tag::Bhave, Tag::Karmani]) + } + /// Returns whether the given term can be called "pada". pub(crate) fn is_pada(&self, i: usize) -> bool { if let Some(t) = self.get(i) { @@ -280,23 +297,38 @@ impl Prakriya { } } + /// Returns whether the prakriya has any of the given `tags`. pub(crate) fn any(&self, tags: &[Tag]) -> bool { tags.iter().any(|t| self.tags.contains(*t)) } + /// Returns whether the prakriya has the given `tag`. pub(crate) fn has_tag(&self, tag: Tag) -> bool { self.tags.contains(tag) } + pub(crate) fn has_tag_in(&self, tags: &[Tag]) -> bool { + tags.iter().any(|t| self.tags.contains(*t)) + } + // Basic mutators - pub(crate) fn add_tag(&mut self, t: Tag) { - self.tags.insert(t); + /// Adds a tag to the prakriya. + pub(crate) fn add_tag(&mut self, tag: Tag) { + self.tags.insert(tag); } #[allow(unused)] - pub(crate) fn remove_tag(&mut self, t: Tag) { - self.tags.remove(t); + pub(crate) fn remove_tag(&mut self, tag: Tag) { + self.tags.remove(tag); + } + + pub(crate) fn set_lakara(&mut self, lakara: Lakara) { + self.lakara = Some(lakara); + } + + pub(crate) fn has_lakara(&self, lakara: Lakara) -> bool { + self.lakara == Some(lakara) } pub(crate) fn add_tags(&mut self, tags: &[Tag]) { @@ -324,6 +356,15 @@ impl Prakriya { self.terms.push(t); } + pub(crate) fn maybe_save_sthanivat(&mut self) { + for i in 0..self.terms().len() { + let t = self.get_mut(i).expect("ok"); + if t.is_dhatu() { + t.maybe_save_sthanivat(); + } + } + } + // Rule application /// Applies the given operator. @@ -369,7 +410,7 @@ impl Prakriya { } } - /// Adds a rule to the history. + /// Adds a rule and its result to the 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| { diff --git a/vidyut-prakriya/src/pratipadika_karya.rs b/vidyut-prakriya/src/pratipadika_karya.rs index 379b238..3dd82d1 100644 --- a/vidyut-prakriya/src/pratipadika_karya.rs +++ b/vidyut-prakriya/src/pratipadika_karya.rs @@ -15,6 +15,9 @@ pub fn run(p: &mut Prakriya, pratipadika: &Pratipadika, linga: Linga) -> Option< if pratipadika.is_dhatu() { term.add_tag(T::Dhatu); } + if pratipadika.is_udit() { + term.add_tag(T::udit); + } if pratipadika.is_pratyaya() { term.add_tag(T::Pratyaya); } diff --git a/vidyut-prakriya/src/samjna.rs b/vidyut-prakriya/src/samjna.rs index 9e8fba1..9790d6a 100644 --- a/vidyut-prakriya/src/samjna.rs +++ b/vidyut-prakriya/src/samjna.rs @@ -2,7 +2,7 @@ use crate::operators as op; use crate::prakriya::Prakriya; use crate::sounds as al; use crate::sounds::{s, Set}; -use crate::stem_gana::{LAUKIKA_SAMJNA, PRATHAMA_ADI, PURVA_ADI, SARVA_ADI, USES_DATARA_DATAMA}; +use crate::stem_gana::{LAUKIKA_SANKHYA, PRATHAMA_ADI, PURVA_ADI, SARVA_ADI, USES_DATARA_DATAMA}; use crate::tag::Tag as T; use crate::term::Term; use lazy_static::lazy_static; @@ -31,7 +31,8 @@ fn try_run_for_pratipadika(p: &mut Prakriya) -> Option<()> { let ii_uu = prati.has_antya('I') || prati.has_antya('U'); let i_u = prati.has_antya('i') || prati.has_antya('u'); - if prati.has_text_in(LAUKIKA_SAMJNA) { + if prati.has_text_in(&["bahu", "gaRa"]) || prati.has_text_in(LAUKIKA_SANKHYA) { + // TODO: vatu, qati p.op_term("1.1.23", i, op::add_tag(T::Sankhya)); let prati = p.get(i)?; if prati.has_antya('z') || prati.has_antya('n') { @@ -47,17 +48,44 @@ fn try_run_for_pratipadika(p: &mut Prakriya) -> Option<()> { if sarvanama { p.op_term("1.1.27", i, op::add_tag(T::Sarvanama)); } - } else if ii_uu && p.has_tag(T::Stri) { - p.op_term("1.4.3", i, op::add_tag(T::Nadi)); - } else if i_u && !prati.has_text_in(&["saKi", "pati"]) { - // TODO: patiH *samAsa eva* + } else if i_u || ii_uu { let sup = p.get(i + 1)?; - let mut is_nadi = false; - if sup.has_tag(T::Nit) && p.has_tag(T::Stri) { - is_nadi = p.op_optional("1.4.6", op::t(i, op::add_tag(T::Nadi))); + + // iyan-uvan are defined in 6.4.77 (Snu-dhAtu-bhruvAm) -- only dhAtu and bhrU apply here. + let iyan_uvan_astri = + (prati.has_text("BrU") || prati.is_dhatu()) && !prati.has_text("strI"); + let stri_linga = p.has_tag(T::Stri); + + // default: nadI + // not: iyan-uvan-astrI + // optional: for Am + // optional: iyan-uvan-astri and hrasva + // if option declined and short and not sakhi: ghi + + let mut decided = false; + if stri_linga && (iyan_uvan_astri || i_u) && sup.has_tag(T::Nit) { + decided = p.op_optional("1.4.6", op::t(i, op::add_tag(T::Nadi))); } - if !is_nadi { - p.op_term("1.4.7", i, op::add_tag(T::Ghi)); + + let prati = p.get(i)?; + let sup = p.get(i + 1)?; + if i_u && !decided && !prati.has_text("saKi") { + // TODO: patiH samAsa eva + if !prati.has_text("pati") { + p.op_term("1.4.7", i, op::add_tag(T::Ghi)); + } + } else if ii_uu { + if iyan_uvan_astri { + if sup.has_u("Am") { + p.op_optional("1.4.5", op::t(i, op::add_tag(T::Nadi))); + } else { + // "he SrIH", "he BrUH", but "he stri" + p.step("1.4.4"); + } + } else { + // Base case + p.op_term("1.4.3", i, op::add_tag(T::Nadi)); + } } } @@ -82,11 +110,15 @@ 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? } else { let next = p.view(i + 1)?; // Includes both sup-pratayas and taddhitas, per SK on 1.4.17. let is_svadi = next.has_tag_in(&[T::Sup, T::Taddhita]); - if is_svadi && !next.has_tag(T::Sarvanamasthana) { + + if next.has_tag(T::sit) { + p.op_term("1.4.16", i, op::add_tag(T::Pada)); + } else if is_svadi && !next.has_tag(T::Sarvanamasthana) { if next.has_adi('y') || next.has_adi(&*AC) { p.op_term("1.4.18", i, op::add_tag(T::Bha)); } else if (term.has_antya('t') || term.has_antya('s')) @@ -122,6 +154,16 @@ fn try_run_for_sup(p: &mut Prakriya) -> Option<()> { Some(()) } +fn try_run_for_taddhita(p: &mut Prakriya) -> Option<()> { + let i = p.find_last(T::Taddhita)?; + + if p.has(i, |t| t.has_u_in(&["tarap", "tamap"])) { + p.op_term("1.1.22", i, |t| t.add_tag(T::Gha)); + } + + Some(()) +} + fn try_run_for_dhatu_pratyaya(p: &mut Prakriya, i: usize) -> Option<()> { // TODO: add other exclusions here. let pratyaya = p.get_if(i, |t| !t.has_tag_in(&[T::Sup, T::Taddhita]))?; @@ -167,4 +209,5 @@ pub fn run(p: &mut Prakriya) { try_run_for_dhatu(p); try_run_for_pratipadika(p); try_run_for_sup(p); + try_run_for_taddhita(p); } diff --git a/vidyut-prakriya/src/samprasarana.rs b/vidyut-prakriya/src/samprasarana.rs index e65d418..9a82317 100644 --- a/vidyut-prakriya/src/samprasarana.rs +++ b/vidyut-prakriya/src/samprasarana.rs @@ -34,29 +34,74 @@ fn is_grahi_jya(t: &Term) -> bool { ]) } -/// Runs a hacky version of samprasarana that runs 6.1.108 (samprasAraNAcca) immediately. -/// -/// TODO: properly annotate 6.1.108 and related rules here. -fn do_samprasarana(rule: Code, p: &mut Prakriya, i: usize) -> Option<()> { - let before = &[ - "vac", "svap", "yaj", "vap", "vah", "vas", "ve", "vye", "hve", "vad", "Svi", +fn find_samprasarana_match(p: &Prakriya, i: usize) -> Option<&'static str> { + const BEFORE: &[&str] = &[ + "va\\ca~", + "va\\ci~", + "Yizva\\pa~", + "ya\\ja~^", + "quva\\pa~^", + "va\\ha~^", + "va\\sa~", + "ve\\Y", + "vye\\Y", + "hve\\Y", + "vada~", + "wuo~Svi", // grahi-jyA - "grah", "jyA", "vay", "vyaD", "vaS", "vyac", "vrasc", "praC", "Brasj", + "graha~^", + "jyA\\", + // vayi~ replaces ve\\Y in 2.4.41 + "vayi~", + // not sure how to handle "vay" root + "vaya~\\", + "vya\\Da~", + "vaSa~", + "vyaca~", + "o~vrascU~", + "pra\\Ca~", + "Bra\\sja~^", // other rules - "syam", + "syama~", + "syamu~", ]; - let after = &[ - "uc", "sup", "ij", "up", "uh", "us", "u", "vI", "hU", "ud", "SU", // grahi-jyA - "gfh", "ji", "uy", "viD", "uS", "vic", "vfSc", "pfC", "Bfsj", // other rules - "sim", + const AFTER: &[&str] = &[ + // vaci-svapi + "uc", "uc", "sup", "ij", "up", "uh", "us", "u", "vI", "hU", "ud", "SU", + // grahi-jyA + "gfh", "ji", "uy", "uy", "viD", "uS", "vic", "vfsc", "pfC", "Bfsj", + // other rules + "sim", "sim", ]; - let text = &p.get(i)?.text; - if let Some(j) = before.iter().position(|x| x == text) { - p.op_term(rule, i, |t| { - t.set_text(after[j]); - t.add_tag(T::FlagSamprasarana); - }); + debug_assert!(BEFORE.len() == AFTER.len()); + + let dhatu = &p.get(i)?; + if let Some(j) = BEFORE.iter().position(|x| dhatu.has_u(x)) { + Some(AFTER[j]) + } else { + None } +} + +/// Runs a hacky version of samprasarana that runs 6.1.108 (samprasAraNAcca) immediately. +/// +/// TODO: properly annotate 6.1.108 and related rules here. +fn do_samprasarana(rule: Code, p: &mut Prakriya, i_dhatu: usize) -> Option<()> { + let after = find_samprasarana_match(p, i_dhatu)?; + p.op_term(rule, i_dhatu, |t| { + t.set_text(after); + t.add_tag(T::FlagSamprasarana); + }); + Some(()) +} + +fn do_samprasarana_for_abhyasa(rule: Code, p: &mut Prakriya, i_abhyasa: usize) -> Option<()> { + let i_dhatu = i_abhyasa + 1; + let after = find_samprasarana_match(p, i_dhatu)?; + p.op_term(rule, i_abhyasa, |t| { + t.set_text(after); + t.add_tag(T::FlagSamprasarana); + }); Some(()) } @@ -65,6 +110,12 @@ pub fn run_for_dhatu(p: &mut Prakriya) -> Option<()> { let i_n = p.find_next_where(i, |t| !t.is_empty())?; let dhatu = p.get(i)?; + + // Don't apply samprasarana rules twice (for sanAdi-dhatus) + if dhatu.has_tag(T::FlagSamprasarana) { + return None; + } + let n = p.view(i_n)?; let n_is_yan = n.has_u("yaN"); let n_is_lit = n.has_lakshana("li~w"); @@ -155,21 +206,21 @@ pub fn run_for_dhatu(p: &mut Prakriya) -> Option<()> { } pub fn run_for_abhyasa(p: &mut Prakriya) -> Option<()> { - let i = p.find_first(T::Abhyasa)?; - let dhatu = p.get_if(i + 1, |t| t.is_dhatu())?; + let i_abhyasa = p.find_first_where(|t| t.is_abhyasa() && !t.has_tag(T::Complete))?; + let dhatu = p.get_if(i_abhyasa + 1, |t| t.is_dhatu())?; let last = p.terms().last()?; 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.has_text("Svi") { + if is_vaci_svapi(dhatu) && !dhatu.text.starts_with("Sv") { if dhatu.has_u("ve\\Y") { p.step("6.1.40"); } else { - do_samprasarana("6.1.17", p, i); + do_samprasarana_for_abhyasa("6.1.17", p, i_abhyasa); } } else if is_grahi_jya(dhatu) { - do_samprasarana("6.1.17", p, i); + do_samprasarana_for_abhyasa("6.1.17", p, i_abhyasa); } } diff --git a/vidyut-prakriya/src/sanadi.rs b/vidyut-prakriya/src/sanadi.rs index 8bfa905..c4626e4 100644 --- a/vidyut-prakriya/src/sanadi.rs +++ b/vidyut-prakriya/src/sanadi.rs @@ -4,6 +4,7 @@ use crate::dhatu_gana as gana; use crate::filters as f; use crate::it_samjna; use crate::operators as op; +use crate::prakriya::Rule; use crate::prakriya::{Code, Prakriya}; use crate::sounds::{s, Set}; use crate::tag::Tag as T; @@ -33,8 +34,23 @@ fn add_sanadi(rule: Code, p: &mut Prakriya, i_dhatu: usize, upadesha: &str) { it_samjna::run(p, i_pratyaya).expect("ok") } -// TODO: 3.1.8 - 3.1.21 -pub fn run(p: &mut Prakriya, is_ardhadhatuka: bool, sanadi: &[Sanadi]) -> Option<()> { +/// 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; + + let i_yan = p.find_last_where(|t| t.is_pratyaya() && t.has_u("yaN"))?; + + // Apply luk. + p.op_term("2.4.74", i_yan, op::lopa); + + // "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.op_term(DP("02.0076"), i_yan, |d| d.set_gana(Gana::Adadi)); + + Some(()) +} + +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)?; @@ -98,16 +114,20 @@ pub fn run(p: &mut Prakriya, is_ardhadhatuka: bool, sanadi: &[Sanadi]) -> Option } } - // General sanAdi-pratyayas - // ------------------------ + 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. - for s in sanadi { - let i = p.find_last(T::Dhatu)?; - let dhatu = p.get(i)?; - if *s == Sanadi::San { + let i = p.find_last(T::Dhatu)?; + let dhatu = p.get(i)?; + match sanadi { + Sanadi::San => { add_sanadi("3.1.7", p, i, "san"); - } else if *s == Sanadi::Yan || *s == Sanadi::YanLuk { + } + 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"]))) @@ -117,7 +137,13 @@ pub fn run(p: &mut Prakriya, is_ardhadhatuka: bool, sanadi: &[Sanadi]) -> Option } else if f::is_eka_ac(dhatu) && dhatu.has_adi(&*HAL) { add_sanadi("3.1.22", p, i, "yaN"); } - } else if *s == Sanadi::Nic { + + // 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"); } } @@ -132,19 +158,26 @@ mod tests { use crate::dhatu_karya; use crate::dhatupatha; - fn check_sanadi(upadesha: &str, gana: Gana, number: u16, sanadi: &[Sanadi]) -> (Term, Term) { + 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(); - run(&mut p, false, sanadi).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) { - check_sanadi(upadesha, gana, number, &[]) + 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] @@ -170,7 +203,7 @@ mod tests { #[test] fn test_hetumati() { - let (_, nic) = check_sanadi("BU", Gana::Bhvadi, 1, &[Sanadi::Nic]); + let (_, nic) = check_sanadi("BU", Gana::Bhvadi, 1, Sanadi::Nic); assert_eq!(nic.text, "i"); assert!(nic.is_pratyaya()); } diff --git a/vidyut-prakriya/src/sounds.rs b/vidyut-prakriya/src/sounds.rs index eb5723c..7398fae 100644 --- a/vidyut-prakriya/src/sounds.rs +++ b/vidyut-prakriya/src/sounds.rs @@ -320,6 +320,8 @@ pub fn is_samyoganta(text: &str) -> bool { pub fn to_guna(s: Sound) -> Option<&'static str> { let res = match s { + // TODO: remove 'a' | 'A' line + 'a' | 'A' => "a", 'i' | 'I' => "e", 'u' | 'U' => "o", 'f' | 'F' => "ar", @@ -375,11 +377,11 @@ pub fn to_dirgha(s: Sound) -> Option { Some(res) } -/// Returns the sounds contained the given pratyahara. +/// Returns the sounds contained in the given pratyahara. /// -/// Since the it letter `R` is duplicated, we disambiguate as follows: -/// - `R` refers to the first `R`. -/// - `R2` refers to the second `R`. +/// Since the it letter `R` appears twice in the Maheshvara sutras, we disambiguate as follows: +/// - `R` refers to the first `R` (a i u R). +/// - `R2` refers to the second `R` (la R). fn pratyahara(s: &str) -> Set { let first = s.as_bytes()[0] as char; @@ -423,12 +425,22 @@ fn pratyahara(s: &str) -> Set { Set::from(&res) } +/// Parses a list of upadeshas and returns the sound set it corresponds to. +/// +/// Upadeshas this function accepts: +/// - pratyaharas ("ac", "hal") +/// - udit sounds ("ku~", "pu~") +/// - vowels ("a", "e") +/// - simple consonants ("h", "k") +/// +/// `s` is an abbrevation for "sound_set." Since this function is so frequent in the codebase, we +/// have shortened its name for brevity. pub fn s(terms: &str) -> Set { let mut ret = String::new(); - let ak = ["a", "A", "i", "I", "u", "U", "f", "F", "x", "X"]; + const AK: &[&str] = &["a", "A", "i", "I", "u", "U", "f", "F", "x", "X"]; for term in terms.split_whitespace() { - if term.ends_with("u~") || ak.contains(&term) { + if term.ends_with("u~") || AK.contains(&term) { let first = term.chars().next().expect("non-empty"); ret += &savarna(first).to_string(); } else if term.len() == 1 { @@ -479,6 +491,7 @@ enum Prayatna { /// Models the phonetic properties of a Sanskrit sound. struct Uccarana { + // Some sounds have multiple sthanas, e.g. "e" (kantha-talavya) and "va" (dantoshtya). sthana: Vec, ghosha: Ghosha, prana: Prana, @@ -486,8 +499,11 @@ struct Uccarana { } impl Uccarana { - /// Calculates a heuristic distance between this sound and another. The shorter the distance, - /// the closer the sounds are. + /// Calculates a heuristic distance score between this sound and another. The shorter the + /// distance, the closer the sounds are. + /// + /// TODO: this score is not symmetric -- a.distance(b) != b.distance(a). What are the + /// implications of this? Does a symmetric score still work? fn distance(&self, other: &Uccarana) -> usize { let mut dist = 0; if self.ghosha != other.ghosha { @@ -532,7 +548,7 @@ pub fn is_savarna(x: Sound, y: Sound) -> bool { savarna_str(x) == savarna_str(y) } -/// Creates a `savarna` set for teh given sound. +/// Creates a `savarna` set for the given sound. pub fn savarna(c: Sound) -> Set { Set::from(savarna_str(c)) } diff --git a/vidyut-prakriya/src/stem_gana.rs b/vidyut-prakriya/src/stem_gana.rs index 2ad61de..26eed22 100644 --- a/vidyut-prakriya/src/stem_gana.rs +++ b/vidyut-prakriya/src/stem_gana.rs @@ -8,8 +8,8 @@ pub const SARVA_ADI: &[&str] = &[ "Bavatu~", "kim", ]; -pub const LAUKIKA_SAMJNA: &[&str] = &[ - "eka", "dvi", "tri", "catur", "paYcan", "zaz", "saptan", "azwan", "navan", "daSan", +pub const LAUKIKA_SANKHYA: &[&str] = &[ + "eka", "dvi", "tri", "catur", "paYcan", "zaz", "saptan", "azwan", "navan", "daSan", "zoqaSan", ]; pub const TYAD_ADI: &[&str] = &["tyad", "tad", "yad", "etad", "idam", "adas", "eka", "dvi"]; diff --git a/vidyut-prakriya/src/taddhita.rs b/vidyut-prakriya/src/taddhita.rs new file mode 100644 index 0000000..68c507c --- /dev/null +++ b/vidyut-prakriya/src/taddhita.rs @@ -0,0 +1,12 @@ +use crate::args::Taddhita; +use crate::prakriya::Prakriya; + +mod basic; +mod gana; +mod utils; + +/// Runs the rules that add a taddhita-pratyaya to a given pratipadika. +/// Returns whether a pratyaya was added. +pub fn run(p: &mut Prakriya, t: Taddhita) -> bool { + basic::try_add_taddhita(p, t).unwrap_or(false) +} diff --git a/vidyut-prakriya/src/taddhita/basic.rs b/vidyut-prakriya/src/taddhita/basic.rs new file mode 100644 index 0000000..cf1afb3 --- /dev/null +++ b/vidyut-prakriya/src/taddhita/basic.rs @@ -0,0 +1,497 @@ +/*! +Runs rules that add taddhita-pratyayas after a prAtipadika.. + +*Status: experimental.* +*/ + +use crate::args::Taddhita; +use crate::it_samjna; +use crate::operators as op; +use crate::prakriya::Prakriya; +use crate::taddhita::gana; +use crate::taddhita::utils::TaddhitaPrakriya; +use crate::tag::Tag as T; +use crate::term::Term; + +impl Taddhita { + pub(crate) fn to_term(self) -> Term { + let mut taddhita = Term::make_upadesha(self.as_str()); + taddhita.add_tags(&[T::Pratyaya, T::Taddhita]); + taddhita + } +} + +fn add_vibhakti_pratyayas(p: &mut Prakriya, t: Taddhita) -> Option { + let i = p.terms().len() - 1; + let prati = p.get(i)?; + + let add = |rule, p: &mut Prakriya, t: Taddhita| { + let i = p.terms().len(); + let taddhita = t.to_term(); + p.terms_mut().push(taddhita); + p.step(rule); + + if t != Taddhita::at { + // TODO: not sure how to support `at`. + p.set(i, |t| t.add_tag(T::Vibhakti)); + } + + it_samjna::run(p, i).expect("should never fail"); + }; + + // Use `P` because `T` conventionally refers to `Tag`. + use Taddhita as P; + match t { + P::tasil => { + if prati.has_u_in(&["kim", "bahu"]) || prati.has_tag(T::Sarvanama) { + add("5.3.7", p, t); + } else if prati.has_u_in(&["pari", "aBi"]) { + add("5.3.9", p, t); + } + } + P::tral | P::ha => { + let is_ha = t == P::ha; + if prati.has_u("idam") { + if is_ha { + add("5.3.11", p, t); + } + } else if prati.has_u_in(&["kim", "bahu"]) || prati.has_tag(T::Sarvanama) { + if prati.has_u("kim") && is_ha { + add("5.3.10", p, t); + } else { + add("5.3.13", p, t); + } + } + } + P::at => { + if prati.has_u("kim") { + add("5.3.12", p, t); + } + } + P::dA | P::rhil | P::dAnIm => { + if prati.has_u_in(&["sarva", "eka", "anya", "kim", "yad", "tad"]) { + if prati.has_u("tad") && t == P::dAnIm { + add("5.3.19", p, t); + } else { + add("5.3.15", p, t); + } + } else if prati.has_u("idam") { + if t == P::rhil { + add("5.3.16", p, t); + } else if t == P::dAnIm { + add("5.3.18", p, t); + } + } + } + P::TAl | P::Tamu => { + let is_tham = t == P::Tamu; + if prati.has_u("idam") && is_tham { + add("5.3.23", p, t); + } else if prati.has_u("kim") && is_tham { + add("5.3.24", p, t); + } else { + add("5.3.25", p, t); + } + } + _ => return None, + } + + let added = p.terms().last()?.is_taddhita(); + + if added { + let prati = p.get(i)?; + let t = p.get(i + 1)?; + if prati.has_u("idam") { + if t.has_adi('r') || t.has_adi('T') { + let sub = if t.has_adi('r') { "eta" } else { "it" }; + p.op_term("5.3.4", i, |t| t.set_text(sub)); + } else { + p.op_term("5.3.3", i, |t| t.set_text("i")); + } + } else if prati.has_u("etad") { + p.op_term("5.3.5", i, |t| t.set_text("a")); + } else if prati.has_u("sarva") && t.has_adi('d') { + p.op_optional("5.3.6", op::t(i, |t| t.set_text("sa"))); + } + } + + Some(added) +} + +pub fn try_add_taddhita(p: &mut Prakriya, t: Taddhita) -> Option { + let i = p.terms().len() - 1; + + // Use `P` because `T` conventionally refers to `Tag`. + use Taddhita as P; + let mut wrap = TaddhitaPrakriya::new(p, t); + let prati = wrap.p.get(i)?; + + match t { + P::aR => { + if prati.has_text("ftu") { + wrap.try_add("5.1.105", t); + } else { + wrap.try_add("4.1.83", t); + } + } + P::iY => { + if prati.has_antya('a') { + wrap.try_add("4.1.95", t); + } else if prati.has_suffix_in(gana::BAHU_ADI) { + // HACK: check suffix instead of uttarapada + wrap.try_add("4.1.96", t); + } + } + P::cPaY => { + const KUNJA_ADI: &[&str] = &[ + "kuYja", "braDna", "SaNKa", "Basman", "gaRa", "loman", "SaWa", "SAka", "SAkawa", + "SuRqA", "SuBa", "vipASa", "skanda", "stamBa", + ]; + if prati.has_text_in(KUNJA_ADI) { + wrap.try_add("4.1.98", t); + } + } + P::Pak => { + if prati.has_text_in(gana::NADA_ADI) { + wrap.try_add("4.1.99", t); + } + } + P::yaY => { + if prati.has_text_in(gana::GARGA_ADI) { + wrap.try_add("4.1.105", t); + } else if prati.has_text_in(&["maDu", "baBru"]) { + wrap.try_add("4.1.106", t); + } else if prati.has_text_in(&["kapi", "boDa"]) { + wrap.try_add("4.1.107", t); + } else if prati.has_text("vataRqa") { + wrap.try_add("4.1.108", t); + } + } + P::PaY => { + if prati.has_text_in(gana::ASHVA_ADI) { + wrap.try_add("4.1.110", t); + } else if prati.has_text("Barga") { + wrap.try_add("4.1.111", t); + } + } + P::Qak => { + let is_dvi_ac = prati.num_vowels() == 2; + if prati.has_antya('i') && is_dvi_ac { + // Atreya, ... + // TODO: an-iY + wrap.try_add("4.1.122", t); + } else if prati.has_text_in(gana::SHUBHRA_ADI) { + wrap.try_add("4.1.123", t); + } else if prati.has_text_in(&["vikarRa", "kuzItaka"]) { + wrap.try_add("4.1.124", t); + } else if prati.has_text("BrU") { + if wrap.try_add_with("4.1.125", t, |p| op::insert_agama_after(p, i, "vu~k")) { + it_samjna::run(wrap.p, i + 1).expect("ok"); + } + } else if prati.has_text_in(&gana::KALYANI_ADI) { + wrap.try_add_with("4.1.126", t, |p| p.set(i, |t| t.set_antya("in"))); + } else if prati.has_text("kulawA") { + wrap.optional_try_add_with("4.1.127", t, |p| p.set(i, |t| t.set_antya("in"))); + } else if prati.has_text("pitfzvasf") { + wrap.try_add_with("4.1.133", t, |p| p.set(i, |t| t.set_antya(""))); + } else if prati.has_text("mAtfzvasf") { + wrap.try_add_with("4.1.134", t, |p| p.set(i, |t| t.set_antya(""))); + } else if prati.has_text_in(&["vrIhi", "SAli"]) { + wrap.try_add("5.2.2", t); + } + + // General case. + let prati = wrap.p.get(i)?; + if prati.has_tag(T::Stri) { + if is_dvi_ac { + // dAtteya, ... + wrap.try_add("4.1.121", t); + } else { + // sOparReya, ... + wrap.try_add("4.1.120", t); + } + } + } + P::Qrak => { + if prati.has_text("goDA") { + wrap.try_add("4.1.129", t); + } + } + P::QaY => { + if prati.has_text_in(&[ + "gfzwi", "hfzwi", "bali", "hali", "viSri", "kudri", "ajavasti", "mitrayu", + ]) { + wrap.try_add("4.1.136", t); + } + } + P::Arak => { + if prati.has_text("goDA") { + wrap.try_add("4.1.130", t); + } + } + P::CaR => { + if prati.has_text("pitfzvasf") { + wrap.try_add("4.1.132", t); + } else if prati.has_text("mAtfzvasf") { + wrap.try_add("4.1.134", t); + } + } + P::Erak => { + if prati.has_text("cawakA") { + wrap.try_add("4.1.129", t); + } else if prati.has_text("cawaka") { + wrap.try_add("4.1.129.v1", t); + } + } + P::Ga => { + if prati.has_text("kzatra") { + wrap.try_add("4.1.138", t); + } + } + P::Ka => { + if prati.has_text("kula") { + wrap.try_add("4.1.139", t); + } + } + P::Wak => { + if prati.has_text_in(gana::REVATI_ADI) { + wrap.try_add("4.1.146", t); + } else if prati.has_text("Bavat") { + wrap.try_add("4.2.115", t); + } else { + wrap.try_add("4.4.1", t); + } + } + P::PiY => { + if prati.has_tag(T::Vrddha) { + wrap.try_add("4.1.157", t); + } + } + P::Gac => {} + P::qmatup => { + if prati.has_text_in(&["kumuda", "naqa", "vetasa"]) { + wrap.try_add("4.2.87", t); + } + } + P::Ca => { + if prati.has_tag(T::Vrddha) { + wrap.try_add("4.2.114", t); + } + } + P::Cas => { + if prati.has_text("Bavat") { + wrap.try_add("4.2.115", t); + } + } + P::aY => { + // TODO: prARi-rajatAdi + wrap.try_add("4.3.154", t); + } + P::WaY => { + if prati.has_text("lavaRa") { + wrap.try_add("4.4.52", t); + } + } + P::zWan => { + const KISHARA_ADI: &[&str] = &[ + "kiSara", + "narada", + "nalada", + "sumaNgala", + "tagara", + "guggulu", + "uSIra", + "haridrA", + "haridrAyaRI", + ]; + if prati.has_text_in(&KISHARA_ADI) { + wrap.try_add("4.4.53", t); + } + } + P::yat => { + const GO_ADI: &[&str] = &[ + "go", "havis", "varhiz", "Kawa", "azwakA", "yuga", "meDA", "srak", "nABi", "naBam", + ]; + if prati.has_text_in(&["rAjan", "Svasura"]) { + wrap.try_add("4.1.137", t); + } else if prati.has_antya('u') || prati.has_antya('U') || prati.has_text_in(&GO_ADI) { + wrap.try_add("5.1.2", t); + } else if prati.has_text_in(&["yava", "yavaka", "zazwika"]) { + // TODO: block KaY + wrap.try_add("5.2.3", t); + } + } + P::kan => { + const STHULA_ADI: &[&str] = &[ + "sTUla", + "aRu", + "mAza", + "izu", + "kfzRa", + "yava", + "ikzu", + "tila", + "pAdya", + "kAla", + "avadAta", + "gomUtra", + "surA", + "jIrRa", + "patra", + "mUla", + "kumArIputra", + "kumAra", + "SvaSura", + "maRi", + ]; + if prati.has_tag(T::Sankhya) { + wrap.try_add("5.1.22", t); + } else if prati.has_text_in(&STHULA_ADI) { + wrap.try_add("5.4.3", t); + } else if prati.has_text_in(&["caYcut", "bfhat"]) { + wrap.try_add("5.4.3.v1", t); + } + } + P::qvun => { + if prati.has_text_in(&["viMSati", "triMSat"]) { + wrap.try_add("5.1.24", t); + } + } + P::Gas => { + if prati.has_text("ftu") { + wrap.try_add("5.1.106", t); + } + } + P::tva | P::tal => { + if prati.has_u("deva") { + wrap.try_add("5.4.27", t); + } else { + wrap.try_add("5.1.119", t); + } + } + P::imanic => { + if prati.has_text_in(gana::PRTHU_ADI) { + wrap.try_add("5.1.122", t); + } + } + P::KaY => { + wrap.try_add("5.2.94", t); + } + P::matup => { + wrap.try_add("5.2.94", t); + } + P::lac => { + if prati.has_antya('A') { + wrap.try_add("5.2.96", t); + } + } + P::Sa | P::na | P::ilac => { + 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", + ]; + if (t == P::Sa && prati.has_text_in(&LOMA_ADI)) + || (t == P::na && prati.has_text_in(&PAMA_ADI)) + || (t == P::ilac && prati.has_text_in(&PICCHA_ADI)) + { + wrap.try_add("5.2.100", t); + } + } + P::vini => { + if prati.text.ends_with("as") || prati.has_u_in(&["mAyA", "meDA", "sraj"]) { + wrap.try_add("5.2.121", t); + } + } + P::yus => { + if prati.has_text("UrRA") { + wrap.try_add("5.2.123", t); + } + } + P::DA => { + if prati.has_tag(T::Sankhya) { + wrap.try_add("5.3.42", t); + } + } + P::tamap | P::izWan => { + wrap.try_add("5.3.55", t); + } + P::tarap | P::Iyasun => { + wrap.try_add("5.3.57", t); + } + P::rUpap => { + // vaiyAkaraRarUpa + wrap.try_add("5.3.66", t); + } + P::kalpap | P::deSya | P::deSIyar => { + // pawukalpa + wrap.try_add("5.3.67", t); + } + P::akac => { + if prati.has_tag(T::Sarvanama) { + wrap.try_add("5.3.71", t); + } + } + P::kftvasuc | P::suc => { + if prati.has_tag(T::Sankhya) { + if prati.has_u("eka") { + // TODO: replace with sakft + wrap.try_add("5.4.19", P::suc); + } else if prati.has_u_in(&["dvi", "tri", "catur"]) { + wrap.try_add("5.4.18", P::suc); + } else { + wrap.try_add("5.4.17", P::kftvasuc); + } + } + } + P::mayaw => { + wrap.try_add("5.4.21", t); + } + P::Yya => { + if prati.has_u_in(&[ + "SaRqika", + "sarvasena", + "sarvakeSa", + "Saka", + "sawa", + "raka", + "SaNKa", + "boDa", + ]) { + wrap.try_add("4.3.92", t); + } else if prati.has_u_in(&["ananta", "AvasaTa", "itiha", "Bezaja"]) { + wrap.try_add("5.4.23", t); + } else if prati.has_u("atiTi") { + wrap.try_add("5.4.26", t); + } + } + P::Sas => { + if prati.has_tag(T::Sankhya) { + wrap.try_add("5.4.43", t); + } + } + P::tikan => { + if prati.has_u("mfd") { + wrap.try_add("5.4.39", t); + } + } + P::tasi => { + wrap.try_add("5.4.44", t); + } + P::sAti => { + wrap.try_add("5.4.52", t); + } + _ => { + add_vibhakti_pratyayas(p, t); + } + } + + let added = p.terms().last()?.is_taddhita(); + Some(added) +} diff --git a/vidyut-prakriya/src/taddhita/gana.rs b/vidyut-prakriya/src/taddhita/gana.rs new file mode 100644 index 0000000..a0a3f13 --- /dev/null +++ b/vidyut-prakriya/src/taddhita/gana.rs @@ -0,0 +1,343 @@ +/// For 4.1.96. +pub const BAHU_ADI: &[&str] = &[ + "bAhu", + "upabAhu", + "upavAku", + "nivAku", + "SivAku", + "vawAku", + "upanindu", + "upabindu", + "vfzalI", + "vfkalA", + "cUqA", + "balAkA", + "mUzikA", + "kuSalA", + "BagalA", + "CagalA", + "DruvakA", + "DuvakA", + "sumitrA", + "durmitrA", + "puzkarasad", + "anuharat", + "devaSarman", + "agniSarman", + "BadraSarman", + "suSarman", + "kunAman", + "sunAman", + "paYcan", + "saptan", + "azwan", + // amitOjasa has sa-lopa + "amitOjasa", + "suDAvat", + "udaYcu", + "Siras", + "mAza", + "SarAvin", + "marIcI", + "kSemavfdDin", + "SfNKalatodin", + "KaranAdin", + "nagaramardin", + "prAkAramardin", + "loman", + "ajIgarta", + "kfzra", + "yuDizWira", + "arjuna", + "sAmba", + "gada", + "pradyumna", + "rAma", + "udaNku", +]; + +/// For 4.1.99. +pub const NADA_ADI: &[&str] = &[ + "naqa", + "cara", + "baka", + "muYja", + "itika", + "itiSa", + "upaka", + "lamaka", + "SalaNku", + "SalaNkam", + "saptala", + "vAjapya", + "tika", + "agniSarman", + "prARa", + "nara", + "sAyaka", + "dAsa", + "mitra", + "dvIpa", + "piNgara", + "piNgala", + "kiNkara", + "kiNkala", + "kAtara", + "kAtala", + "kASya", + "kASyapa", + "kAvya", + "aja", + "amuzya", + "kfzRa", + "raRa", + "amitra", + "ligu", + "citra", + "kumAra", + "krozwu", + "krozwam", + "loha", + "durga", + "stamBa", + "SiMSipA", + "agra", + "tfRa", + "Sakawa", + "sumanas", + "sumata", + "mimata", + "fk", + "jat", + "yuganDara", + "haMsaka", + "daRqin", + "hastin", + "paYcAla", + "camasin", + "sukftya", + "sTiraka", + "brAhmaRa", + "cawaka", + "badara", + "aSvala", + "Karapa", + "kAmuka", + "vrahmadatta", + "udumbara", + "SoRa", + "aloha", + "daRqa", +]; + +/// For 4.1.105. +pub const GARGA_ADI: &[&str] = &[ + "garga", + "vatsa", + "vAjAse", + "saMskfti", + "aja", + "vyAGrapAt", + "vidaBft", + "prAcInayoga", + "agasti", + "pulasti", + "reBa", + "agniveSa", + "SaNKa", + "SaWa", + "GUma", + "avawa", + "camasa", + "DanaYjaya", + "manasa", + "vfkza", + "viSvAvasu", + "janamAna", + "lohita", + "SaMsita", + "baBru", + "maRqu", + "makzu", + "aligu", + "SaNku", + "ligu", + "gulu", + "mantu", + "jigIzu", + "manu", + "tantu", + "manAyI", + "BUta", + "kaTaka", + "kaza", + "taRqa", + "vataRqa", + "kapi", + "kata", + "kurukata", + "anaquH", + "kaRva", + "Sakala", + "gokakza", + "agastya", + "kuRqina", + "yajYavalka", + "uBaya", + "jAta", + "virohita", + "vfzagaRa", + "rahUgaRa", + "SaRqila", + "vaRa", + "kaculuka", + "mudgala", + "musala", + "parASara", + "jatUkarRa", + "mAntrita", + "saMhita", + "aSmaraTa", + "SarkarAkza", + "pUtimAza", + "sTURa", + "araraka", + "piNgala", + "kfzRa", + "golunda", + "ulUka", + "titikza", + "Bizaj", + "Baqita", + "BaRqita", + "dalBa", + "cikita", + "devahU", + "indrahU", + "ekalU", + "pippalU", + "vfdagni", + "jamadagni", + "suloBin", + "ukatTa", + "kuwIgu", +]; + +/// For 4.1.110. +pub const ASHVA_ADI: &[&str] = &[ + "aSva", + "aSman", + "SaNKa", + "pawu", + "rohiRa", + "KarjUra", + "KarjUla", + "piYjUra", + "Baqila", + "BaRqila", + "Baqita", + "BaRqita", + "BaRqika", + "prahfta", + "romAda", + "kzatra", + "grIvA", + "kASa", + "golANkya", + "arka", + "svana", + "Dvana", + "pAda", + "cakra", + "kula", + "pavitra", + "gomin", + "SyAma", + "DUma", + "DUmra", + "vAgmin", + "viSvAnara", + "kuwa", + "veSa", + "Sapa", + "natta", + "taqa", + "naqa", + "grIzma", + "arha", + "viSamya", + "viSAlA", + "giri", + "capala", + "cunama", + "dAsaka", + "vElya", + "Darma", + "Anaquhra", + "puMsijAta", + "arjuna", + "SUdraka", + "sumanas", + "durmanas", + "kzAnta", + "prAcya", + "kita", + "kARa", + "cumba", + "SravizWA", + "vIkzya", + "pavindA", + "Atreya", + "kutsa", + "Atava", + "kitava", + "Siva", + "Kadira", + "BAradvAja", +]; + +/// For 4.1.123. +pub const SHUBHRA_ADI: &[&str] = &[ + "SuBra", + "vizwapura", + // TODO: many others +]; + +/// For 4.1.126. +pub const KALYANI_ADI: &[&str] = &[ + "kalyARI", + "suBagA", + "durBagA", + "banDakI", + "anudfzwi", + "anusfzwi", + "jaratI", + "balIvardI", + "jyezWA", + "kanizWA", + "maDyamA", + "parastrI", +]; + +/// For 4.1.146. +pub const REVATI_ADI: &[&str] = &[ + "revatI", + "aSvapAlI", + "maRipAlI", + "dvArapAlI", + "vfkavaYcin", + "vfkabanDu", + "vfkagrAha", + "karRagrAha", + "daRqagrAha", + "kukkUwAkza", + "kakudAkza", + "cAmaragrAha", +]; + +/// For 5.1.122. +pub const PRTHU_ADI: &[&str] = &[ + "pfTu", "mfdu", "mahat", "pawu", "tanu", "laGu", "bahu", "sADu", "veRu", "ASu", "bahula", + "guru", "daRqa", "uru", "KaRqa", "caRqa", "bAla", "akiYcana", "hoqa", "pAka", "vatsa", "manda", + "svAdu", "hrasva", "dIrGa", "priya", "vfza", "fju", "kzipra", "kzupra", "kzudra", +]; diff --git a/vidyut-prakriya/src/taddhita/utils.rs b/vidyut-prakriya/src/taddhita/utils.rs new file mode 100644 index 0000000..2bd5a6d --- /dev/null +++ b/vidyut-prakriya/src/taddhita/utils.rs @@ -0,0 +1,79 @@ +use crate::args::Taddhita; +use crate::it_samjna; +use crate::prakriya::{Prakriya, Rule}; + +/// Wrapper for `Prakriya` with the following features: +/// +/// - remembers which `taddhita` pratyaya the caller wishes to add. +/// - records whether a `taddhita` pratyaya has been added or not, which simplifies the control +/// flow for optional rules. +pub struct TaddhitaPrakriya<'a> { + pub p: &'a mut Prakriya, + pub taddhita: Taddhita, + pub tried: bool, + pub has_taddhita: bool, +} + +impl<'a> TaddhitaPrakriya<'a> { + /// Creates a new `TaddhitaPrakriya` struct. + pub fn new(p: &'a mut Prakriya, taddhita: Taddhita) -> Self { + TaddhitaPrakriya { + p, + taddhita, + tried: false, + has_taddhita: false, + } + } + + /// If there's a match, adds the given `taddhita` pratyaya. + /// + /// This method does nothing if a pratyaya has already been added. + pub fn try_add(&mut self, rule: &'static str, taddhita: Taddhita) -> bool { + self.try_add_with(rule, taddhita, |_| {}) + } + + /// If there's a match, adds the given `taddhita` pratyaya then runs `func`. + /// + /// This method does nothing if a pratyaya has already been added. + pub fn try_add_with( + &mut self, + rule: impl Into, + taddhita: Taddhita, + func: impl Fn(&mut Prakriya), + ) -> bool { + self.tried = true; + if taddhita == self.taddhita && !self.has_taddhita { + self.p.op(rule.into(), |p| { + p.push(taddhita.to_term()); + func(p); + }); + + let i_last = self.p.terms().len() - 1; + it_samjna::run(self.p, i_last).expect("should never fail"); + self.has_taddhita = true; + true + } else { + false + } + } + + /// If there's a match, optionally adds the given `krt` pratyaya then runs `func`. + /// Returns if the option succeeded. + /// + /// This method does nothing if a krt pratyaya has already been added. + pub fn optional_try_add_with( + &mut self, + rule: impl Into + Copy, + taddhita: Taddhita, + func: impl Fn(&mut Prakriya), + ) -> bool { + if taddhita == self.taddhita && !self.has_taddhita { + if self.p.is_allowed(rule) { + return self.try_add_with(rule, taddhita, func); + } else { + self.p.decline(rule); + } + } + false + } +} diff --git a/vidyut-prakriya/src/taddhita_gana.rs b/vidyut-prakriya/src/taddhita_gana.rs deleted file mode 100644 index 3096745..0000000 --- a/vidyut-prakriya/src/taddhita_gana.rs +++ /dev/null @@ -1,181 +0,0 @@ -pub const NADADI: &[&str] = &[ - "naqa", - "cara", - "baka", - "muYja", - "itika", - "itiSa", - "upaka", - "lamaka", - "SalaNku", - "SalaNkam", - "saptala", - "vAjapya", - "tika", - "agniSarman", - "prARa", - "nara", - "sAyaka", - "dAsa", - "mitra", - "dvIpa", - "piNgara", - "piNgala", - "kiNkara", - "kiNkala", - "kAtara", - "kAtala", - "kASya", - "kASyapa", - "kAvya", - "aja", - "amuzya", - "kfzRa", - "raRa", - "amitra", - "ligu", - "citra", - "kumAra", - "krozwu", - "krozwam", - "loha", - "durga", - "stamBa", - "SiMSipA", - "agra", - "tfRa", - "Sakawa", - "sumanas", - "sumata", - "mimata", - "fk", - "jat", - "yuganDara", - "haMsaka", - "daRqin", - "hastin", - "paYcAla", - "camasin", - "sukftya", - "sTiraka", - "brAhmaRa", - "cawaka", - "badara", - "aSvaka", - "Karapa", - "kAmuka", - "vrahmadatta", - "udumbara", - "SoRa", - "aloha", - "daRqa", -]; - -/// For 4.1.96. Copied from the Kashika Vrtti on ashtadhyayi.com -pub const GARGADI: &[&str] = &[ - "garga", - "vatsa", - "vAjAse", - "saMskfti", - "aja", - "vyAGrapAt", - "vidaBft", - "prAcInayoga", - "agasti", - "pulasti", - "reBa", - "agniveSa", - "SaNKa", - "SaWa", - "GUma", - "avawa", - "camasa", - "DanaYjaya", - "manasa", - "vfkza", - "viSvAvasu", - "janamAna", - "lohita", - "SaMsita", - "baBru", - "maRqu", - "makzu", - "aligu", - "SaNku", - "ligu", - "gulu", - "mantu", - "jigIzu", - "manu", - "tantu", - "manAyI", - "BUta", - "kaTaka", - "kaza", - "taRqa", - "vataRqa", - "kapi", - "kata", - "kurukata", - "anaquH", - "kaRva", - "Sakala", - "gokakza", - "agastya", - "kuRqina", - "yajYavalka", - "uBaya", - "jAta", - "virohita", - "vfzagaRa", - "rahUgaRa", - "SaRqila", - "vaRa", - "kaculuka", - "mudgala", - "musala", - "parASara", - "jatUkarRa", - "mAntrita", - "saMhita", - "aSmaraTa", - "SarkarAkza", - "pUtimAza", - "sTURa", - "araraka", - "piNgala", - "kfzRa", - "golunda", - "ulUka", - "titikza", - "Bizaj", - "Baqita", - "BaRqita", - "dalBa", - "cikita", - "devahU", - "indrahU", - "ekalU", - "pippalU", - "vfdagni", - "jamadagni", - "suloBin", - "ukatTa", - "kuwIgu", -]; - -/// For 4.1.146. Copied from the Kashika Vrtti on ashtadhyayi.com -pub const REVATYADI: &[&str] = &[ - "revatI", - "aSvapAlI", - "maRipAlI", - "dvArapAlI", - "vfkavaYcin", - "vfkabanDu", - "vfkagrAha", - "karRagrAha", - "daRqagrAha", - "kukkUwAkza", - "kakudAkza", - "cAmaragrAha", -]; diff --git a/vidyut-prakriya/src/taddhita_pratyaya.rs b/vidyut-prakriya/src/taddhita_pratyaya.rs deleted file mode 100644 index 9d39e13..0000000 --- a/vidyut-prakriya/src/taddhita_pratyaya.rs +++ /dev/null @@ -1,225 +0,0 @@ -/*! -Runs rules that add taddhita-pratyayas after a prAtipadika.. - -*Status: experimental.* -*/ - -use crate::args::Taddhita; -use crate::it_samjna; -use crate::operators as op; -use crate::prakriya::Prakriya; -use crate::taddhita_gana as gana; -use crate::tag::Tag as T; -use crate::term::Term; - -impl Taddhita { - fn to_term(self) -> Term { - let mut taddhita = Term::make_upadesha(self.as_str()); - taddhita.add_tags(&[T::Pratyaya, T::Taddhita]); - taddhita - } -} - -fn add_vibhakti_pratyayas(p: &mut Prakriya, t: Taddhita) -> Option { - let i = p.terms().len() - 1; - let prati = p.get(i)?; - - let add = |rule, p: &mut Prakriya, t: Taddhita| { - let i = p.terms().len(); - let taddhita = t.to_term(); - p.terms_mut().push(taddhita); - p.step(rule); - - if t != Taddhita::at { - // TODO: not sure how to support `at`. - p.set(i, |t| t.add_tag(T::Vibhakti)); - } - - it_samjna::run(p, i).expect("should never fail"); - }; - - // Use `P` because `T` conventionally refers to `Tag`. - use Taddhita as P; - match t { - P::tasil => { - if prati.has_u_in(&["kim", "bahu"]) || prati.has_tag(T::Sarvanama) { - add("5.3.7", p, t); - } else if prati.has_u_in(&["pari", "aBi"]) { - add("5.3.9", p, t); - } - } - P::tral | P::ha => { - let is_ha = t == P::ha; - if prati.has_u("idam") { - if is_ha { - add("5.3.11", p, t); - } - } else if prati.has_u_in(&["kim", "bahu"]) || prati.has_tag(T::Sarvanama) { - if prati.has_u("kim") && is_ha { - add("5.3.10", p, t); - } else { - add("5.3.13", p, t); - } - } - } - P::at => { - if prati.has_u("kim") { - add("5.3.12", p, t); - } - } - P::dA | P::rhil | P::dAnIm => { - if prati.has_u_in(&["sarva", "eka", "anya", "kim", "yad", "tad"]) { - if prati.has_u("tad") && t == P::dAnIm { - add("5.3.19", p, t); - } else { - add("5.3.15", p, t); - } - } else if prati.has_u("idam") { - if t == P::rhil { - add("5.3.16", p, t); - } else if t == P::dAnIm { - add("5.3.18", p, t); - } - } - } - P::TAl | P::Tamu => { - let is_tham = t == P::Tamu; - if prati.has_u("idam") && is_tham { - add("5.3.23", p, t); - } else if prati.has_u("kim") && is_tham { - add("5.3.24", p, t); - } else { - add("5.3.25", p, t); - } - } - _ => return None, - } - - let added = p.terms().last()?.is_taddhita(); - - if added { - let prati = p.get(i)?; - let t = p.get(i + 1)?; - if prati.has_u("idam") { - if t.has_adi('r') || t.has_adi('T') { - let sub = if t.has_adi('r') { "eta" } else { "it" }; - p.op_term("5.3.4", i, |t| t.set_text(sub)); - } else { - p.op_term("5.3.3", i, |t| t.set_text("i")); - } - } else if prati.has_u("etad") { - p.op_term("5.3.5", i, |t| t.set_text("a")); - } else if prati.has_u("sarva") && t.has_adi('d') { - p.op_optional("5.3.6", op::t(i, |t| t.set_text("sa"))); - } - } - - Some(added) -} - -fn try_add_taddhita(p: &mut Prakriya, t: Taddhita) -> Option { - let i = p.terms().len() - 1; - let prati = p.get(i)?; - - let add = |rule, p: &mut Prakriya, t: Taddhita| { - let i = p.terms().len(); - p.terms_mut().push(t.to_term()); - p.step(rule); - it_samjna::run(p, i).expect("should never fail"); - }; - - // Use `P` because `T` conventionally refers to `Tag`. - use Taddhita as P; - match t { - P::aR => { - add("4.1.83", p, t); - } - P::iY => { - if prati.has_antya('a') { - add("4.1.95", p, t); - } - } - P::Pak => { - if prati.has_text_in(gana::NADADI) { - add("4.1.99", p, t); - } - } - P::yaY => { - if prati.has_text_in(gana::GARGADI) { - add("4.1.105", p, t); - } - } - P::Qak => { - if prati.has_tag(T::Stri) { - add("4.1.120", p, t); - } - } - P::Ga => { - if prati.has_text("kzatra") { - add("4.1.138", p, t); - } - } - P::Ka => { - if prati.has_text("kula") { - add("4.1.139", p, t); - } - } - P::Wak => { - if prati.has_text_in(gana::REVATYADI) { - add("4.1.146", p, t); - } else { - add("4.4.1", p, t); - } - } - P::PiY => { - if prati.has_tag(T::Vrddha) { - add("4.1.157", p, t); - } - } - P::Gac => {} - P::Ca => { - if prati.has_tag(T::Vrddha) { - add("4.2.114", p, t); - } - } - P::yat => { - if prati.has_antya('u') || prati.has_antya('U') { - add("5.1.2", p, t); - } - } - P::tva | P::tal => { - add("5.1.119", p, t); - } - P::matup => { - add("5.2.94", p, t); - } - P::vini => { - if prati.text.ends_with("as") || prati.has_u_in(&["mAyA", "meDA", "sraj"]) { - add("5.2.121", p, t); - } - } - P::tamap | P::izWan => { - add("5.3.55", p, t); - } - P::tarap | P::Iyasun => { - add("5.3.57", p, t); - } - P::akac => { - if prati.has_tag(T::Sarvanama) { - add("5.3.71", p, t); - } - } - _ => { - add_vibhakti_pratyayas(p, t); - } - } - - let added = p.terms().last()?.is_taddhita(); - Some(added) -} - -/// Runs the rules that add a taddhita-pratyaya to a given pratipadika. -/// Returns whether a pratyaya was added. -pub fn run(p: &mut Prakriya, t: Taddhita) -> bool { - try_add_taddhita(p, t).unwrap_or(false) -} diff --git a/vidyut-prakriya/src/tag.rs b/vidyut-prakriya/src/tag.rs index 2f30dc0..1f56ad2 100644 --- a/vidyut-prakriya/src/tag.rs +++ b/vidyut-prakriya/src/tag.rs @@ -24,6 +24,7 @@ pub enum Tag { Sarvanama, Sarvanamasthana, Tin, + La, Nistha, Krt, Krtya, @@ -233,6 +234,8 @@ pub enum Tag { FlagIttva, /// Blocks a rule that causes dirgha. FlagNoDirgha, + // Indicates replacement of f/F with f (acIkftat, ...). + FlagUrRt, Sankhya, Sat, @@ -249,6 +252,13 @@ pub enum Tag { TrnTrc, Pada, Bha, + YanLuk, + Dvitva, + Gha, + + // Indicates that a derivation phase is complete, e.g. to avoid running abhyAsa rules + // twice. + Complete, } impl Tag { diff --git a/vidyut-prakriya/src/term.rs b/vidyut-prakriya/src/term.rs index 3fbab6f..faba149 100644 --- a/vidyut-prakriya/src/term.rs +++ b/vidyut-prakriya/src/term.rs @@ -1,10 +1,17 @@ use crate::args::{Antargana, Gana}; use crate::sounds; use crate::sounds::Pattern; +use crate::sounds::{s, Set}; use crate::tag::Tag; use compact_str::CompactString; use enumset::EnumSet; +use lazy_static::lazy_static; + +lazy_static! { + static ref AC: Set = s("ac"); +} + /// `Term` is a text string with additional metadata. It is a generalized version of an *upadesha* /// that also stores abhyAsas and other strings that don't have an upadesha associated with them. #[derive(Clone, Debug, Eq, PartialEq)] @@ -17,6 +24,11 @@ pub struct Term { pub u: Option, /// The text of this term. This string contains sound changes such as guna, vrddhi, lopa, etc. pub text: CompactString, + /// 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. + /// + /// For a complete example in English, see S. C. Vasu's commentary on rule 1.1.59, part (e). + sthanivat: CompactString, /// Various metadata associated with this term. tags: EnumSet, /// If this term is a dhatu, the dhatu's gana. @@ -25,7 +37,7 @@ pub struct Term { antargana: Option, /// All upadeshas that this term has had. This field is called `lakshanas` per rule 1.1.62 /// (*pratyayalopa pratyaylakshanam*). - lakshana: Vec, + lakshanas: Vec, } impl Term { @@ -37,10 +49,11 @@ impl Term { Term { u: Some(CompactString::from(s)), text: CompactString::from(s), + sthanivat: CompactString::from(s), tags: EnumSet::new(), gana: None, antargana: None, - lakshana: Vec::new(), + lakshanas: Vec::new(), } } @@ -49,10 +62,11 @@ impl Term { Term { u: None, text: CompactString::from(s), + sthanivat: CompactString::from(s), tags: EnumSet::new(), gana: None, antargana: None, - lakshana: Vec::new(), + lakshanas: Vec::new(), } } @@ -85,6 +99,8 @@ impl Term { } /// Returns the penultimate sound in the term if it exists. + /// + /// (1.1.65 alo'ntyāt pūrva upadhā) pub fn upadha(&self) -> Option { self.text.chars().rev().nth(1) } @@ -105,8 +121,8 @@ impl Term { } /// Returns whether the term has a first sound that matches the given pattern. - pub fn has_adi(&self, p: impl Pattern) -> bool { - self.matches_sound_pattern(self.adi(), p) + pub fn has_adi(&self, pattern: impl Pattern) -> bool { + self.matches_sound_pattern(self.adi(), pattern) } /// Returns whether the term has a final sound that matches the given pattern. @@ -120,8 +136,8 @@ impl Term { } /// Returns whether the term has a sound at index `i` that matches the given pattern. - pub fn has_at(&self, i: usize, p: impl Pattern) -> bool { - self.matches_sound_pattern(self.get_at(i), p) + pub fn has_at(&self, i: usize, pattern: impl Pattern) -> bool { + self.matches_sound_pattern(self.get_at(i), pattern) } /// Returns whether the term has a specific upadesha. @@ -141,15 +157,15 @@ impl Term { } pub fn has_any_lakshana(&self) -> bool { - !self.lakshana.is_empty() + !self.lakshanas.is_empty() } pub fn has_lakshana(&self, u: &str) -> bool { - self.lakshana.iter().any(|s| s == &u) + self.lakshanas.iter().any(|s| s == &u) } pub fn has_lakshana_in(&self, us: &[&str]) -> bool { - self.lakshana.iter().any(|s| us.contains(&s.as_str())) + self.lakshanas.iter().any(|s| us.contains(&s.as_str())) } /// Returns whether the term has the provided text. @@ -157,26 +173,32 @@ impl Term { self.text == text } - /// Returns whether the term's text matches any of the strings in `items`. + /// Returns whether the term's text is equal to any of the strings in `items`. pub fn has_text_in(&self, items: &[&str]) -> bool { items.contains(&self.text.as_str()) } - pub fn has_prefix_in(&self, terms: &[&str]) -> bool { - terms.iter().any(|t| self.text.starts_with(t)) + /// Returns whether the term's text starts with any of the given `prefixes`. + pub fn has_prefix_in(&self, prefixes: &[&str]) -> bool { + prefixes.iter().any(|t| self.text.starts_with(t)) + } + + /// Returns whether the term's text ends with any of the given `suffixes`. + pub fn has_suffix_in(&self, suffixes: &[&str]) -> bool { + suffixes.iter().any(|t| self.text.ends_with(t)) } - /// Returns whether the term's text ends with the given value. + /// Returns whether the term's text ends with the given `suffix`. pub fn ends_with(&self, suffix: &str) -> bool { self.text.ends_with(suffix) } - /// Returns whether the term has the given root gaNa. - pub fn has_gana_int(&self, gana: u8) -> bool { - self.has_gana(Gana::from_int(gana).expect("valid")) + /// Sets the dhatu's gana. + pub fn set_gana(&mut self, gana: Gana) { + self.gana = Some(gana); } - /// Returns whether the term has the given root gaNa. + /// Returns whether the term has the given dhatu gana. pub fn has_gana(&self, gana: Gana) -> bool { self.gana == Some(gana) } @@ -194,6 +216,17 @@ 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 + } + + /// 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() + } + // Tags and Samjnas // ---------------- @@ -202,12 +235,12 @@ impl Term { self.tags.contains(tag) } - /// Returns whether the term has all of the tags provided. + /// Returns whether the term has all of the tags in `tags`. pub fn has_all_tags(&self, tags: &[Tag]) -> bool { tags.iter().all(|t| self.tags.contains(*t)) } - /// Returns whether the term has any of the tags provided. + /// Returns whether the term has any of the tags in `tags`. pub fn has_tag_in(&self, tags: &[Tag]) -> bool { tags.iter().any(|t| self.tags.contains(*t)) } @@ -254,6 +287,11 @@ impl Term { self.has_tag(Tag::Dhatu) } + /// Returns whether the term has the `Pratipadika` samjna. + pub fn is_pratipadika(&self) -> bool { + self.has_tag(Tag::Pratipadika) + } + /// Returns whether the term is an Agama. pub fn is_agama(&self) -> bool { self.has_tag(Tag::Agama) @@ -294,13 +332,16 @@ impl Term { self.has_tag_in(&[Tag::kit, Tag::Nit]) } + /// Returns whether the term is apṛkta. + /// + /// (1.2.41 apṛkta ekāl pratyayaḥ) pub fn is_aprkta(&self) -> bool { self.is_pratyaya() && self.text.len() == 1 } /// Returns whether the term is the it-Agama. pub fn is_it_agama(&self) -> bool { - // We must check for `Agama` specifically so that we can exclude the tiN-pratyaya "iw". + // We must check `is_agama` specifically so that we can exclude the tiN-pratyaya "iw". self.is_agama() && self.has_u("iw") } @@ -317,7 +358,7 @@ impl Term { sounds::is_samyoganta(&self.text) } - /// Returns whether the last sound of `t` is a short vowel. + /// 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), @@ -325,7 +366,7 @@ impl Term { } } - /// Returns whether the last sound of `t` is a long vowel. + /// 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), @@ -333,7 +374,27 @@ impl Term { } } - /// Returns whether the last syllable of `t` is or could be laghu. + /// Returns whether the first syllable of the term is or could be laghu. + 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 @@ -355,6 +416,7 @@ impl Term { } } + /// Returns whether the last syllable of the term is guru. pub fn is_guru(&self) -> bool { !self.is_laghu() } @@ -389,7 +451,7 @@ impl Term { } } - /// Replaces the character at index `i` with `s`. + /// 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); } @@ -410,9 +472,42 @@ impl Term { self.text = CompactString::from(&alloc); } + pub fn sthanivat(&self) -> &CompactString { + &self.sthanivat + } + + pub fn maybe_save_sthanivat(&mut self) { + // sthani = srO, text = srAv + if self.text.is_empty() { + // If nothing is stored, always save. + self.sthanivat.replace_range(.., &self.text); + } else if self.sthanivat.ends_with('a') && !self.text.ends_with('a') { + // Don't save at-lopa (e.g. anga). + return; + } else if self.text.contains('x') { + // Don't save asiddha sounds. + return; + } else { + let sthanivat_antya = self.sthanivat.chars().rev().next().expect("ok"); + let text_antya = self.text.chars().rev().next().expect("ok"); + if sounds::is_ac(sthanivat_antya) { + if text_antya == 'y' || text_antya == 'v' { + // Don't save changes to the final vowel. + return; + } + } + // Default case. + self.sthanivat.replace_range(.., &self.text); + } + } + + pub fn force_save_sthanivat(&mut self) { + self.sthanivat.replace_range(.., &self.text); + } + pub fn save_lakshana(&mut self) { if let Some(u) = &self.u { - self.lakshana.push(CompactString::new(u)); + self.lakshanas.push(CompactString::new(u)); } } @@ -647,6 +742,7 @@ mod tests { assert!(!term("BU").is_laghu()); assert!(!term("uC").is_laghu()); assert!(!term("IS").is_laghu()); + assert!(!term("Ikz").is_laghu()); } #[test] diff --git a/vidyut-prakriya/src/tin_pratyaya.rs b/vidyut-prakriya/src/tin_pratyaya.rs index 9b0a45f..75a40d8 100644 --- a/vidyut-prakriya/src/tin_pratyaya.rs +++ b/vidyut-prakriya/src/tin_pratyaya.rs @@ -13,7 +13,7 @@ //! //! All of these rules are found at the end of section 3.4 of the Ashtadhyayi. -use crate::args::{Lakara, Purusha, Vacana}; +use crate::args::{Gana, Lakara, Purusha, Vacana}; use crate::errors::*; use crate::it_samjna; use crate::operators as op; @@ -100,7 +100,7 @@ fn maybe_replace_jhi_with_jus(p: &mut Prakriya, i: usize, la: Lakara) -> Option< let i_prev = p.find_prev_where(i, |t| !t.is_empty())?; let prev = p.get(i_prev)?; - let is_vid = prev.has_text("vid") && prev.has_gana_int(2); + let is_vid = prev.has_text("vid") && prev.has_gana(Gana::Adadi); if prev.has_u("si~c") || prev.has_tag(T::Abhyasta) || is_vid { op::adesha("3.4.109", p, i, "jus"); } else if prev.is_dhatu() { @@ -119,16 +119,18 @@ fn maybe_replace_jhi_with_jus(p: &mut Prakriya, i: usize, la: Lakara) -> Option< Some(()) } -fn maybe_do_lut_siddhi(p: &mut Prakriya, i_la: usize, la: Lakara, vacana: Vacana) -> bool { +fn maybe_do_lut_siddhi(p: &mut Prakriya, i_la: usize, la: Lakara) -> bool { let tin = match p.get(i_la) { Some(t) => t, _ => return false, }; if tin.has_tag(T::Prathama) && la == Lakara::Lut { - let ending = match vacana { - Vacana::Eka => "qA", - Vacana::Dvi => "rO", - Vacana::Bahu => "ras", + let ending = if tin.has_tag(T::Ekavacana) { + "qA" + } else if tin.has_tag(T::Dvivacana) { + "rO" + } else { + "ras" }; op::adesha("2.4.85", p, i_la, ending); true @@ -273,16 +275,12 @@ fn maybe_do_lot_and_nit_siddhi(p: &mut Prakriya, la: Lakara) { } } -/// Applies substitutions to the given tin suffix. -/// -/// Due to rule 3.4.109 ("sic-abhyasta-vidibhyaH ca"), this should run after dvitva and the -/// insertion of vikaraNas. -pub fn siddhi(p: &mut Prakriya, la: Lakara, vacana: Vacana) -> Option<()> { +fn siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { let i_dhatu = p.find_last(T::Dhatu)?; let i = p.find_last(T::Tin)?; // Special case: handle lut_siddhi first. - if maybe_do_lut_siddhi(p, i, la, vacana) { + if maybe_do_lut_siddhi(p, i, la) { return None; } @@ -331,3 +329,22 @@ pub fn siddhi(p: &mut Prakriya, la: Lakara, vacana: Vacana) -> Option<()> { Some(()) } + +/// Applies substitutions to the given tin suffix. +pub fn try_general_siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { + if !p.terms().last()?.has_u("Ji") { + siddhi(p, la); + } + Some(()) +} + +/// Applies substitutions to the given tin suffix. +/// +/// Due to rule 3.4.109 ("sic-abhyasta-vidibhyaH ca"), this should run after dvitva and the +/// insertion of vikaraNas. +pub fn try_siddhi_for_jhi(p: &mut Prakriya, la: Lakara) -> Option<()> { + if p.terms().last()?.has_u("Ji") { + siddhi(p, la); + } + Some(()) +} diff --git a/vidyut-prakriya/src/tripadi/pada_8_2.rs b/vidyut-prakriya/src/tripadi/pada_8_2.rs index fd13083..f0f5fb7 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_2.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_2.rs @@ -278,15 +278,17 @@ fn try_lopa_of_samyoganta_and_s(p: &mut Prakriya) -> Option<()> { } } - char_rule( - p, - |_, text, i| al::is_samyoganta(text) && i == text.len() - 1, - |p, _, i| { - set_at(p, i, ""); - p.step("8.2.23"); - true - }, - ); + if !p.terms().last().expect("ok").is_dhatu() { + char_rule( + p, + |_, text, i| al::is_samyoganta(text) && i == text.len() - 1, + |p, _, i| { + set_at(p, i, ""); + p.step("8.2.23"); + true + }, + ); + } Some(()) } @@ -302,7 +304,7 @@ fn try_ha_adesha(p: &mut Prakriya) -> Option<()> { // TODO: implement padAnta // By a vArttika, this applies only at term boundaries. - let druha_muha = &["dru\\ha~", "mu\\ha~", "zRu\\ha~", "zRi\\ha~"]; + const DRUHA_ADI: &[&str] = &["dru\\ha~", "mu\\ha~", "zRu\\ha~", "zRi\\ha~"]; for i in 0..p.terms().len() { let is_dhatu = p.has(i, |t| t.is_dhatu()); @@ -310,13 +312,14 @@ fn try_ha_adesha(p: &mut Prakriya) -> Option<()> { let maybe_j = p.find_next_where(i, |t| !t.is_empty()); let jhali_or_ante = match maybe_j { Some(j) => p.get(j)?.has_adi(&*JHAL), - None => true, + // Check that this is a pada to avoid applying these rules to yan-luk. + None => !p.get(i + 1)?.is_dhatu(), }; if jhali_or_ante { if is_dhatu { let dhatu = p.get(i)?; - if dhatu.has_u_in(druha_muha) { + if dhatu.has_u_in(DRUHA_ADI) { p.op_optional("8.2.33", |p| p.set(i, op::antya("G"))); } else if dhatu.has_u("Ra\\ha~^") { p.op_term("8.2.34", i, op::antya("D")); @@ -351,8 +354,9 @@ fn try_ch_to_s(p: &mut Prakriya) { "sf\\ja~", "mfjU~", "ya\\ja~^", - "rAj", + "rAjf~^", "BrAjf~\\", + "wuBrAjf~\\", ]; iter_terms(p, |p, i| { @@ -363,7 +367,8 @@ fn try_ch_to_s(p: &mut Prakriya) { let maybe_j = p.find_next_where(i, |t| !t.is_empty()); let jhali_ante = match maybe_j { - Some(i) => p.get(i)?.has_adi(&*JHAL), + // TODO: source of non-application with -na? (for vfkRa) + Some(i) => p.get(i)?.has_adi(&*JHAL) && !(x.has_text("vfc") && p.get(i)?.is_nistha()), None => p.terms().last()?.is_pada(), }; if !jhali_ante { @@ -403,7 +408,13 @@ fn per_term_1a(p: &mut Prakriya) -> Option<()> { if x.has_antya(&*CU) && (x.is_pada() || jhali_or_ante) { if let Some(c) = x.antya() { let sub = CU_TO_KU.get(c)?; - p.op_term("8.2.30", i, op::antya(&sub.to_string())); + p.op_term("8.2.30", i, |t| { + // TODO: what is the rule that allows this change? + if t.has_upadha('Y') { + t.set_upadha("N"); + } + t.set_antya(&sub.to_string()); + }); } } } @@ -422,7 +433,7 @@ fn per_term_1b(p: &mut Prakriya) -> Option<()> { None => true, }; - if x.has_adi(&*BASH) && x.has_antya(&*JHAZ) && if_y { + if x.has_adi(&*BASH) && x.has_antya(&*JHAZ) && x.is_ekac() && x.is_dhatu() && if_y { let sub = BASH_TO_BHAZ.get(x.adi()?)?; p.op_term("8.2.37", i, |t| { t.set_adi(&sub.to_string()); @@ -437,8 +448,8 @@ fn per_term_1b(p: &mut Prakriya) -> Option<()> { let c = p.get(i)?; let is_anta = p.find_next_where(i, |t| !t.is_empty()).is_none(); // TODO: 1.4.14 - let is_pada = p.terms().last()?.is_pada(); - let is_padanta = is_pada && is_anta; + let is_pada = p.is_pada(i); + let is_padanta = is_pada && (is_anta || p.has(i + 1, |t| t.is_taddhita())); let has_exception = c.has_antya(&*JHAL_TO_JASH_EXCEPTIONS); if c.has_antya(&*JHAL) && !has_exception && is_padanta { @@ -520,12 +531,37 @@ fn run_rules_for_nistha_t(p: &mut Prakriya) -> Option<()> { } // Exceptions that block the rules below. - if dhatu.has_text_in(&["DyA", "KyA", "pF", "mUrC", "mad"]) { + let mut blocked = false; + if dhatu.has_u_in(&["DyE\\", "KyA\\", "pF", "murCA~", "madI~"]) { // DyAta, KyAta, pUrta, mUrta, matta p.step("8.2.57"); return Some(()); + } else if dhatu.has_u_in(&["Ru\\da~^", "undI~", "trE\\N", "GrA\\", "hrI\\"]) + || (dhatu.has_u("vi\\da~\\") && dhatu.has_gana(Gana::Rudhadi)) + { + let code = "8.2.56"; + if dhatu.has_u("hrI\\") { + // By default, hrI takes -ta. So, this rule allows -na. + p.op_optional(code, op::t(i_k, op::adi("n"))); + } else { + // By default, these dhatus take -na. So, this rule allows -ta. + blocked = p.op_optional(code, |_| {}); + } + } else if dhatu.has_u("vi\\dx~^") { + // TODO: think through the rules below. They all work correctly, but most users won't + // expect to see these outputs. + // blocked = p.op_optional("8.2.58", op::nipatana("vitta")); + } else if dhatu.has_u("Bi\\di~^r") { + // blocked = p.op_optional("8.2.59", op::nipatana("Bitta")); + } else if dhatu.has_u("f\\") { + // blocked = p.op_optional("8.2.60", op::nipatana("fRa")); } + if blocked { + return None; + } + + let dhatu = p.get(i_d)?; if dhatu.has_antya('r') || dhatu.has_antya('d') && ti { p.op("8.2.42", |p| { if p.has(i_d, |t| t.has_antya('d')) { diff --git a/vidyut-prakriya/src/tripadi/pada_8_3.rs b/vidyut-prakriya/src/tripadi/pada_8_3.rs index 25def8b..ff4cd76 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_3.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_3.rs @@ -134,6 +134,7 @@ fn try_get_shatva_niyama(p: &mut Prakriya, i: usize) -> Option { let is_liti = || p.has(i + 1, |t| t.has_lakshana("li~w")); let ra_para = t.get_at(1).map(|x| x == 'r').unwrap_or(false); + // TODO: savanAdi if ra_para || t.has_u_in(&["sf\\px", "sf\\ja~", "sf\\ja~\\", "spf\\Sa~", "spfha"]) { Some("8.3.110") @@ -205,8 +206,11 @@ fn run_shatva_rules_at_index(p: &mut Prakriya, i: usize, j: usize) -> Option<()> } } } else { - // General case. - if !p.has(j, |t| t.has_tag(T::FlagKeepSa)) { + if p.has(j, |t| t.has_u("sAti~")) { + // agnisAt ... + p.step("8.3.111") + } else if !p.has(j, |t| t.has_tag(T::FlagKeepSa)) { + // General case. p.op_term("8.3.59", j, op::adi("z")); } } diff --git a/vidyut-prakriya/src/tripadi/pada_8_4.rs b/vidyut-prakriya/src/tripadi/pada_8_4.rs index 97db846..e0a31f7 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_4.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_4.rs @@ -69,7 +69,7 @@ fn try_natva_for_span(cp: &mut CharPrakriya, i_rs: usize, i_n: usize) -> Option< if (dhatu.has_u("kzuBa~") && next.has_u_in(&["SnA", "SAnac"])) || (dhatu.has_u("ska\\nBu~") && next.has_u_in(&["SnA", "Snu"])) || (dhatu.has_u("tfpa~") && next.has_u("Snu")) - || (dhatu.has_text("nft") && next.has_u("yaN")) + || (dhatu.has_u("nftI~") && next.has_u("yaN")) { cp.p.step("8.4.39"); return None; @@ -172,7 +172,8 @@ fn try_natva_for_span(cp: &mut CharPrakriya, i_rs: usize, i_n: usize) -> Option< } } } else { - // NOTE: condition is `samAnapada`, so upasargas can't cause changes with this rule. + // NOTE: condition is `samAnapada`, so: + // - upasargas can't cause changes with this rule. if !x.is_upasarga() { // TODO: track loctaion of rzfF for better rule logging. set_at(cp.p, i_n, "R"); @@ -318,6 +319,7 @@ fn try_to_anunasika(p: &mut Prakriya) -> Option<()> { // For now, apply the rule to just these sounds. if x.has_antya('d') || x.has_antya('t') { // By convention, this rule is always applied in classical Sanskrit. + p.dump(); p.op_term("8.4.45", i, |t| t.set_antya("n")); } } diff --git a/vidyut-prakriya/src/uttarapade.rs b/vidyut-prakriya/src/uttarapade.rs new file mode 100644 index 0000000..1bd3201 --- /dev/null +++ b/vidyut-prakriya/src/uttarapade.rs @@ -0,0 +1,20 @@ +//! Adhyaya 6.3 of the Ashtadhyayi concerns itself with changes caused by a following word +//! (*uttarpada*). For now, we keep those rule here. + +use crate::prakriya::Prakriya; +use crate::tag::Tag as T; + +pub fn run(p: &mut Prakriya) -> Option<()> { + let last = p.terms().last()?; + if p.terms().len() == 2 + && p.has(0, |t| !t.is_ekac() && t.ends_with("I")) + && (last.has_tag(T::Gha) || last.has_u_in(&["rUpap", "kalpap"])) + { + // TODO; check for bhASitapuMsvat + p.op_term("6.3.43", 0, |t| { + // Rule only applies for NI, so just change `I`. + t.set_antya("i"); + }); + } + Some(()) +} diff --git a/vidyut-prakriya/src/vikarana.rs b/vidyut-prakriya/src/vikarana.rs index 10c9d76..528c092 100644 --- a/vidyut-prakriya/src/vikarana.rs +++ b/vidyut-prakriya/src/vikarana.rs @@ -19,7 +19,6 @@ use crate::args::Gana::*; use crate::dhatu_gana::{DYUT_ADI, PUSH_ADI, TAN_ADI}; use crate::errors::*; -use crate::filters as f; use crate::it_samjna; use crate::operators as op; use crate::prakriya::Prakriya; @@ -104,19 +103,26 @@ fn maybe_replace_cli_with_ksa(p: &mut Prakriya, i: usize) -> Option<()> { || t.has_tag(T::xdit) }; + let mut added = false; + let dhatu = p.get(i)?; let to_ksa = replace_with(i + 1, "ksa"); + if dhatu.has_text("Sliz") && dhatu.has_gana(Divadi) { + // aSlizat, aSlikzat + added = p.op_optional("3.1.46", to_ksa); + } - // Takes priority over shala igupadha - if xyz(p, i, |x, _, z| { - pushadi_dyutadi_ldit(x) && z.has_tag(T::Parasmaipada) - }) { + let to_ksa = replace_with(i + 1, "ksa"); + if !added + && xyz(p, i, |x, _, z| { + pushadi_dyutadi_ldit(x) && z.has_tag(T::Parasmaipada) + }) + { + // Takes priority over "Sala igupaDAt ..." (3.1.45) p.op("3.1.55", |p| op::upadesha_no_it(p, i + 1, "aN")); - } else if p.has(i, shal_igupadha_anit) { + } else if !added && p.has(i, shal_igupadha_anit) { let dhatu = p.get(i)?; if dhatu.has_text("dfS") { p.step("3.1.47") - } else if dhatu.has_text("Sliz") && dhatu.has_gana(Divadi) { - p.op_optional("3.1.46", to_ksa); } else if dhatu.has_tag(T::Udit) { p.op_optional("3.1.45", |p| { to_ksa(p); @@ -266,16 +272,6 @@ fn add_lun_vikarana(p: &mut Prakriya) { maybe_replace_cli_with_sic(p, i); } -fn add_kr_after_am_pratyaya(p: &mut Prakriya) { - let mut kf = Term::make_dhatu("qukf\\Y", Tanadi, None); - kf.set_text("kf"); - kf.add_tag(T::Dhatu); - - let i_tin = p.terms().len() - 1; - p.insert_before(i_tin, kf); - p.step("3.1.40") -} - /// Adds one of `kf`, `BU`, or `as` after the `Am` pratyaya. /// /// Examples: @@ -288,21 +284,33 @@ fn add_kr_bhu_or_as_after_am_pratyaya(p: &mut Prakriya) { // Run exactly one of the following blocks: let mut ran = false; if !ran { - // corayAmbaBUva, corayAmbaBUve, ... + // corayAmbaBUva, ... ran = p.op_optional("3.1.40:BU", |p| { let mut dhatu = Term::make_dhatu("BU", Bhvadi, None); dhatu.set_text("BU"); dhatu.add_tag(T::Dhatu); + dhatu.maybe_save_sthanivat(); p.insert_before(i_tin, dhatu); + + if !p.is_bhave_or_karmani() { + p.remove_tag(T::Atmanepada); + p.add_tag(T::Parasmaipada); + } }); } if !ran { - // corayAmAsa, corayAmAhe, ... + // corayAmAsa, ... ran = p.op_optional("3.1.40:as", |p| { let mut dhatu = Term::make_dhatu("asa~", Adadi, None); dhatu.set_text("as"); dhatu.add_tag(T::Dhatu); + dhatu.maybe_save_sthanivat(); p.insert_before(i_tin, dhatu); + + if !p.is_bhave_or_karmani() { + p.remove_tag(T::Atmanepada); + p.add_tag(T::Parasmaipada); + } }); } if !ran { @@ -311,23 +319,30 @@ fn add_kr_bhu_or_as_after_am_pratyaya(p: &mut Prakriya) { let mut dhatu = Term::make_dhatu("qukf\\Y", Tanadi, None); dhatu.set_text("kf"); dhatu.add_tag(T::Dhatu); + dhatu.maybe_save_sthanivat(); p.insert_before(i_tin, dhatu); }); } } -fn maybe_add_am_pratyaya_for_lit(p: &mut Prakriya) -> Option<()> { +/// If applicable, add Am-pratyaya and the corresponding dhatu. +pub fn try_add_am_pratyaya_for_lit(p: &mut Prakriya) -> Option<()> { + let tin = p.terms().last()?; + if !(tin.has_u("li~w") || tin.has_lakshana("li~w")) { + return None; + } + let i = p.find_last(T::Dhatu)?; let dhatu = p.get(i)?; if dhatu.has_text("kAs") || dhatu.is_pratyaya() { // kAsAYcakre; corayAYcakre p.op("3.1.35", add_aam); - } else if !f::is_eka_ac(dhatu) && !dhatu.has_text_in(&["jAgf", "UrRu"]) { + } else if !dhatu.is_ekac() && !dhatu.has_text_in(&["jAgf", "UrRu"]) { // jAgf is handled separately below. p.op("3.1.35.v1", add_aam); } else if dhatu.has_adi(&*IC) && dhatu.is_guru() && !dhatu.has_u("fCa~") { - // IkSAYcakre + // IkzAYcakre p.op("3.1.36", add_aam); } else if dhatu.has_text_in(&["day", "ay", "As"]) { // dayAYcakre @@ -379,7 +394,14 @@ fn maybe_add_am_pratyaya_for_lot(p: &mut Prakriya) { if added_am { // Derive by nipAtana p.set(i, |t| t.add_tag(T::FlagGunaApavada)); - add_kr_after_am_pratyaya(p); + + let mut kf = Term::make_dhatu("qukf\\Y", Tanadi, None); + kf.set_text("kf"); + kf.add_tag(T::Dhatu); + + let i_tin = p.terms().len() - 1; + p.insert_before(i_tin, kf); + p.step("3.1.40") } } } @@ -387,7 +409,7 @@ fn maybe_add_am_pratyaya_for_lot(p: &mut Prakriya) { fn add_sarvadhatuka_vikarana(p: &mut Prakriya) -> Option<()> { let i = p.find_last(T::Dhatu)?; - if !p.has_tag(T::Kartari) { + if p.has_tag_in(&[T::Bhave, T::Karmani]) { p.op("3.1.67", add_vikarana("yak")); return Some(()); } @@ -576,7 +598,7 @@ pub fn run(p: &mut Prakriya) -> Result<()> { } else if tin.has_lakshana("lu~N") { add_lun_vikarana(p); } else if tin.has_lakshana("li~w") { - maybe_add_am_pratyaya_for_lit(p); + // See `try_add_am_pratyaya_for_lit`. } else if tin.has_tag(T::Sarvadhatuka) { if tin.has_lakshana("lo~w") { // Just for vidāṅkurvantu, etc. diff --git a/vidyut-prakriya/test_utils/src/lib.rs b/vidyut-prakriya/test_utils/src/lib.rs index 608f6dc..f83325c 100644 --- a/vidyut-prakriya/test_utils/src/lib.rs +++ b/vidyut-prakriya/test_utils/src/lib.rs @@ -1,16 +1,26 @@ +/*! +Various test utils. + +vidyut-prakriya has thousands of assert statements. This module contains various functions to +manage the boilerplate required for these assertions. +*/ extern crate vidyut_prakriya; +use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; use vidyut_prakriya::Ashtadhyayi; use vidyut_prakriya::Prakriya; +/// 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| !(p.text().ends_with('d') || p.text().ends_with('q'))) + .filter(|p| { + !(p.text().ends_with('d') || p.text().ends_with('q') || p.text().ends_with('g')) + }) .collect() } @@ -34,12 +44,13 @@ pub fn derive_taddhitantas(p: &Pratipadika, t: Taddhita) -> Vec { sanitize_results(results) } +/// Derives the prathama-eka forms of the given lakara. pub fn derive_lakara(prefixes: &[&str], dhatu: &Dhatu, lakara: Lakara) -> Vec { let dhatu = dhatu.clone().with_prefixes(prefixes); let args = TinantaArgs::builder() .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) + .vacana(Eka) .lakara(lakara) .build() .unwrap(); @@ -47,12 +58,13 @@ pub fn derive_lakara(prefixes: &[&str], dhatu: &Dhatu, lakara: Lakara) -> Vec Vec { let dhatu = dhatu.clone().with_prefixes(prefixes); let args = TinantaArgs::builder() .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) + .vacana(Eka) .lakara(lakara) .pada(Pada::Parasmai) .build() @@ -60,12 +72,13 @@ pub fn derive_parasmai(prefixes: &[&str], dhatu: &Dhatu, lakara: Lakara) -> Vec< derive_tinantas(&dhatu, &args) } +/// Derives the Atmanepada-prathama-eka forms of the given lakara. pub fn derive_atmane(prefixes: &[&str], dhatu: &Dhatu, lakara: Lakara) -> Vec { let dhatu = dhatu.clone().with_prefixes(prefixes); let args = TinantaArgs::builder() .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) + .vacana(Eka) .lakara(lakara) .pada(Pada::Atmane) .build() @@ -73,12 +86,13 @@ pub fn derive_atmane(prefixes: &[&str], dhatu: &Dhatu, lakara: Lakara) -> Vec Vec { let dhatu = dhatu.clone().with_prefixes(prefixes); let args = TinantaArgs::builder() .prayoga(Prayoga::Karmani) .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) + .vacana(Eka) .lakara(lakara) .build() .unwrap(); @@ -95,7 +109,7 @@ fn print_all_prakriyas(prakriyas: &[Prakriya]) { } } -pub fn stri(text: &str) -> Pratipadika { +pub fn nyap(text: &str) -> Pratipadika { Pratipadika::builder() .text(text) .is_nyap(true) @@ -103,6 +117,9 @@ pub fn stri(text: &str) -> Pratipadika { .unwrap() } +/// Asserts that the given `prakriyas` produce the `expected` results. +/// +/// If there is any difference, this function will nicely print out each prakriya in `prakriyas`. pub fn assert_padas(prakriyas: Vec, expected: &[&str]) { let actuals: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); @@ -133,7 +150,8 @@ pub fn assert_padas(prakriyas: Vec, expected: &[&str]) { } } -/// Checks the given lakara/purusha/vacana +/// 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, @@ -380,11 +398,88 @@ pub fn assert_has_lrn_p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { assert_padas(actual, expected); } +pub fn assert_has_lrn_a(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { + let actual = derive_atmane(prefixes, dhatu, Lakara::Lrn); + assert_padas(actual, expected); +} + pub fn assert_has_lrn_karmani(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { let actual = derive_karmani(prefixes, dhatu, Lakara::Lrn); assert_padas(actual, expected); } +pub fn assert_has_tip(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Prathama, Eka, expected); +} + +pub fn assert_has_tas(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Prathama, Dvi, expected); +} + +pub fn assert_has_jhi(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Prathama, Bahu, expected); +} + +pub fn assert_has_sip(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Madhyama, Eka, expected); +} + +pub fn assert_has_thas(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Madhyama, Dvi, expected); +} + +pub fn assert_has_tha(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Madhyama, Bahu, expected); +} + +pub fn assert_has_mip(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Uttama, Eka, expected); +} + +pub fn assert_has_vas(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Uttama, Dvi, expected); +} + +pub fn assert_has_mas(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_parasmai_tinanta(prefixes, dhatu, la, Purusha::Uttama, Bahu, expected); +} + +pub fn assert_has_ta(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Prathama, Eka, expected); +} + +pub fn assert_has_aataam(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Prathama, Dvi, expected); +} + +pub fn assert_has_jha(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Prathama, Bahu, expected); +} + +pub fn assert_has_thaas(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Madhyama, Eka, expected); +} + +pub fn assert_has_aathaam(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Madhyama, Dvi, expected); +} + +pub fn assert_has_dhvam(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Madhyama, Bahu, expected); +} + +pub fn assert_has_iw(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Uttama, Eka, expected); +} + +pub fn assert_has_vahi(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Uttama, Dvi, expected); +} + +pub fn assert_has_mahin(prefixes: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(prefixes, dhatu, la, Purusha::Uttama, Bahu, expected); +} + pub fn assert_has_krdanta(prefixes: &[&str], dhatu: &Dhatu, krt: Krt, expected: &[&str]) { assert_padas( derive_krdantas(&dhatu.clone().with_prefixes(prefixes), krt), @@ -422,12 +517,25 @@ pub fn assert_has_subantas_p( } pub fn assert_has_subantas( - text: &str, + pratipadika_text: &str, linga: Linga, vibhakti: Vibhakti, vacana: Vacana, expected: &[&str], ) { - let pratipadika = Pratipadika::new(text); + let pratipadika = Pratipadika::new(pratipadika_text); assert_has_subantas_p(&pratipadika, linga, vibhakti, vacana, expected); } + +/// 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) +} + +// Shorthand for building a pratipadika. +pub fn prati(text: &str) -> Pratipadika { + Pratipadika::builder().text(text).build().unwrap() +} diff --git a/vidyut-prakriya/tests/basic_krdantas.rs b/vidyut-prakriya/tests/basic_krdantas.rs index aecb50a..9d83d74 100644 --- a/vidyut-prakriya/tests/basic_krdantas.rs +++ b/vidyut-prakriya/tests/basic_krdantas.rs @@ -10,9 +10,9 @@ use vidyut_prakriya::args::*; use vidyut_prakriya::Ashtadhyayi; /// Creates a krdanta with the given args. -fn create_krdanta(dhatu: &str, gana: u8, krt: Krt) -> Vec { +fn create_krdanta(dhatu: &str, gana: &str, krt: Krt) -> Vec { let a = Ashtadhyayi::new(); - let dhatu = Dhatu::new(dhatu, Gana::from_int(gana).unwrap()); + let dhatu = Dhatu::new(dhatu, gana.parse().expect("ok")); let args = KrdantaArgs::builder().krt(krt).build().unwrap(); let prakriyas = a.derive_krdantas(&dhatu, &args); @@ -27,7 +27,7 @@ fn test_krdanta(cases: &Vec<(&'static str, u8, &'static str)>, krt: Krt) { expected.sort(); expected.dedup(); - let mut actual = create_krdanta(dhatu, *gana, krt); + let mut actual = create_krdanta(dhatu, &gana.to_string(), krt); actual.sort(); actual.dedup(); diff --git a/vidyut-prakriya/tests/basic_tinantas.rs b/vidyut-prakriya/tests/basic_tinantas.rs index d5c5aba..497b5b7 100644 --- a/vidyut-prakriya/tests/basic_tinantas.rs +++ b/vidyut-prakriya/tests/basic_tinantas.rs @@ -2,12 +2,11 @@ use vidyut_prakriya::args::*; use vidyut_prakriya::dhatupatha; use vidyut_prakriya::Ashtadhyayi; -fn derive(upadesha: &str, gana: u8, prayoga: Prayoga) -> Vec { - let gana = Gana::from_int(gana).expect("valid"); +fn derive(upadesha: &str, gana: &str, prayoga: Prayoga) -> Vec { let a = Ashtadhyayi::new(); let dhatu = Dhatu::builder() .upadesha(upadesha) - .gana(gana) + .gana(gana.parse().expect("ok")) .build() .unwrap(); @@ -34,7 +33,7 @@ fn run_test_cases(cases: &[(&str, u8, &str)], prayoga: Prayoga) { let mut expected: Vec<_> = expected.split('|').collect(); expected.sort(); - let mut actual: Vec<_> = derive(dhatu, *gana, prayoga); + let mut actual: Vec<_> = derive(dhatu, &gana.to_string(), prayoga); actual.sort(); actual.dedup(); diff --git a/vidyut-prakriya/tests/pada_1_1.rs b/vidyut-prakriya/tests/pada_1_1.rs index 2785c35..4c6e077 100644 --- a/vidyut-prakriya/tests/pada_1_1.rs +++ b/vidyut-prakriya/tests/pada_1_1.rs @@ -9,10 +9,6 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } @@ -25,10 +21,6 @@ fn yan(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Yan]) } -fn prati(text: &str) -> Pratipadika { - Pratipadika::new(text) -} - fn stri(text: &str) -> Pratipadika { Pratipadika::builder() .text(text) @@ -40,7 +32,12 @@ fn stri(text: &str) -> Pratipadika { #[test] fn sutra_1_1_1() { // TODO: others + 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"]); } #[test] @@ -49,15 +46,8 @@ fn sutra_1_1_2() { assert_has_krdanta(&[], &d("tF", Bhvadi), Krt::tfc, &["taritf", "tarItf"]); assert_has_krdanta(&[], &d("ci\\Y", Svadi), Krt::tfc, &["cetf"]); assert_has_krdanta(&[], &d("zwu\\Y", Adadi), Krt::tfc, &["stotf"]); - assert_has_parasmai_tinanta(&[], &pac, Lat, P::Prathama, Bahu, &["pacanti"]); - assert_has_tinanta( - &[], - &d("ji\\", Bhvadi), - Lat, - P::Prathama, - Bahu, - &["jayanti"], - ); + assert_has_jhi(&[], &pac, Lat, &["pacanti"]); + assert_has_jhi(&[], &d("ji\\", Bhvadi), Lat, &["jayanti"]); assert_has_atmane_tinanta(&[], &pac, Lat, P::Uttama, Eka, &["pace"]); } @@ -77,21 +67,41 @@ fn sutra_1_1_3() { // Other examples assert_has_lat_p(&[], &d("YimidA~", Divadi), &["medyati"]); - assert_has_parasmai_tinanta( - &[], - &d("YiBI\\", Juhotyadi), - Lan, - P::Prathama, - Bahu, - &["abiBayuH"], - ); + assert_has_jhi(&[], &d("YiBI\\", Juhotyadi), Lan, &["abiBayuH"]); // ikaH assert_has_krdanta(&[], &d("yA\\", Adadi), Krt::lyuw, &["yAna"]); assert_has_lat_p(&[], &d("glE\\", Bhvadi), &["glAyati"]); assert_has_krdanta(&[], &d("unBa~", Tudadi), Krt::tfc, &["umBitf"]); - // TODO: others + // punargrahaNam of the terms "guna" and "vrddhi" + assert_has_subantas("div", Stri, Prathama, Eka, &["dyOH"]); + assert_has_subantas("paTin", Pum, Prathama, Eka, &["panTAH"]); + assert_has_subantas("tad", Pum, Prathama, Eka, &["saH"]); + assert_has_subantas("idam", Pum, Dvitiya, Eka, &["imam"]); +} + +#[test] +fn sutra_1_1_4() { + let lu = d("lUY", Kryadi); + assert_has_krdanta(&[], &yan(&lu), Krt::ac, &["loluva"]); + assert_has_krdanta(&[], &yan(&d("pUY", Kryadi)), Krt::ac, &["popuva"]); + assert_has_krdanta(&[], &yan(&d("mfjU~", Adadi)), Krt::ac, &["marImfja"]); + + // dhAtu? + assert_has_krdanta(&[], &lu, Krt::tfc, &["lavitf"]); + assert_has_krdanta(&[], &d("riza~", Bhvadi), Krt::vic, &["rez"]); + assert_has_sip(&[], &d("RI\\Y", Bhvadi), VidhiLin, &["nayeH"]); + + // TODO: ArdhadhAtuke? + + // ikaH + assert_has_lun_karmani(&[], &d("Ba\\njo~", Rudhadi), &["aBAji", "aBaYji"]); + assert_has_krdanta(&[], &d("ra\\nja~^", Divadi), Krt::GaY, &["rAga", "raNga"]); + + // bahuvrIhi? + assert_has_lat_p(&[], &nic(&d("knUyI~\\", Bhvadi)), &["knopayati"]); + // TODO: preddha } #[test] @@ -114,7 +124,7 @@ fn sutra_1_1_5() { // Niti assert_has_parasmai_tinanta(&[], &ci, Lat, P::Prathama, Dvi, &["cinutaH"]); - assert_has_parasmai_tinanta(&[], &ci, Lat, P::Prathama, Bahu, &["cinvanti"]); + assert_has_jhi(&[], &ci, Lat, &["cinvanti"]); assert_has_tinanta(&[], &mfj, Lat, P::Prathama, Dvi, &["mfzwaH"]); assert_has_tinanta(&[], &mfj, Lat, P::Prathama, Bahu, &["mfjanti"]); @@ -163,6 +173,55 @@ fn sutra_1_1_20() { assert_has_krdanta(&["ava"], &d("dE\\p", Bhvadi), Krt::kta, &["avadAta"]); } +#[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"]); +} + +#[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"]); + // 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"]); + // TODO: assert_has_taddhitanta(&gana, T::Sas, &["gaRaSas"]); + + // TODO: + // let taavat = prati("tAvat"); + // assert_has_taddhitanta(&taavat, T::kftvasuc, &["tAvatkftvas"]); + // assert_has_taddhitanta(&taavat, T::DA, &["tAvadDA"]); + // assert_has_taddhitanta(&taavat, T::kan, &["tAvatka"]); + // assert_has_taddhitanta(&taavat, T::Sas, &["tAvacCas"]); + + // let kati = prati("kati"); + // assert_has_taddhitanta(&kati, T::kftvasuc, &["katikftvas"]); + // assert_has_taddhitanta(&kati, T::DA, &["katiDA"]); + // assert_has_taddhitanta(&kati, T::kan, &["katika"]); + // assert_has_taddhitanta(&kati, T::Sas, &["katizas"]); +} + +#[test] +fn sutra_1_1_24() { + assert_has_subantas("zaz", Napumsaka, Prathama, Bahu, &["zaw"]); + assert_has_subantas("paYcan", Napumsaka, Prathama, Bahu, &["paYca"]); + assert_has_subantas("saptan", Napumsaka, Prathama, Bahu, &["sapta"]); + assert_has_subantas("navan", Napumsaka, Prathama, Bahu, &["nava"]); + assert_has_subantas("daSan", Napumsaka, Prathama, Bahu, &["daSa"]); + // others + assert_has_subantas("Sata", Napumsaka, Prathama, Bahu, &["SatAni"]); + assert_has_subantas("sahasra", Napumsaka, Prathama, Bahu, &["sahasrARi"]); +} + #[test] fn sutra_1_1_26() { let kf = d("qukf\\Y", Tanadi); @@ -234,6 +293,16 @@ fn sutra_1_1_34() { assert_has_subantas("aDara", Pum, Prathama, Bahu, &["aDare", "aDarAH"]); } +#[test] +fn sutra_1_1_40() { + assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::ktvA, &["kftvA"]); + assert_has_krdanta(&[], &d("hf\\Y", Bhvadi), Krt::ktvA, &["hftvA"]); + // TODO: tosun + // kasun + assert_has_krdanta(&["vi"], &d("sf\\px~", Tudadi), Krt::kasun, &["visfpas"]); + assert_has_krdanta(&["AN"], &d("u~tfdi~^r", Rudhadi), Krt::kasun, &["Atfdas"]); +} + #[test] fn sutra_1_1_42() { assert_has_subantas("kuRqa", Napumsaka, Prathama, Bahu, &["kuRqAni"]); @@ -258,6 +327,55 @@ fn sutra_1_1_43() { assert_has_subantas("veman", Napumsaka, Prathama, Dvi, &["vemanI", "vemnI"]); } +#[test] +fn sutra_1_1_45() { + let yaj = d("ya\\ja~^", Bhvadi); + assert_has_krdanta(&[], &yaj, Krt::kta, &["izwa"]); + let vap = d("quva\\pa~^", Bhvadi); + assert_has_krdanta(&[], &vap, Krt::kta, &["upta"]); + let grah = d("graha~^", Kryadi); + assert_has_krdanta(&[], &grah, Krt::kta, &["gfhIta"]); +} + +#[test] +fn sutra_1_1_46() { + let lu = d("lUY", Kryadi); + assert_has_krdanta(&[], &lu, Krt::tfc, &["lavitf"]); + + assert_has_lat( + &[], + &nic(&d("YiBI\\", Juhotyadi)), + &["BAyayati", "BAyayate", "BIzayate", "BApayate"], + ); +} + +#[test] +fn sutra_1_1_47() { + assert_has_lat_p(&["vi"], &d("ru\\Di~^r", Rudhadi), &["viruRadDi"]); + assert_has_lat_p(&[], &d("mu\\cx~^", Tudadi), &["muYcati"]); + assert_has_subantas("payas", Napumsaka, Prathama, Bahu, &["payAMsi"]); +} + +#[test] +fn sutra_1_1_47_v1() { + let masj = d("wuma\\sjo~", Tudadi); + assert_has_krdanta(&[], &masj, Krt::kta, &["magna"]); + assert_has_krdanta(&[], &masj, Krt::ktavatu, &["magnavat"]); + assert_has_krdanta(&[], &masj, Krt::tfc, &["maNktf"]); + assert_has_krdanta(&[], &masj, Krt::tumun, &["maNktum"]); +} + +#[test] +fn sutra_1_1_48() { + use Vibhakti::*; + assert_has_subantas("atirE", Napumsaka, Prathama, Eka, &["atiri"]); + assert_has_subantas("atinO", Napumsaka, Prathama, Eka, &["atinu"]); + assert_has_subantas("upago", Napumsaka, Prathama, Eka, &["upagu"]); + // ecaH? + // TODO: assert_has_subantas("atiKawvA", Pum, Prathama, Eka, &["atiKawvaH"]); + // TODO: assert_has_subantas("atimAlA", Pum, Prathama, Eka, &["atimAlaH"]); +} + #[test] fn sutra_1_1_51() { assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::tfc, &["kartf"]); @@ -272,6 +390,18 @@ fn sutra_1_1_51() { assert_has_krdanta(&[], &d("gE\\", Bhvadi), Krt::yat, &["geya"]); } +#[test] +fn sutra_1_1_55() { + let asa = d("asa~", Adadi); + // aneka-al + assert_has_krdanta(&[], &asa, Krt::tfc, &["Bavitf"]); + assert_has_krdanta(&[], &asa, Krt::tumun, &["Bavitum"]); + assert_has_krdanta(&[], &asa, Krt::tavya, &["Bavitavya"]); + // Sit + assert_has_subantas("kuRqa", Napumsaka, Prathama, Bahu, &["kuRqAni"]); + assert_has_subantas("kuRqa", Napumsaka, Dvitiya, Bahu, &["kuRqAni"]); +} + #[test] fn sutra_1_1_56() { assert_has_krdanta(&[], &d("asa~", Adadi), Krt::tfc, &["Bavitf"]); @@ -355,6 +485,13 @@ fn sutra_1_1_59() { assert_has_lat(&[], &yan(&d("DmA\\", Bhvadi)), &["deDmIyate"]); } +#[test] +fn sutra_1_1_61() { + assert_has_lat_p(&[], &d("a\\da~", Adadi), &["atti"]); + assert_has_lat_p(&[], &d("hu\\", Juhotyadi), &["juhoti"]); + // TODO: lup +} + #[test] fn sutra_1_1_73() { assert_has_taddhitanta(&stri("SAlA"), T::Ca, &["SAlIya"]); diff --git a/vidyut-prakriya/tests/pada_1_2.rs b/vidyut-prakriya/tests/pada_1_2.rs index 73be128..cae3354 100644 --- a/vidyut-prakriya/tests/pada_1_2.rs +++ b/vidyut-prakriya/tests/pada_1_2.rs @@ -8,10 +8,6 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } @@ -340,6 +336,19 @@ fn sutra_1_2_15() { ); } +#[test] +fn sutra_1_2_16() { + let yam = d("ya\\ma~", Bhvadi); + assert_has_atmane_tinanta( + &["upa", "AN"], + &yam, + Lun, + Prathama, + Eka, + &["upAyata", "upAyaMsta"], + ); +} + #[test] fn sutra_1_2_17() { let stha = d("zWA\\", Bhvadi); @@ -374,6 +383,29 @@ fn sutra_1_2_18() { assert_has_krdanta(&["ni"], &d("kuca~", Tudadi), Krt::kta, &["nikucita"]); } +#[ignore] +#[test] +fn sutra_1_2_19() { + let shi = d("SIN", Adadi); + assert_has_krdanta(&[], &shi, Krt::kta, &["Sayita"]); + assert_has_krdanta(&[], &shi, Krt::ktavatu, &["Sayitavat"]); + let svid = d("zvi\\dA~", Divadi); + assert_has_krdanta(&["pra"], &svid, Krt::kta, &["prasvedita"]); + assert_has_krdanta(&["pra"], &svid, Krt::ktavatu, &["prasveditavat"]); + let mid = d("YimidA~\\", Bhvadi); + assert_has_krdanta(&["pra"], &mid, Krt::kta, &["pramedita"]); + assert_has_krdanta(&["pra"], &mid, Krt::ktavatu, &["prameditavat"]); + let kshved = d("YikzvidA~", Bhvadi); + assert_has_krdanta(&["pra"], &kshved, Krt::kta, &["prakzvedita"]); + assert_has_krdanta(&["pra"], &kshved, Krt::ktavatu, &["prakzveditavat"]); + let dharsh = d("YiDfzA~", Svadi); + assert_has_krdanta(&["pra"], &dharsh, Krt::kta, &["praDarzita"]); + assert_has_krdanta(&["pra"], &dharsh, Krt::ktavatu, &["praDarzitavat"]); + // set + assert_has_krdanta(&[], &svid, Krt::kta, &["svinna"]); + assert_has_krdanta(&[], &svid, Krt::ktavatu, &["svinnavat"]); +} + #[test] fn sutra_1_2_20() { let mfz = d("mfza~^", Divadi); @@ -427,6 +459,28 @@ fn sutra_1_2_23() { ); } +#[test] +fn sutra_1_2_24() { + assert_has_krdanta( + &[], + &d("vancu~", Bhvadi), + Krt::ktvA, + &["vacitvA", "vaYcitvA", "vaktvA"], + ); + assert_has_krdanta( + &[], + &d("lunca~", Bhvadi), + Krt::ktvA, + &["lucitvA", "luYcitvA"], + ); + assert_has_krdanta( + &[], + &d("fti", Bhvadi), + Krt::ktvA, + &["ftitvA", "artitvA", "ftIyitvA"], + ); +} + #[test] fn sutra_1_2_25() { assert_has_krdanta( @@ -464,7 +518,7 @@ fn sutra_1_2_26() { // vyupaDAt let vft = d("vftu~\\", Bhvadi); assert_has_krdanta(&[], &vft, Krt::ktvA, &["vartitvA", "vfttvA"]); - assert_has_lat(&[], &san(&vft), &["vivartizate"]); + assert_has_lat(&[], &san(&vft), &["vivftsati", "vivartizate"]); // halAdeH let iz = d("izu~", Tudadi); assert_has_krdanta(&[], &iz, Krt::ktvA, &["ezitvA", "izwvA"]); @@ -475,6 +529,24 @@ fn sutra_1_2_26() { assert_has_lat_a(&[], &san(&bhuj), &["buBukzate"]); } +#[test] +fn sutra_1_2_41() { + assert_has_krdanta(&[], &d("spf\\Sa~", Tudadi), Krt::kvin, &["spfS"]); + assert_has_krdanta(&[], &d("Ba\\ja~^", Bhvadi), Krt::Rvi, &["BAj"]); +} + +#[test] +fn sutra_1_2_45() { + use Vibhakti::*; + assert_has_subantas("qitTa", Pum, Prathama, Eka, &["qitTaH"]); + assert_has_subantas("kapitTa", Pum, Prathama, Eka, &["kapitTaH"]); + assert_has_subantas("kuRqa", Napumsaka, Prathama, Eka, &["kuRqam"]); + assert_has_subantas("pIWa", Napumsaka, Prathama, Eka, &["pIWam"]); + // a-dhAtu? + assert_has_lan(&[], &d("ha\\na~", Adadi), &["ahan"]); + // TODO: others +} + #[test] fn sutra_1_2_47() { use Vibhakti::*; diff --git a/vidyut-prakriya/tests/pada_1_3.rs b/vidyut-prakriya/tests/pada_1_3.rs index 5028a29..4ada160 100644 --- a/vidyut-prakriya/tests/pada_1_3.rs +++ b/vidyut-prakriya/tests/pada_1_3.rs @@ -1,10 +1,15 @@ extern crate test_utils; use test_utils::*; 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::Vacana::*; +use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) +fn nic(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Nic]) } fn san(dhatu: &Dhatu) -> Dhatu { @@ -12,12 +17,111 @@ fn san(dhatu: &Dhatu) -> Dhatu { } #[test] -fn sutra_1_3_1() { +fn sutra_1_3_1_and_sutra_1_3_2() { assert_has_lat(&[], &d("BU", Bhvadi), &["Bavati"]); assert_has_lat(&[], &d("eDa~\\", Bhvadi), &["eDate"]); assert_has_lat(&[], &d("sparDa~\\", Bhvadi), &["sparDate"]); } +#[test] +fn sutra_1_3_3() { + assert_has_krdanta(&[], &d("ci\\Y", Svadi), Krt::kvip, &["cit"]); + assert_has_krdanta(&[], &d("zu\\Y", Svadi), Krt::kvip, &["sut"]); +} + +#[test] +fn sutra_1_3_4() { + // t + assert_has_subantas("vfkza", Pum, V::Panchami, Eka, &["vfkzAt"]); + assert_has_subantas("plakza", Pum, V::Panchami, Eka, &["plakzAt"]); + // s + let pac = &d("qupa\\ca~^z", Bhvadi); + assert_has_subantas("brAhmaRa", Pum, V::Prathama, Bahu, &["brAhmaRAH"]); + assert_has_tas(&[], &pac, Lat, &["pacataH"]); + assert_has_thas(&[], &pac, Lat, &["pacaTaH"]); + // m + assert_has_tas(&[], &pac, Lan, &["apacatAm"]); + assert_has_thas(&[], &pac, Lan, &["apacatam"]); +} + +#[test] +fn sutra_1_3_5() { + // Yi + assert_has_krdanta(&[], &d("YimidA~\\", Bhvadi), Krt::kta, &["minna"]); + assert_has_krdanta(&[], &d("YiDfzA~", Svadi), Krt::kta, &["Dfzwa"]); + assert_has_krdanta(&[], &d("YikzvidA~", Divadi), Krt::kta, &["kzviRRa"]); + assert_has_krdanta(&[], &d("YiinDI~\\", Rudhadi), Krt::kta, &["idDa"]); + // wu + assert_has_krdanta(&[], &d("wuvepf~\\", Bhvadi), Krt::aTuc, &["vepaTu"]); + assert_has_krdanta(&[], &d("wuo~Svi", Bhvadi), Krt::aTuc, &["SvayaTu"]); + // qu + assert_has_krdanta(&[], &d("qupa\\ca~^z", Bhvadi), Krt::ktri, &["paktrima"]); + assert_has_krdanta(&[], &d("quva\\pa~^", Bhvadi), Krt::ktri, &["uptrima"]); + assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::ktri, &["kftrima"]); + // TODO: Adi? +} + +#[test] +fn sutra_1_3_6() { + // TODO: change examples to nartakI, etc. + assert_has_krdanta(&[], &d("nftI~", Divadi), Krt::zvun, &["nartaka"]); + assert_has_krdanta(&[], &d("ra\\nja~^", Bhvadi), Krt::zvun, &["rajaka"]); + // pratyayasya? + assert_has_subantas("zoqa", Pum, V::Prathama, Eka, &["zoqaH"]); + assert_has_subantas("zaRqa", Pum, V::Prathama, Eka, &["zaRqaH"]); + assert_has_subantas("zaqika", Pum, V::Prathama, Eka, &["zaqikaH"]); + // AdiH + assert_has_krdanta(&[], &d("ava~", Bhvadi), Krt::wizac, &["aviza"]); + // TODO: right mah? + assert_has_krdanta(&[], &d("maha~", Bhvadi), Krt::wizac, &["mahiza"]); +} + +#[test] +fn sutra_1_3_7() { + // ca + assert_has_taddhitanta(&prati("kuYja"), T::cPaY, &["kOYjAyana"]); + // ja + assert_has_subantas("brAhmaRa", Pum, V::Prathama, Bahu, &["brAhmaRAH"]); + // Ya + assert_has_taddhitanta(&prati("SaRqika"), T::Yya, &["SARqikya"]); + // wa + assert_has_krdanta(&[], &d("cara~", Bhvadi), Krt::wa, &["cara"]); + // qa + assert_has_krdanta(&[], &d("janI~\\", Divadi), Krt::qa, &["ja"]); + // Ignore Ca, Ja, Wa, Qa, + // TODO: others +} + +#[test] +fn sutra_1_3_8() { + // la + assert_has_krdanta(&[], &d("ci\\Y", Svadi), Krt::lyuw, &["cayana"]); + assert_has_krdanta(&[], &d("ji\\", Bhvadi), Krt::lyuw, &["jayana"]); + // Sa + assert_has_lat_p(&[], &d("BU", Bhvadi), &["Bavati"]); + assert_has_lat_p(&[], &d("qupa\\ca~^z", Bhvadi), &["pacati"]); + // ka + let bhuj = d("Bu\\ja~", Rudhadi); + assert_has_krdanta(&[], &bhuj, Krt::kta, &["Bukta"]); + assert_has_krdanta(&[], &bhuj, Krt::ktavatu, &["Buktavat"]); + // Ka + assert_has_krdanta(&[], &d("vada~", Bhvadi), Krt::Kac, &["vada"]); + // ga + assert_has_krdanta(&[], &d("glE\\", Bhvadi), Krt::ksnu, &["glAsnu"]); + assert_has_krdanta(&[], &d("ji\\", Bhvadi), Krt::ksnu, &["jizRu"]); + assert_has_krdanta(&[], &d("BU", Bhvadi), Krt::ksnu, &["BUzRu"]); + // Ga + assert_has_krdanta(&[], &d("Ba\\njo~", Rudhadi), Krt::Gurac, &["BaNgura"]); + // Na (Nasi --> At, Nas --> sya) + assert_has_subantas("vfkza", Pum, V::Panchami, Eka, &["vfkzAt"]); + assert_has_subantas("vfkza", Pum, V::Sasthi, Eka, &["vfkzasya"]); + // ataddhite? + assert_has_taddhitanta(&prati("cUqA"), T::lac, &["cUqAla"]); + assert_has_taddhitanta(&prati("loman"), T::Sa, &["lomaSa"]); + // TODO: support kan-pratyaya here + // assert_has_taddhitanta(&prati("vfkza"), T::kan, &["vfkzaka"]); +} + #[test] fn sutra_1_3_12() { // anudAttet @@ -106,20 +210,20 @@ fn sutra_1_3_24() { } #[test] -fn sutra_1_3_25() { +fn sutra_1_3_25_and_sutra_1_3_26() { let stha = d("zWA\\", Bhvadi); assert_has_lat(&["upa"], &stha, &["upatizWati", "upatizWate"]); } #[test] -fn sutra_1_3_26() { +fn sutra_1_3_27() { let tap = d("ta\\pa~", Bhvadi); assert_has_lat(&["ud"], &tap, &["uttapati", "uttapate"]); assert_has_lat(&["vi"], &tap, &["vitapati", "vitapate"]); } #[test] -fn sutra_1_3_27() { +fn sutra_1_3_28() { let yam = d("ya\\ma~", Bhvadi); let han = d("ha\\na~", Adadi); assert_has_lat(&["AN"], &yam, &["AyacCati", "AyacCate"]); @@ -127,7 +231,7 @@ fn sutra_1_3_27() { } #[test] -fn sutra_1_3_28() { +fn sutra_1_3_29() { let d = d; assert_has_lat( &["sam"], @@ -160,11 +264,17 @@ fn sutra_1_3_28_v1() { #[test] fn sutra_1_3_30() { - let han = d("hve\\Y", Bhvadi); - assert_has_lat(&["ni"], &han, &["nihvayate"]); - assert_has_lat(&["sam"], &han, &["saMhvayate"]); - assert_has_lat(&["upa"], &han, &["upahvayate"]); - assert_has_lat(&["vi"], &han, &["vihvayate"]); + let hve = d("hve\\Y", Bhvadi); + assert_has_lat(&["ni"], &hve, &["nihvayate"]); + assert_has_lat(&["sam"], &hve, &["saMhvayate"]); + assert_has_lat(&["upa"], &hve, &["upahvayate"]); + assert_has_lat(&["vi"], &hve, &["vihvayate"]); +} + +#[test] +fn sutra_1_3_30_v1() { + assert_has_lat(&["nis"], &d("asu~", Divadi), &["nirasyati", "nirasyate"]); + assert_has_lat(&["sam"], &d("Uha~\\", Bhvadi), &["samUhati", "samUhate"]); } #[test] @@ -229,12 +339,56 @@ fn sutra_1_3_42() { ); } +#[test] +fn sutra_1_3_43() { + let kram = d("kramu~", Bhvadi); + assert_has_lat(&[], &kram, &["krAmati", "krAmyati", "kramate", "kramyate"]); +} + +#[test] +fn sutra_1_3_44() { + let jna = d("jYA\\", Kryadi); + assert_has_lat(&["apa"], &jna, &["apajAnAti", "apajAnIte"]); +} + +#[test] +fn sutra_1_3_45() { + let jna = d("jYA\\", Kryadi); + assert_has_lat(&[], &jna, &["jAnAti", "jAnIte"]); +} + +#[test] +fn sutra_1_3_46() { + let jna = d("jYA\\", Kryadi); + assert_has_lat(&["sam"], &jna, &["saYjAnAti", "saYjAnIte"]); + assert_has_lat(&["prati"], &jna, &["pratijAnAti", "pratijAnIte"]); +} + #[test] fn sutra_1_3_47() { let vad = d("vada~", Bhvadi); assert_has_lat(&[], &vad, &["vadati", "vadate"]); } +#[test] +fn sutra_1_3_48() { + let vad = d("vada~", Bhvadi); + assert_has_lat(&["sam", "pra"], &vad, &["sampravadati", "sampravadate"]); +} + +#[test] +fn sutra_1_3_49() { + let vad = d("vada~", Bhvadi); + assert_has_lat(&["anu"], &vad, &["anuvadati", "anuvadate"]); +} + +#[test] +fn sutra_1_3_50() { + let vad = d("vada~", Bhvadi); + assert_has_jhi(&["vi", "pra"], &vad, Lat, &["vipravadanti"]); + assert_has_jha(&["vi", "pra"], &vad, Lat, &["vipravadante"]); +} + #[test] fn sutra_1_3_51() { let gf = d("gF", Tudadi); @@ -275,7 +429,6 @@ fn sutra_1_3_56() { assert_has_lat(&["upa"], &yam, &["upayacCati", "upayacCate"]); } -#[ignore] #[test] fn sutra_1_3_57() { let jna = d("jYA\\", Kryadi); @@ -323,7 +476,6 @@ fn sutra_1_3_61() { assert_has_lrn(&[], &mr, &["amarizyat"]); } -#[ignore] #[test] fn sutra_1_3_62() { let d = d; @@ -335,7 +487,7 @@ fn sutra_1_3_62() { assert_has_lat( &["AN"], &san("kramu~", Bhvadi), - &["AcikraMsate", "AcikraMsati"], + &["AcikraMsate", "Acikramizati"], ); // From S. C. Vasu's commentary @@ -345,7 +497,6 @@ fn sutra_1_3_62() { assert_has_lat(&[], &d("baDa~\\", Bhvadi), &["bIBatsate"]); } -#[ignore] #[test] fn sutra_1_3_63() { assert_has_lit( @@ -383,12 +534,86 @@ fn sutra_1_3_66() { assert_has_lat(&[], &bhuj, &["Bunakti", "BuNkte"]); } +#[ignore] +#[test] +fn sutra_1_3_68() { + assert_has_lat( + &[], + &nic(&d("YiBI\\", Juhotyadi)), + &["BAyayati", "BAyayate", "BIzayate", "BApayate"], + ); + assert_has_lat( + &["vi"], + &nic(&d("zmi\\N", Bhvadi)), + &["vismAyayati", "vismAyayate", "vismApayate"], + ); +} + +#[test] +fn sutra_1_3_69() { + assert_has_lat(&[], &nic(&d("gfDU~", Divadi)), &["garDayati", "garDayate"]); + assert_has_lat(&[], &nic(&d("vancu~", Bhvadi)), &["vaYcayati", "vaYcayate"]); +} + +#[test] +fn sutra_1_3_70() { + let li = d("lI\\N", Divadi); + assert_has_lat( + &["AN"], + &nic(&li), + &[ + "AlApayati", + "AlApayate", + "AlAlayati", + "AlAlayate", + "AlAyayati", + "AlAyayate", + "AlInayati", + "AlInayate", + ], + ); + assert_has_lat( + &["ud"], + &nic(&li), + &[ + "ullApayati", + "ullApayate", + "ullAlayati", + "ullAlayate", + "ullAyayati", + "ullAyayate", + "ullInayati", + "ullInayate", + ], + ); +} + +#[test] +fn sutra_1_3_72() { + // svaritet + assert_has_lat(&[], &d("ya\\ja~^", Bhvadi), &["yajati", "yajate"]); + assert_has_lat(&[], &d("qupa\\ca~^z", Bhvadi), &["pacati", "pacate"]); + // Yit + assert_has_lat(&[], &d("zu\\Y", Svadi), &["sunoti", "sunute"]); + assert_has_lat(&[], &d("qukf\\Y", Tanadi), &["karoti", "kurute"]); +} + #[test] fn sutra_1_3_73() { let vad = d("vada~", Bhvadi); assert_has_lat(&["apa"], &vad, &["apavadati", "apavadate"]); } +#[test] +fn sutra_1_3_74() { + assert_has_lat( + &[], + &nic(&d("qupa\\ca~^z", Bhvadi)), + &["pAcayate", "pAcayati"], + ); + assert_has_lat(&[], &nic(&d("qukf\\Y", Tanadi)), &["kArayate", "kArayati"]); +} + #[test] fn sutra_1_3_75() { let yam = d("ya\\ma~", Bhvadi); @@ -427,7 +652,7 @@ fn sutra_1_3_80() { assert_has_lat(&["aBi"], &ksip, &["aBikzipati"]); assert_has_lat(&["prati"], &ksip, &["pratikzipati"]); assert_has_lat(&["ati"], &ksip, &["atikzipati"]); - + // abhi-prati-atiByaH? assert_has_lat(&["AN"], &ksip, &["Akzipati", "Akzipate"]); } @@ -455,7 +680,38 @@ fn sutra_1_3_83() { } #[test] -fn sutra_1_3_85() { +fn sutra_1_3_84_and_sutra_1_3_85() { let ram = d("ra\\ma~\\", Bhvadi); assert_has_lat(&["upa"], &ram, &["uparamati", "uparamate"]); } + +#[test] +fn sutra_1_3_91() { + let dyut = &d("dyuta~\\", Bhvadi); + assert_has_lun(&["vi"], &dyut, &["vyadyutat", "vyadyotizwa"]); + assert_has_lun(&[], &d("luWa~\\", Bhvadi), &["aluWat", "aloWizwa"]); + // luNi? + assert_has_lat(&[], &dyut, &["dyotate"]); +} + +#[test] +fn sutra_1_3_92() { + let dyut = &d("dyuta~\\", Bhvadi); + assert_has_lun(&["vi"], &dyut, &["vyadyutat", "vyadyotizwa"]); + assert_has_lun(&[], &d("luWa~\\", Bhvadi), &["aluWat", "aloWizwa"]); + // luNi? + assert_has_lat(&[], &dyut, &["dyotate"]); +} + +#[test] +fn sutra_1_3_93() { + let vft = d("vftu~\\", Bhvadi); + assert_has_lrt(&[], &vft, &["vartsyati", "vartizyate"]); + assert_has_lrn(&[], &vft, &["avartsyat", "avartizyata"]); + assert_has_lat(&[], &san(&vft), &["vivftsati", "vivartizate"]); + + let vfdh = d("vfDu~\\", Bhvadi); + assert_has_lrt(&[], &vfdh, &["vartsyati", "varDizyate"]); + assert_has_lrn(&[], &vfdh, &["avartsyat", "avarDizyata"]); + assert_has_lat(&[], &san(&vfdh), &["vivftsati", "vivarDizate"]); +} diff --git a/vidyut-prakriya/tests/pada_1_4.rs b/vidyut-prakriya/tests/pada_1_4.rs index e995d62..f4dfecd 100644 --- a/vidyut-prakriya/tests/pada_1_4.rs +++ b/vidyut-prakriya/tests/pada_1_4.rs @@ -1,18 +1,16 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; +use vidyut_prakriya::args::Purusha as P; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +fn nic(d: &Dhatu) -> Dhatu { + d.clone().with_sanadi(&[Sanadi::Nic]) } fn dhatu_prati(text: &str) -> Pratipadika { @@ -26,10 +24,10 @@ fn dhatu_prati(text: &str) -> Pratipadika { #[test] fn sutra_1_4_3() { // IkArAnta - assert_has_subantas_p(&stri("kumArI"), Stri, Prathama, Eka, &["kumArI"]); - assert_has_subantas_p(&stri("gOrI"), Stri, Prathama, Eka, &["gOrI"]); + assert_has_subantas_p(&nyap("kumArI"), Stri, Prathama, Eka, &["kumArI"]); + assert_has_subantas_p(&nyap("gOrI"), Stri, Prathama, Eka, &["gOrI"]); assert_has_subantas("lakzmI", Stri, Prathama, Eka, &["lakzmIH"]); - assert_has_subantas_p(&stri("SArNgaravI"), Stri, Prathama, Eka, &["SArNgaravI"]); + assert_has_subantas_p(&nyap("SArNgaravI"), Stri, Prathama, Eka, &["SArNgaravI"]); // UkArAnta assert_has_subantas("brahmabanDU", Stri, Prathama, Eka, &["brahmabanDUH"]); assert_has_subantas("yavagU", Stri, Prathama, Eka, &["yavagUH"]); @@ -42,7 +40,28 @@ fn sutra_1_4_3() { assert_has_subantas("KalapU", Pum, Prathama, Eka, &["KalapUH"]); } -#[ignore] +#[test] +fn sutra_1_4_4() { + let shri = Pratipadika::builder() + .text("SrI") + .is_dhatu(true) + .build() + .unwrap(); + assert_has_subantas_p(&shri, Stri, Sambodhana, Eka, &["SrIH"]); + assert_has_subantas("BrU", Stri, Sambodhana, Eka, &["BrUH"]); + // astrI + assert_has_subantas("strI", Stri, Sambodhana, Eka, &["stri"]); +} + +#[test] +fn sutra_1_4_5() { + let shri = dhatu_prati("SrI"); + assert_has_subantas_p(&shri, Stri, Sasthi, Bahu, &["SriyAm", "SrIRAm"]); + assert_has_subantas("BrU", Stri, Sasthi, Bahu, &["BruvAm", "BrURAm"]); + // astrI + assert_has_subantas("strI", Stri, Sasthi, Bahu, &["strIRAm"]); +} + #[test] fn sutra_1_4_6() { assert_has_subantas("kfti", Stri, Caturthi, Eka, &["kftyE", "kftaye"]); @@ -60,7 +79,7 @@ fn sutra_1_4_6() { // stryAKyO assert_has_subantas("agni", Pum, Caturthi, Eka, &["agnaye"]); assert_has_subantas("vAyu", Pum, Caturthi, Eka, &["vAyave"]); - assert_has_subantas("BAnave", Pum, Caturthi, Eka, &["BAnave"]); + assert_has_subantas("Banu", Pum, Caturthi, Eka, &["Banave"]); } #[test] @@ -76,16 +95,108 @@ fn sutra_1_4_7() { assert_has_subantas("saKi", Pum, Saptami, Eka, &["saKyO"]); } +#[test] +fn sutra_1_4_8() { + assert_has_subantas("pati", Pum, Trtiya, Eka, &["patyA"]); + assert_has_subantas("pati", Pum, Caturthi, Eka, &["patye"]); + assert_has_subantas("pati", Pum, Panchami, Eka, &["patyuH"]); + assert_has_subantas("pati", Pum, Sasthi, Eka, &["patyuH"]); + assert_has_subantas("pati", Pum, Saptami, Eka, &["patyO"]); + // TODO: test when in samasa. +} + +#[test] +fn sutra_1_4_10() { + assert_has_krdanta(&[], &d("Bi\\di~^r", Rudhadi), Krt::tfc, &["Bettf"]); + assert_has_krdanta(&[], &d("Ci\\di~^r", Rudhadi), Krt::tfc, &["Cettf"]); + assert_has_lun_p(&[], &nic(&d("qukf\\Y", Tanadi)), &["acIkarat"]); + assert_has_lun_p(&[], &nic(&d("hf\\Y", Bhvadi)), &["ajIharat"]); +} + +#[test] +fn sutra_1_4_11() { + assert_has_krdanta(&[], &d("kuqi~\\", Bhvadi), Krt::a, &["kuRqA"]); + assert_has_krdanta(&[], &d("huqi~\\", Bhvadi), Krt::a, &["huRqA"]); + assert_has_krdanta(&[], &d("Sikza~\\", Bhvadi), Krt::a, &["SikzA"]); + assert_has_krdanta(&[], &d("Bikza~\\", Bhvadi), Krt::a, &["BikzA"]); +} + +#[test] +fn sutra_1_4_13() { + let kf = d("qukf\\Y", Tanadi); + let hf = d("hf\\Y", Bhvadi); + assert_has_krdanta(&[], &kf, Krt::tfc, &["kartf"]); + assert_has_krdanta(&[], &hf, Krt::tfc, &["hartf"]); + assert_has_lrt_p(&[], &kf, &["karizyati"]); + assert_has_lrt_p(&[], &hf, &["harizyati"]); + assert_has_lrn_p(&[], &kf, &["akarizyat"]); + assert_has_taddhitanta(&prati("upagu"), T::aR, &["Opagava"]); + assert_has_taddhitanta(&prati("kapawu"), T::aR, &["kApawava"]); + + // pratyayagrahana + assert_has_lan(&["ni"], &d("vi\\Sa~", Tudadi), &["nyaviSata"]); + assert_has_lan(&["vi"], &d("qukrI\\Y", Kryadi), &["vyakrIRIta"]); + + assert_has_parasmai_tinanta(&[], &kf, Lrt, P::Uttama, Dvi, &["karizyAvaH"]); + assert_has_parasmai_tinanta(&[], &kf, Lrt, P::Uttama, Bahu, &["karizyAmaH"]); + assert_has_subantas("kuRqa", Napumsaka, Prathama, Bahu, &["kuRqAni"]); + // TODO: others; +} + +#[test] +fn sutra_1_4_14() { + assert_has_subantas("brAhmaRa", Pum, Prathama, Bahu, &["brAhmaRAH"]); +} + +#[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"]); +} + #[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"]); - // tasau? + // tasau assert_has_taddhitanta(&prati("takzan"), T::matup, &["takzavat"]); } +#[test] +fn sutra_1_4_21() { + assert_has_subantas("brAhmaRa", Pum, Prathama, Bahu, &["brAhmaRAH"]); + assert_has_parasmai_tinanta( + &[], + &d("paWa~", Bhvadi), + Lat, + P::Prathama, + Bahu, + &["paWanti"], + ); +} + +#[test] +fn sutra_1_4_22() { + let path = d("paWa~", Bhvadi); + assert_has_subantas("brAhmaRa", Pum, Prathama, Dvi, &["brAhmaRO"]); + assert_has_parasmai_tinanta(&[], &path, Lat, P::Prathama, Dvi, &["paWataH"]); + + assert_has_subantas("brAhmaRa", Pum, Prathama, Eka, &["brAhmaRaH"]); + assert_has_parasmai_tinanta(&[], &path, Lat, P::Prathama, Eka, &["paWati"]); +} + +#[test] +fn sutra_1_4_59() { + let ni = d("RI\\Y", Bhvadi); + assert_has_lat_p(&["pra"], &ni, &["praRayati"]); + assert_has_lat_p(&["pari"], &ni, &["pariRayati"]); + assert_has_krdanta(&["pra"], &ni, Krt::Rvul, &["praRAyaka"]); + assert_has_krdanta(&["pari"], &ni, Krt::Rvul, &["pariRAyaka"]); +} + #[test] fn sutra_1_4_80() { assert_has_lat(&["vi"], &d("liKa~", Tudadi), &["viliKati"]); diff --git a/vidyut-prakriya/tests/pada_2_3.rs b/vidyut-prakriya/tests/pada_2_3.rs index 56ea7e9..067adaf 100644 --- a/vidyut-prakriya/tests/pada_2_3.rs +++ b/vidyut-prakriya/tests/pada_2_3.rs @@ -2,10 +2,43 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Vacana::*; -use vidyut_prakriya::args::Vibhakti as V; +use vidyut_prakriya::args::Vibhakti::*; + +#[test] +fn sutra_2_3_28() { + assert_has_subantas("vfka", Pum, Panchami, Bahu, &["vfkeByaH"]); + assert_has_subantas("aDyayana", Napumsaka, Panchami, Eka, &["aDyayanAt"]); + // lyap-lopa + assert_has_subantas("prAsAda", Napumsaka, Panchami, Eka, &["prAsAdAt"]); + // adhikarana + assert_has_subantas("Asana", Napumsaka, Panchami, Eka, &["AsanAt"]); + assert_has_subantas("Sayana", Napumsaka, Panchami, Eka, &["SayanAt"]); + // prashna + assert_has_subantas("pAwaliputra", Napumsaka, Panchami, Eka, &["pAwaliputrAt"]); + // TODO: tas-pratyaya +} + +#[test] +fn sutra_2_3_30() { + assert_has_subantas("grAma", Pum, Panchami, Eka, &["grAmAt"]); +} + +#[test] +fn sutra_2_3_47() { + assert_has_subantas("devadatta", Pum, Sambodhana, Eka, &["devadatta"]); + assert_has_subantas("devadatta", Pum, Sambodhana, Dvi, &["devadattO"]); + assert_has_subantas("devadatta", Pum, Sambodhana, Bahu, &["devadattAH"]); +} #[test] fn sutra_2_3_49() { - assert_has_subantas("pawu", Pum, V::Sambodhana, Eka, &["pawo"]); - assert_has_subantas("devadatta", Pum, V::Sambodhana, Eka, &["devadatta"]); + assert_has_subantas("pawu", Pum, Sambodhana, Eka, &["pawo"]); + assert_has_subantas("devadatta", Pum, Sambodhana, Eka, &["devadatta"]); +} + +#[test] +fn sutra_2_3_50() { + assert_has_subantas("rAjan", Pum, Sasthi, Eka, &["rAjYaH"]); + assert_has_subantas("paSu", Pum, Sasthi, Eka, &["paSoH"]); + assert_has_subantas("pitf", Pum, Sasthi, Eka, &["pituH"]); } diff --git a/vidyut-prakriya/tests/pada_2_4.rs b/vidyut-prakriya/tests/pada_2_4.rs index 6ac82a5..ad7543a 100644 --- a/vidyut-prakriya/tests/pada_2_4.rs +++ b/vidyut-prakriya/tests/pada_2_4.rs @@ -6,10 +6,6 @@ use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } @@ -18,6 +14,18 @@ fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } +#[ignore] +#[test] +fn sutra_2_4_35() { + let han = d("ha\\na~", Adadi); + assert_has_ashirlin(&[], &han, &["vaDyAt"]); + assert_has_vidhilin(&[], &han, &["hanyAt"]); + // TODO: wait until base substitution before adding krt + assert_has_krdanta(&[], &d("asa~", Adadi), Krt::yat, &["Bavya"]); + assert_has_krdanta(&["pra"], &d("aja~", Bhvadi), Krt::yat, &["praveya"]); + assert_has_krdanta(&["AN"], &d("ca\\kzi~\\N", Adadi), Krt::yat, &["AKyeya"]); +} + #[test] fn sutra_2_4_36() { let ad = d("a\\da~", Adadi); @@ -58,6 +66,8 @@ fn sutra_2_4_38() { assert_has_krdanta(&["pra"], &ad, Krt::ap, &["praGasa"]); } +// 2.4.39 is chAndasa. + #[test] fn sutra_2_4_40() { let ad = d("a\\da~", Adadi); @@ -141,27 +151,31 @@ fn sutra_2_4_45_v1() { #[test] fn sutra_2_4_46() { let i = d("i\\R", Adadi); - assert_has_parasmai_tinanta(&[], &nic(&i), Lat, Prathama, Eka, &["gamayati", "Ayayati"]); - assert_has_parasmai_tinanta( - &[], - &nic(&i), - Lat, - Prathama, - Dvi, - &["gamayataH", "AyayataH"], - ); - assert_has_parasmai_tinanta( - &[], - &nic(&i), - Lat, - Prathama, - Bahu, - &["gamayanti", "Ayayanti"], - ); + assert_has_tip(&[], &nic(&i), Lat, &["gamayati", "Ayayati"]); + assert_has_tas(&[], &nic(&i), Lat, &["gamayataH", "AyayataH"]); + assert_has_jhi(&[], &nic(&i), Lat, &["gamayanti", "Ayayanti"]); // TODO: iRvad } +#[ignore] +#[test] +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"]); + // 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"]); +} + #[test] fn sutra_2_4_49() { let i = d("i\\N", Adadi); @@ -284,6 +298,31 @@ fn sutra_2_4_55() { ); } +#[test] +fn sutra_2_4_56() { + let aj = d("aja~", Bhvadi); + assert_has_krdanta(&["pra"], &aj, Krt::anIyar, &["pravayaRIya"]); + assert_has_krdanta(&["pra"], &aj, Krt::Rvul, &["pravAyaka"]); + // aGaYap? + assert_has_krdanta(&["sam"], &aj, Krt::GaY, &["samAja"]); + assert_has_krdanta(&["ud"], &aj, Krt::GaY, &["udAja"]); + assert_has_krdanta(&["sam"], &aj, Krt::ap, &["samaja"]); + assert_has_krdanta(&["ud"], &aj, Krt::ap, &["udaja"]); +} + +#[test] +fn sutra_2_4_56_v2() { + let aj = d("aja~", Bhvadi); + assert_has_krdanta(&["pra"], &aj, Krt::tfc, &["pravetf", "prAjitf"]); + assert_has_krdanta(&["pra"], &aj, Krt::tumun, &["pravetum", "prAjitum"]); +} + +#[test] +fn sutra_2_4_57() { + let aj = d("aja~", Bhvadi); + assert_has_krdanta(&["pra"], &aj, Krt::lyuw, &["pravayaRa", "prAjana"]); +} + #[test] fn sutra_2_4_72() { assert_has_lat_p(&[], &d("a\\da~", Adadi), &["atti"]); diff --git a/vidyut-prakriya/tests/pada_3_1.rs b/vidyut-prakriya/tests/pada_3_1.rs index 1520cc3..70146b4 100644 --- a/vidyut-prakriya/tests/pada_3_1.rs +++ b/vidyut-prakriya/tests/pada_3_1.rs @@ -6,19 +6,31 @@ use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } +fn san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::San]) +} + fn yan(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Yan]) } -// For tests on 3.1.1, see `unadi_sutras.rs` +#[test] +fn sutra_3_1_1() { + let kf = Dhatu::new("qukf\\Y", Tanadi); + assert_has_krdanta(&[], &kf, Krt::tavyat, &["kartavya"]); + assert_has_krdanta(&[], &kf, Krt::anIyar, &["karaRIya"]); +} + +#[test] +fn sutra_3_1_2() { + let kf = Dhatu::new("qukf\\Y", Tanadi); + assert_has_krdanta(&[], &kf, Krt::tavyat, &["kartavya"]); + // TODO: tEtttirIya +} #[test] fn sutra_3_1_5() { @@ -71,6 +83,24 @@ fn sutra_3_1_22_v1() { assert_has_lat(&["pra"], &yan(&d("UrRuY", Adadi)), &["prorRonUyate"]); } +#[test] +fn sutra_3_1_23() { + assert_has_lat(&[], &yan(&d("kramu~", Bhvadi)), &["caNkramyate"]); + assert_has_lat(&[], &yan(&d("drama~", Bhvadi)), &["dandramyate"]); +} + +#[test] +fn sutra_3_1_24() { + assert_has_lat(&[], &yan(&d("lu\\px~^", Tudadi)), &["lolupyate"]); + assert_has_lat(&[], &yan(&d("za\\dx~", Bhvadi)), &["sAsadyate"]); + assert_has_lat(&[], &yan(&d("cara~", Bhvadi)), &["caYcUryate"]); + assert_has_lat(&[], &yan(&d("japa~", Bhvadi)), &["jaYjapyate"]); + assert_has_lat(&[], &yan(&d("jaBI~\\", Bhvadi)), &["jaYjaByate"]); + assert_has_lat(&[], &yan(&d("da\\ha~", Bhvadi)), &["dandahyate"]); + assert_has_lat(&[], &yan(&d("da\\nSa~", Bhvadi)), &["dandaSyate"]); + assert_has_lat(&["ni"], &yan(&d("gF", Tudadi)), &["nijegilyate"]); +} + #[test] fn sutra_3_1_25() { assert_has_lat_p(&[], &d("cura~", Curadi), &["corayati"]); @@ -170,10 +200,9 @@ fn sutra_3_1_45() { assert_has_lun_p(&[], &d("muza~", Kryadi), &["amozIt"]); } -#[ignore] #[test] fn sutra_3_1_46() { - assert_has_lun_p(&["AN"], &d("Sli\\za~", Divadi), &["ASlikSat", "ASlizat"]); + assert_has_lun_p(&["AN"], &d("Sli\\za~", Divadi), &["ASlikzat", "ASlizat"]); } #[test] @@ -262,6 +291,23 @@ fn sutra_3_1_57() { assert_has_lun_a(&[], &d("Ci\\di~^r", Rudhadi), &["acCitta"]); } +#[test] +fn sutra_3_1_58() { + assert_has_lun_p(&[], &d("jF", Kryadi), &["ajarat", "ajArIt"]); + // TODO: astamBIt? + // assert_has_lun_p(&[], &d("", Kryadi), &["astaBat", "astamBIt"]) + assert_has_lun_p(&[], &d("mrucu~", Bhvadi), &["amrucat", "amrocIt"]); + assert_has_lun_p(&[], &d("mlucu~", Bhvadi), &["amlucat", "amlocIt"]); + assert_has_lun_p(&[], &d("grucu~", Bhvadi), &["agrucat", "agrocIt"]); + assert_has_lun_p(&[], &d("glucu~", Bhvadi), &["aglucat", "aglocIt"]); + assert_has_lun_p(&[], &d("gluncu~", Bhvadi), &["aglucat", "agluYcIt"]); + assert_has_lun_p( + &[], + &d("wuo~Svi", Bhvadi), + &["aSvat", "aSvayIt", "aSiSviyat"], + ); +} + #[test] fn sutra_3_1_61() { assert_has_lun_karmani(&[], &d("dIpI~\\", Divadi), &["adIpi", "adIpizwa"]); @@ -437,7 +483,27 @@ fn sutra_3_1_97() { assert_has_krdanta(&[], &d("pA\\", Bhvadi), Krt::yat, &["peya"]); assert_has_krdanta(&[], &d("ci\\Y", Svadi), Krt::yat, &["ceya"]); assert_has_krdanta(&[], &d("ji\\", Bhvadi), Krt::yat, &["jeya"]); - // TODO: other examples. + + // ajanta-bhUta-pUrva + assert_has_krdanta(&[], &san(&d("do\\", Divadi)), Krt::yat, &["ditsya"]); + assert_has_krdanta(&[], &san(&d("quDA\\Y", Juhotyadi)), Krt::yat, &["Ditsya"]); +} + +#[test] +fn sutra_3_1_97_v1() { + // TODO: not sure which "tak" or "Sas" + assert_has_krdanta(&[], &d("taka~", Bhvadi), Krt::yat, &["takya"]); + assert_has_krdanta(&[], &d("Sasu~\\", Bhvadi), Krt::yat, &["Sasya"]); + assert_has_krdanta(&[], &d("cate~^", Bhvadi), Krt::yat, &["catya"]); + assert_has_krdanta(&[], &d("yatI~\\", Bhvadi), Krt::yat, &["yatya"]); + assert_has_krdanta(&[], &d("janI~\\", Divadi), Krt::yat, &["janya"]); +} + +#[test] +fn sutra_3_1_97_v2() { + let han = d("ha\\na~", Adadi); + assert_has_krdanta(&[], &han, Krt::yat, &["vaDya"]); + assert_has_krdanta(&[], &han, Krt::Ryat, &["GAtya"]); } #[test] @@ -548,6 +614,43 @@ fn sutra_3_1_133() { assert_has_krdanta(&[], &hf, Krt::tfc, &["hartf"]); } +#[test] +fn sutra_3_1_137() { + let paa = &d("pA\\", Bhvadi); + assert_has_krdanta(&["ud"], &paa, Krt::Sa, &["utpiba"]); + assert_has_krdanta(&["vi"], &paa, Krt::Sa, &["vipiba"]); + + let ghra = &d("GrA\\", Bhvadi); + assert_has_krdanta(&["ud"], &ghra, Krt::Sa, &["ujjiGra"]); + assert_has_krdanta(&["vi"], &ghra, Krt::Sa, &["vijiGra"]); + + let dhma = &d("DmA\\", Bhvadi); + assert_has_krdanta(&["ud"], &dhma, Krt::Sa, &["udDama"]); + assert_has_krdanta(&["vi"], &dhma, Krt::Sa, &["viDama"]); + + let dhe = &d("De\\w", Bhvadi); + assert_has_krdanta(&["ud"], &dhe, Krt::Sa, &["udDaya"]); + assert_has_krdanta(&["vi"], &dhe, Krt::Sa, &["viDaya"]); + + let dfs = &d("df\\Si~r", Bhvadi); + assert_has_krdanta(&["ud"], &dfs, Krt::Sa, &["utpaSya"]); + assert_has_krdanta(&["vi"], &dfs, Krt::Sa, &["vipaSya"]); +} + +#[ignore] +#[test] +fn sutra_3_1_138() { + assert_has_krdanta(&[], &d("li\\pa~^", Tudadi), Krt::Sa, &["limpa"]); + assert_has_krdanta(&[], &d("vi\\dx~^", Tudadi), Krt::Sa, &["vinda"]); + assert_has_krdanta(&[], &d("", Bhvadi), Krt::Sa, &["DAraya"]); + assert_has_krdanta(&[], &d("pF", Curadi), Krt::Sa, &["pAraya"]); + assert_has_krdanta(&[], &d("vida~", Bhvadi), Krt::Sa, &["vedaya"]); + assert_has_krdanta(&["ud"], &d("ejf~\\", Bhvadi), Krt::Sa, &["udejaya"]); + assert_has_krdanta(&[], &d("cita~", Curadi), Krt::Sa, &["cetaya"]); + assert_has_krdanta(&[], &d("sAti", Bhvadi), Krt::Sa, &["sAtaya"]); + assert_has_krdanta(&[], &d("zaha~\\", Bhvadi), Krt::Sa, &["sAhaya"]); +} + #[test] fn sutra_3_1_142() { assert_has_krdanta(&[], &d("wudu\\", Svadi), Krt::Ra, &["dAva"]); @@ -565,10 +668,10 @@ fn sutra_3_1_144() { #[test] fn sutra_3_1_145() { + // TODO: change examples to nartakI, etc. assert_has_krdanta(&[], &d("nftI~", Divadi), Krt::zvun, &["nartaka"]); assert_has_krdanta(&[], &d("Kanu~^", Bhvadi), Krt::zvun, &["Kanaka"]); assert_has_krdanta(&[], &d("ra\\nja~^", Bhvadi), Krt::zvun, &["rajaka"]); - // TODO: stri } #[test] diff --git a/vidyut-prakriya/tests/pada_3_2.rs b/vidyut-prakriya/tests/pada_3_2.rs index 5af18c7..d480761 100644 --- a/vidyut-prakriya/tests/pada_3_2.rs +++ b/vidyut-prakriya/tests/pada_3_2.rs @@ -3,8 +3,21 @@ use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) +#[test] +fn sutra_3_2_16() { + assert_has_krdanta(&[], &d("cara~", Bhvadi), Krt::wa, &["cara"]); + // TODO: upapadas +} + +#[test] +fn sutra_3_2_62() { + assert_has_krdanta(&["pra"], &d("Ba\\ja~^", Bhvadi), Krt::Rvi, &["praBAj"]); +} + +#[test] +fn sutra_3_2_97() { + assert_has_krdanta(&[], &d("janI~\\", Divadi), Krt::qa, &["ja"]); + // TODO: upapadas } #[test] diff --git a/vidyut-prakriya/tests/pada_3_3.rs b/vidyut-prakriya/tests/pada_3_3.rs index 16c071a..0618cdc 100644 --- a/vidyut-prakriya/tests/pada_3_3.rs +++ b/vidyut-prakriya/tests/pada_3_3.rs @@ -3,10 +3,16 @@ use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) +fn san(d: &Dhatu) -> Dhatu { + d.clone().with_sanadi(&[Sanadi::San]) } +fn nic(d: &Dhatu) -> Dhatu { + d.clone().with_sanadi(&[Sanadi::Nic]) +} + +// For tests on 3.3.1, see `unadi_sutras.rs` + #[test] fn sutra_3_3_10() { assert_has_krdanta(&[], &d("Bu\\ja~", Rudhadi), Krt::tumun, &["Boktum"]); @@ -44,6 +50,13 @@ fn sutra_3_3_18() { assert_has_krdanta(&[], &d("ra\\nja~^", Divadi), Krt::GaY, &["rAga", "raNga"]); } +#[test] +fn sutra_3_3_88() { + assert_has_krdanta(&[], &d("qupa\\ca~^z", Bhvadi), Krt::ktri, &["paktrima"]); + assert_has_krdanta(&[], &d("quva\\pa~^", Bhvadi), Krt::ktri, &["uptrima"]); + assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::ktri, &["kftrima"]); +} + #[test] fn sutra_3_3_89() { assert_has_krdanta(&[], &d("wuvepf~\\", Bhvadi), Krt::aTuc, &["vepaTu"]); @@ -74,6 +87,34 @@ fn sutra_3_3_94() { // TODO: others } +#[test] +fn sutra_3_3_102() { + assert_has_krdanta(&[], &san(&d("qukf\\Y", Tanadi)), Krt::a, &["cikIrzA"]); + assert_has_krdanta(&[], &san(&d("hf\\Y", Bhvadi)), Krt::a, &["jihIrzA"]); + // TODO: others +} + +#[test] +fn sutra_3_3_103() { + assert_has_krdanta(&[], &d("kuqi~\\", Bhvadi), Krt::a, &["kuRqA"]); + assert_has_krdanta(&[], &d("huqi~\\", Bhvadi), Krt::a, &["huRqA"]); + assert_has_krdanta(&[], &d("Iha~\\", Bhvadi), Krt::a, &["IhA"]); + assert_has_krdanta(&[], &d("Uha~\\", Bhvadi), Krt::a, &["UhA"]); + // guroH + assert_has_krdanta(&[], &d("Ba\\ja~^", Bhvadi), Krt::a, &[]); + // halaH + assert_has_krdanta(&[], &d("RI\\Y", Bhvadi), Krt::a, &[]); +} + +#[ignore] +#[test] +fn sutra_3_3_107() { + assert_has_krdanta(&[], &nic(&d("qukf\\Y", Tanadi)), Krt::yuc, &["kAraRA"]); + assert_has_krdanta(&[], &nic(&d("hf\\Y", Bhvadi)), Krt::yuc, &["hArRA"]); + assert_has_krdanta(&[], &nic(&d("Asa~\\", Adadi)), Krt::yuc, &["AsanA"]); + assert_has_krdanta(&[], &nic(&d("SranTa~", Kryadi)), Krt::yuc, &["SranTanA"]); +} + #[test] fn sutra_3_3_115() { assert_has_krdanta(&[], &d("hase~", Bhvadi), Krt::lyuw, &["hasana"]); @@ -82,3 +123,9 @@ fn sutra_3_3_115() { assert_has_krdanta(&[], &d("SIN", Adadi), Krt::lyuw, &["Sayana"]); assert_has_krdanta(&[], &d("Asa~\\", Adadi), Krt::lyuw, &["Asana"]); } + +#[test] +fn sutra_3_3_120() { + assert_has_krdanta(&["ava"], &d("tF", Bhvadi), Krt::GaY, &["avatAra"]); + assert_has_krdanta(&["ava"], &d("stFY", Kryadi), Krt::GaY, &["avastAra"]); +} diff --git a/vidyut-prakriya/tests/pada_3_4.rs b/vidyut-prakriya/tests/pada_3_4.rs index 218c182..d5b45d6 100644 --- a/vidyut-prakriya/tests/pada_3_4.rs +++ b/vidyut-prakriya/tests/pada_3_4.rs @@ -9,20 +9,43 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) +#[test] +fn sutra_3_4_12() { + assert_has_krdanta(&["vi"], &d("Ba\\ja~^", Tudadi), Krt::Ramul, &["viBAjam"]); + assert_has_krdanta(&["apa"], &d("lu\\px~^", Tudadi), Krt::kamul, &["apalupam"]); } -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +#[test] +fn sutra_3_4_17() { + assert_has_krdanta(&["vi"], &d("sf\\px~", Tudadi), Krt::kasun, &["visfpas"]); + assert_has_krdanta(&["AN"], &d("u~tfdi~^r", Rudhadi), Krt::kasun, &["Atfdas"]); } -fn assert_has_jhi(prefixes: &[&str], dhatu: &Dhatu, lakara: Lakara, exp: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, lakara, Prathama, Bahu, exp); +#[test] +fn sutra_3_4_21() { + assert_has_krdanta(&[], &d("Bu\\ja~", Rudhadi), Krt::ktvA, &["BuktvA"]); + assert_has_krdanta(&[], &d("pA\\", Bhvadi), Krt::ktvA, &["pItvA"]); + assert_has_krdanta(&[], &d("zRA\\", Adadi), Krt::ktvA, &["snAtvA"]); } -pub fn assert_has_lit_p_2s(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lit, Madhyama, Eka, expected); +#[test] +fn sutra_3_4_70() { + let kf = &d("qukf\\Y", Tanadi); + let bhuj = &d("Bu\\ja~", Rudhadi); + let aas = &d("Asa~\\", Tanadi); + let shi = &d("SIN", Adadi); + assert_has_krdanta(&[], &kf, Krt::tavya, &["kartavya"]); + assert_has_krdanta(&[], &bhuj, Krt::tavya, &["Boktavya"]); + assert_has_krdanta(&[], &aas, Krt::tavya, &["Asitavya"]); + assert_has_krdanta(&[], &shi, Krt::tavya, &["Sayitavya"]); + // kta + assert_has_krdanta(&[], &kf, Krt::kta, &["kfta"]); + assert_has_krdanta(&[], &bhuj, Krt::kta, &["Bukta"]); + assert_has_krdanta(&[], &aas, Krt::kta, &["Asita"]); + assert_has_krdanta(&[], &shi, Krt::kta, &["Sayita"]); + + assert_has_krdanta(&[], &kf, Krt::Kal, &["kara"]); + assert_has_krdanta(&[], &d("BU", Bhvadi), Krt::Kal, &["Bava"]); } #[test] @@ -32,16 +55,16 @@ fn sutra_3_4_78() { use Vacana::*; let pac = d("qupa\\ca~^z", Bhvadi); + assert_has_tip(&[], &pac, Lat, &["pacati"]); + assert_has_tas(&[], &pac, Lat, &["pacataH"]); + assert_has_jhi(&[], &pac, Lat, &["pacanti"]); + assert_has_sip(&[], &pac, Lat, &["pacasi"]); + assert_has_thas(&[], &pac, Lat, &["pacaTaH"]); + assert_has_tha(&[], &pac, Lat, &["pacaTa"]); + assert_has_mip(&[], &pac, Lat, &["pacAmi"]); + assert_has_vas(&[], &pac, Lat, &["pacAvaH"]); + assert_has_mas(&[], &pac, Lat, &["pacAmaH"]); let items = &[ - (Prathama, Eka, Parasmai, "pacati"), - (Prathama, Dvi, Parasmai, "pacataH"), - (Prathama, Bahu, Parasmai, "pacanti"), - (Madhyama, Eka, Parasmai, "pacasi"), - (Madhyama, Dvi, Parasmai, "pacaTaH"), - (Madhyama, Bahu, Parasmai, "pacaTa"), - (Uttama, Eka, Parasmai, "pacAmi"), - (Uttama, Dvi, Parasmai, "pacAvaH"), - (Uttama, Bahu, Parasmai, "pacAmaH"), (Prathama, Eka, Atmane, "pacate"), (Prathama, Dvi, Atmane, "pacete"), (Prathama, Bahu, Atmane, "pacante"), @@ -76,91 +99,113 @@ fn sutra_3_4_79() { #[test] fn sutra_3_4_80() { let pac = d("qupa\\ca~^z", Bhvadi); - assert_has_atmane_tinanta(&[], &pac, Lat, Madhyama, Eka, &["pacase"]); - assert_has_atmane_tinanta(&[], &pac, Lit, Madhyama, Eka, &["pecize"]); - assert_has_atmane_tinanta(&[], &pac, Lut, Madhyama, Eka, &["paktAse"]); - assert_has_atmane_tinanta(&[], &pac, Lrt, Madhyama, Eka, &["pakzyase"]); + assert_has_thaas(&[], &pac, Lat, &["pacase"]); + assert_has_thaas(&[], &pac, Lit, &["pecize"]); + assert_has_thaas(&[], &pac, Lut, &["paktAse"]); + assert_has_thaas(&[], &pac, Lrt, &["pakzyase"]); } #[test] fn sutra_3_4_81() { let pac = d("qupa\\ca~^z", Bhvadi); - assert_has_atmane_tinanta(&[], &pac, Lit, Prathama, Eka, &["pece"]); - assert_has_atmane_tinanta(&[], &pac, Lit, Prathama, Dvi, &["pecAte"]); - assert_has_atmane_tinanta(&[], &pac, Lit, Prathama, Bahu, &["pecire"]); + assert_has_ta(&[], &pac, Lit, &["pece"]); + assert_has_aataam(&[], &pac, Lit, &["pecAte"]); + assert_has_jha(&[], &pac, Lit, &["pecire"]); let labh = d("qula\\Ba~\\z", Bhvadi); - assert_has_atmane_tinanta(&[], &labh, Lit, Prathama, Eka, &["leBe"]); - assert_has_atmane_tinanta(&[], &labh, Lit, Prathama, Dvi, &["leBAte"]); - assert_has_atmane_tinanta(&[], &labh, Lit, Prathama, Bahu, &["leBire"]); + assert_has_ta(&[], &labh, Lit, &["leBe"]); + assert_has_aataam(&[], &labh, Lit, &["leBAte"]); + assert_has_jha(&[], &labh, Lit, &["leBire"]); } #[test] fn sutra_3_4_82() { let pac = d("qupa\\ca~^z", Bhvadi); - assert_has_parasmai_tinanta(&[], &pac, Lit, Prathama, Eka, &["papAca"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Prathama, Dvi, &["pecatuH"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Prathama, Bahu, &["pecuH"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Madhyama, Eka, &["peciTa", "papakTa"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Madhyama, Dvi, &["pecaTuH"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Madhyama, Bahu, &["peca"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Uttama, Eka, &["papAca", "papaca"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Uttama, Dvi, &["peciva"]); - assert_has_parasmai_tinanta(&[], &pac, Lit, Uttama, Bahu, &["pecima"]); + assert_has_tip(&[], &pac, Lit, &["papAca"]); + assert_has_tas(&[], &pac, Lit, &["pecatuH"]); + assert_has_jhi(&[], &pac, Lit, &["pecuH"]); + assert_has_sip(&[], &pac, Lit, &["peciTa", "papakTa"]); + assert_has_thas(&[], &pac, Lit, &["pecaTuH"]); + assert_has_tha(&[], &pac, Lit, &["peca"]); + assert_has_mip(&[], &pac, Lit, &["papAca", "papaca"]); + assert_has_vas(&[], &pac, Lit, &["peciva"]); + assert_has_mas(&[], &pac, Lit, &["pecima"]); +} + +#[test] +fn sutra_3_4_83() { + let vid = d("vida~", Adadi); + assert_has_tip(&[], &vid, Lat, &["veda", "vetti"]); + assert_has_tas(&[], &vid, Lat, &["vidatuH", "vittaH"]); + assert_has_jhi(&[], &vid, Lat, &["viduH", "vidanti"]); + assert_has_sip(&[], &vid, Lat, &["vetTa", "vetsi"]); + assert_has_thas(&[], &vid, Lat, &["vidaTuH", "vitTaH"]); + assert_has_tha(&[], &vid, Lat, &["vida", "vitTa"]); + assert_has_mip(&[], &vid, Lat, &["veda", "vedmi"]); + assert_has_vas(&[], &vid, Lat, &["vidva", "vidvaH"]); + assert_has_mas(&[], &vid, Lat, &["vidma", "vidmaH"]); +} + +#[test] +fn sutra_3_4_84() { + let bru = d("brUY", Adadi); + assert_has_tip(&[], &bru, Lat, &["Aha", "bravIti"]); + assert_has_tas(&[], &bru, Lat, &["AhatuH", "brUtaH"]); + assert_has_jhi(&[], &bru, Lat, &["AhuH", "bruvanti"]); + assert_has_sip(&[], &bru, Lat, &["AtTa", "bravIzi"]); + assert_has_thas(&[], &bru, Lat, &["AhaTuH", "brUTaH"]); + assert_has_tha(&[], &bru, Lat, &["brUTa"]); + assert_has_mip(&[], &bru, Lat, &["bravImi"]); + assert_has_vas(&[], &bru, Lat, &["brUvaH"]); + assert_has_mas(&[], &bru, Lat, &["brUmaH"]); } #[test] fn sutra_3_4_85() { let pac = d("qupa\\ca~^z", Bhvadi); - assert_has_parasmai_tinanta(&[], &pac, Lot, Prathama, Dvi, &["pacatAm"]); - assert_has_parasmai_tinanta(&[], &pac, Lot, Madhyama, Dvi, &["pacatam"]); - assert_has_parasmai_tinanta(&[], &pac, Lot, Madhyama, Bahu, &["pacata"]); - assert_has_parasmai_tinanta(&[], &pac, Lot, Uttama, Dvi, &["pacAva"]); - assert_has_parasmai_tinanta(&[], &pac, Lot, Uttama, Bahu, &["pacAma"]); + assert_has_tas(&[], &pac, Lot, &["pacatAm"]); + assert_has_thas(&[], &pac, Lot, &["pacatam"]); + assert_has_tha(&[], &pac, Lot, &["pacata"]); + assert_has_vas(&[], &pac, Lot, &["pacAva"]); + assert_has_mas(&[], &pac, Lot, &["pacAma"]); // - assert_has_parasmai_tinanta(&[], &d("yA\\", Adadi), Lot, Prathama, Bahu, &["yAntu"]); - assert_has_parasmai_tinanta(&[], &d("vA\\", Adadi), Lot, Prathama, Bahu, &["vAntu"]); + assert_has_jhi(&[], &d("yA\\", Adadi), Lot, &["yAntu"]); + assert_has_jhi(&[], &d("vA\\", Adadi), Lot, &["vAntu"]); } #[test] fn sutra_3_4_86() { let pac = d("qupa\\ca~^z", Bhvadi); - assert_has_parasmai_tinanta(&[], &pac, Lot, Prathama, Eka, &["pacatu", "pacatAt"]); - assert_has_parasmai_tinanta(&[], &pac, Lot, Prathama, Bahu, &["pacantu"]); + assert_has_tip(&[], &pac, Lot, &["pacatu", "pacatAt"]); + assert_has_jhi(&[], &pac, Lot, &["pacantu"]); } #[test] fn sutra_3_4_87() { - let assert_has_lot_madhyama_eka = |dhatu, exp| { - assert_has_parasmai_tinanta(&[], &dhatu, Lot, Madhyama, Eka, exp); - }; - assert_has_lot_madhyama_eka(d("lUY", Kryadi), &["lunIhi", "lunItAt"]); - assert_has_lot_madhyama_eka(d("pUY", Kryadi), &["punIhi", "punItAt"]); - assert_has_lot_madhyama_eka(d("rA\\Da~", Svadi), &["rADnuhi", "rADnutAt"]); - assert_has_lot_madhyama_eka( - d("takzU~", Bhvadi), + assert_has_sip(&[], &d("lUY", Kryadi), Lot, &["lunIhi", "lunItAt"]); + assert_has_sip(&[], &d("pUY", Kryadi), Lot, &["punIhi", "punItAt"]); + assert_has_sip(&[], &d("rA\\Da~", Svadi), Lot, &["rADnuhi", "rADnutAt"]); + assert_has_sip( + &[], + &d("takzU~", Bhvadi), + Lot, &["takzRuhi", "takzRutAt", "takza", "takzatAt"], ); } +// 3.4.88 is chAndasa. + #[test] fn sutra_3_4_89() { - assert_has_parasmai_tinanta( - &[], - &d("qupa\\ca~^z", Bhvadi), - Lot, - Uttama, - Eka, - &["pacAni"], - ); - assert_has_parasmai_tinanta(&[], &d("paWa~", Bhvadi), Lot, Uttama, Eka, &["paWAni"]); + assert_has_mip(&[], &d("qupa\\ca~^z", Bhvadi), Lot, &["pacAni"]); + assert_has_mip(&[], &d("paWa~", Bhvadi), Lot, &["paWAni"]); } #[test] fn sutra_3_4_90() { let pac = d("qupa\\ca~^z", Bhvadi); - assert_has_atmane_tinanta(&[], &pac, Lot, Prathama, Eka, &["pacatAm"]); - assert_has_atmane_tinanta(&[], &pac, Lot, Prathama, Dvi, &["pacetAm"]); - assert_has_atmane_tinanta(&[], &pac, Lot, Prathama, Bahu, &["pacantAm"]); + assert_has_ta(&[], &pac, Lot, &["pacatAm"]); + assert_has_aataam(&[], &pac, Lot, &["pacetAm"]); + assert_has_jha(&[], &pac, Lot, &["pacantAm"]); } #[test] @@ -181,6 +226,8 @@ fn sutra_3_4_92_and_sutra_3_4_93() { assert_has_atmane_tinanta(&[], &kf, Lot, Uttama, Bahu, &["karavAmahE"]); } +// 3.4.94 - 3.4.98 are for lew. + #[test] fn sutra_3_4_99() { let pac = d("qupa\\ca~^z", Bhvadi); @@ -249,12 +296,9 @@ fn sutra_3_4_104() { #[test] fn sutra_3_4_105() { - let assert_has_jha = |dhatu, lakara, exp| { - assert_has_atmane_tinanta(&[], &dhatu, lakara, Prathama, Bahu, exp); - }; - assert_has_jha(d("qupa\\ca~^z", Bhvadi), VidhiLin, &["paceran"]); - assert_has_jha(d("ya\\ja~^", Bhvadi), VidhiLin, &["yajeran"]); - assert_has_jha(d("qukf\\Y", Tanadi), AshirLin, &["kfzIran"]); + assert_has_jha(&[], &d("qupa\\ca~^z", Bhvadi), VidhiLin, &["paceran"]); + assert_has_jha(&[], &d("ya\\ja~^", Bhvadi), VidhiLin, &["yajeran"]); + assert_has_jha(&[], &d("qukf\\Y", Tanadi), AshirLin, &["kfzIran"]); } #[test] @@ -352,8 +396,8 @@ fn sutra_3_4_114() { #[test] fn sutra_3_4_115() { - assert_has_lit_p_2s(&[], &d("qupa\\ca~^z", Adadi), &["peciTa", "papakTa"]); - assert_has_lit_p_2s(&[], &d("Sa\\kx~", Adadi), &["SekiTa", "SaSakTa"]); + assert_has_sip(&[], &d("qupa\\ca~^z", Adadi), Lit, &["peciTa", "papakTa"]); + assert_has_sip(&[], &d("Sa\\kx~", Adadi), Lit, &["SekiTa", "SaSakTa"]); assert_has_lit_karmani(&[], &d("glE\\", Bhvadi), &["jagle"]); assert_has_lit_karmani(&[], &d("mlE\\", Bhvadi), &["mamle"]); } @@ -369,3 +413,5 @@ fn sutra_3_4_116() { assert_has_vidhilin_p(&[], &lu, &["lunIyAt"]); assert_has_vidhilin_p(&[], &pu, &["punIyAt"]); } + +// 3.4.117 is chAndasa. diff --git a/vidyut-prakriya/tests/pada_4_1.rs b/vidyut-prakriya/tests/pada_4_1.rs index d709164..1e042c0 100644 --- a/vidyut-prakriya/tests/pada_4_1.rs +++ b/vidyut-prakriya/tests/pada_4_1.rs @@ -1,15 +1,11 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::Taddhita; +use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti::*; use vidyut_prakriya::args::*; -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() -} - fn assert_has_pum(prati: &str, expected: &[&str]) { assert_has_subantas(prati, Pum, Prathama, Eka, expected); } @@ -18,6 +14,200 @@ fn assert_has_stri(prati: &str, expected: &[&str]) { assert_has_subantas(prati, Stri, Prathama, Eka, expected); } +#[test] +fn sutra_4_1_2() { + // NIp + let kumari = Pratipadika::builder() + .text("kumArI") + .is_nyap(true) + .build() + .unwrap(); + assert_has_subantas_p(&kumari, Stri, Prathama, Eka, &["kumArI"]); + assert_has_subantas_p(&kumari, Stri, Prathama, Dvi, &["kumAryO"]); + assert_has_subantas_p(&kumari, Stri, Prathama, Bahu, &["kumAryaH"]); + assert_has_subantas_p(&kumari, Stri, Dvitiya, Eka, &["kumArIm"]); + assert_has_subantas_p(&kumari, Stri, Dvitiya, Dvi, &["kumAryO"]); + assert_has_subantas_p(&kumari, Stri, Dvitiya, Bahu, &["kumArIH"]); + assert_has_subantas_p(&kumari, Stri, Trtiya, Eka, &["kumAryA"]); + assert_has_subantas_p(&kumari, Stri, Trtiya, Dvi, &["kumArIByAm"]); + assert_has_subantas_p(&kumari, Stri, Trtiya, Bahu, &["kumArIBiH"]); + assert_has_subantas_p(&kumari, Stri, Caturthi, Eka, &["kumAryE"]); + assert_has_subantas_p(&kumari, Stri, Caturthi, Dvi, &["kumArIByAm"]); + assert_has_subantas_p(&kumari, Stri, Caturthi, Bahu, &["kumArIByaH"]); + assert_has_subantas_p(&kumari, Stri, Panchami, Eka, &["kumAryAH"]); + assert_has_subantas_p(&kumari, Stri, Panchami, Dvi, &["kumArIByAm"]); + assert_has_subantas_p(&kumari, Stri, Panchami, Bahu, &["kumArIByaH"]); + assert_has_subantas_p(&kumari, Stri, Sasthi, Eka, &["kumAryAH"]); + assert_has_subantas_p(&kumari, Stri, Sasthi, Dvi, &["kumAryoH"]); + assert_has_subantas_p(&kumari, Stri, Sasthi, Bahu, &["kumArIRAm"]); + assert_has_subantas_p(&kumari, Stri, Saptami, Eka, &["kumAryAm"]); + assert_has_subantas_p(&kumari, Stri, Saptami, Dvi, &["kumAryoH"]); + assert_has_subantas_p(&kumari, Stri, Saptami, Bahu, &["kumArIzu"]); + + // NIz + let gauri = Pratipadika::builder() + .text("gOrI") + .is_nyap(true) + .build() + .unwrap(); + assert_has_subantas_p(&gauri, Stri, Prathama, Eka, &["gOrI"]); + assert_has_subantas_p(&gauri, Stri, Prathama, Dvi, &["gOryO"]); + assert_has_subantas_p(&gauri, Stri, Prathama, Bahu, &["gOryaH"]); + assert_has_subantas_p(&gauri, Stri, Dvitiya, Eka, &["gOrIm"]); + assert_has_subantas_p(&gauri, Stri, Dvitiya, Dvi, &["gOryO"]); + assert_has_subantas_p(&gauri, Stri, Dvitiya, Bahu, &["gOrIH"]); + assert_has_subantas_p(&gauri, Stri, Trtiya, Eka, &["gOryA"]); + assert_has_subantas_p(&gauri, Stri, Trtiya, Dvi, &["gOrIByAm"]); + assert_has_subantas_p(&gauri, Stri, Trtiya, Bahu, &["gOrIBiH"]); + assert_has_subantas_p(&gauri, Stri, Caturthi, Eka, &["gOryE"]); + assert_has_subantas_p(&gauri, Stri, Caturthi, Dvi, &["gOrIByAm"]); + assert_has_subantas_p(&gauri, Stri, Caturthi, Bahu, &["gOrIByaH"]); + assert_has_subantas_p(&gauri, Stri, Panchami, Eka, &["gOryAH"]); + assert_has_subantas_p(&gauri, Stri, Panchami, Dvi, &["gOrIByAm"]); + assert_has_subantas_p(&gauri, Stri, Panchami, Bahu, &["gOrIByaH"]); + assert_has_subantas_p(&gauri, Stri, Sasthi, Eka, &["gOryAH"]); + assert_has_subantas_p(&gauri, Stri, Sasthi, Dvi, &["gOryoH"]); + assert_has_subantas_p(&gauri, Stri, Sasthi, Bahu, &["gOrIRAm"]); + assert_has_subantas_p(&gauri, Stri, Saptami, Eka, &["gOryAm"]); + assert_has_subantas_p(&gauri, Stri, Saptami, Dvi, &["gOryoH"]); + assert_has_subantas_p(&gauri, Stri, Saptami, Bahu, &["gOrIzu"]); + + // NIn + let sharngaravi = Pratipadika::builder() + .text("SArNgaravI") + .is_nyap(true) + .build() + .unwrap(); + assert_has_subantas_p(&sharngaravi, Stri, Prathama, Eka, &["SArNgaravI"]); + assert_has_subantas_p(&sharngaravi, Stri, Prathama, Dvi, &["SArNgaravyO"]); + assert_has_subantas_p(&sharngaravi, Stri, Prathama, Bahu, &["SArNgaravyaH"]); + assert_has_subantas_p(&sharngaravi, Stri, Dvitiya, Eka, &["SArNgaravIm"]); + assert_has_subantas_p(&sharngaravi, Stri, Dvitiya, Dvi, &["SArNgaravyO"]); + assert_has_subantas_p(&sharngaravi, Stri, Dvitiya, Bahu, &["SArNgaravIH"]); + assert_has_subantas_p(&sharngaravi, Stri, Trtiya, Eka, &["SArNgaravyA"]); + assert_has_subantas_p(&sharngaravi, Stri, Trtiya, Dvi, &["SArNgaravIByAm"]); + assert_has_subantas_p(&sharngaravi, Stri, Trtiya, Bahu, &["SArNgaravIBiH"]); + assert_has_subantas_p(&sharngaravi, Stri, Caturthi, Eka, &["SArNgaravyE"]); + assert_has_subantas_p(&sharngaravi, Stri, Caturthi, Dvi, &["SArNgaravIByAm"]); + assert_has_subantas_p(&sharngaravi, Stri, Caturthi, Bahu, &["SArNgaravIByaH"]); + assert_has_subantas_p(&sharngaravi, Stri, Panchami, Eka, &["SArNgaravyAH"]); + assert_has_subantas_p(&sharngaravi, Stri, Panchami, Dvi, &["SArNgaravIByAm"]); + assert_has_subantas_p(&sharngaravi, Stri, Panchami, Bahu, &["SArNgaravIByaH"]); + assert_has_subantas_p(&sharngaravi, Stri, Sasthi, Eka, &["SArNgaravyAH"]); + assert_has_subantas_p(&sharngaravi, Stri, Sasthi, Dvi, &["SArNgaravyoH"]); + assert_has_subantas_p(&sharngaravi, Stri, Sasthi, Bahu, &["SArNgaravIRAm"]); + assert_has_subantas_p(&sharngaravi, Stri, Saptami, Eka, &["SArNgaravyAm"]); + assert_has_subantas_p(&sharngaravi, Stri, Saptami, Dvi, &["SArNgaravyoH"]); + assert_has_subantas_p(&sharngaravi, Stri, Saptami, Bahu, &["SArNgaravIzu"]); + + // wAp + let khatva = Pratipadika::builder() + .text("KawvA") + .is_nyap(true) + .build() + .unwrap(); + assert_has_subantas_p(&khatva, Stri, Prathama, Eka, &["KawvA"]); + assert_has_subantas_p(&khatva, Stri, Prathama, Dvi, &["Kawve"]); + assert_has_subantas_p(&khatva, Stri, Prathama, Bahu, &["KawvAH"]); + assert_has_subantas_p(&khatva, Stri, Dvitiya, Eka, &["KawvAm"]); + assert_has_subantas_p(&khatva, Stri, Dvitiya, Dvi, &["Kawve"]); + assert_has_subantas_p(&khatva, Stri, Dvitiya, Bahu, &["KawvAH"]); + assert_has_subantas_p(&khatva, Stri, Trtiya, Eka, &["KawvayA"]); + assert_has_subantas_p(&khatva, Stri, Trtiya, Dvi, &["KawvAByAm"]); + assert_has_subantas_p(&khatva, Stri, Trtiya, Bahu, &["KawvABiH"]); + assert_has_subantas_p(&khatva, Stri, Caturthi, Eka, &["KawvAyE"]); + assert_has_subantas_p(&khatva, Stri, Caturthi, Dvi, &["KawvAByAm"]); + assert_has_subantas_p(&khatva, Stri, Caturthi, Bahu, &["KawvAByaH"]); + assert_has_subantas_p(&khatva, Stri, Panchami, Eka, &["KawvAyAH"]); + assert_has_subantas_p(&khatva, Stri, Panchami, Dvi, &["KawvAByAm"]); + assert_has_subantas_p(&khatva, Stri, Panchami, Bahu, &["KawvAByaH"]); + assert_has_subantas_p(&khatva, Stri, Sasthi, Eka, &["KawvAyAH"]); + assert_has_subantas_p(&khatva, Stri, Sasthi, Dvi, &["KawvayoH"]); + assert_has_subantas_p(&khatva, Stri, Sasthi, Bahu, &["KawvAnAm"]); + assert_has_subantas_p(&khatva, Stri, Saptami, Eka, &["KawvAyAm"]); + assert_has_subantas_p(&khatva, Stri, Saptami, Dvi, &["KawvayoH"]); + assert_has_subantas_p(&khatva, Stri, Saptami, Bahu, &["KawvAsu"]); + + // qAp + let bahuraja = Pratipadika::builder() + .text("bahurAjA") + .is_nyap(true) + .build() + .unwrap(); + assert_has_subantas_p(&bahuraja, Stri, Prathama, Eka, &["bahurAjA"]); + assert_has_subantas_p(&bahuraja, Stri, Prathama, Dvi, &["bahurAje"]); + assert_has_subantas_p(&bahuraja, Stri, Prathama, Bahu, &["bahurAjAH"]); + assert_has_subantas_p(&bahuraja, Stri, Dvitiya, Eka, &["bahurAjAm"]); + assert_has_subantas_p(&bahuraja, Stri, Dvitiya, Dvi, &["bahurAje"]); + assert_has_subantas_p(&bahuraja, Stri, Dvitiya, Bahu, &["bahurAjAH"]); + assert_has_subantas_p(&bahuraja, Stri, Trtiya, Eka, &["bahurAjayA"]); + assert_has_subantas_p(&bahuraja, Stri, Trtiya, Dvi, &["bahurAjAByAm"]); + assert_has_subantas_p(&bahuraja, Stri, Trtiya, Bahu, &["bahurAjABiH"]); + assert_has_subantas_p(&bahuraja, Stri, Caturthi, Eka, &["bahurAjAyE"]); + assert_has_subantas_p(&bahuraja, Stri, Caturthi, Dvi, &["bahurAjAByAm"]); + assert_has_subantas_p(&bahuraja, Stri, Caturthi, Bahu, &["bahurAjAByaH"]); + assert_has_subantas_p(&bahuraja, Stri, Panchami, Eka, &["bahurAjAyAH"]); + assert_has_subantas_p(&bahuraja, Stri, Panchami, Dvi, &["bahurAjAByAm"]); + assert_has_subantas_p(&bahuraja, Stri, Panchami, Bahu, &["bahurAjAByaH"]); + assert_has_subantas_p(&bahuraja, Stri, Sasthi, Eka, &["bahurAjAyAH"]); + assert_has_subantas_p(&bahuraja, Stri, Sasthi, Dvi, &["bahurAjayoH"]); + assert_has_subantas_p(&bahuraja, Stri, Sasthi, Bahu, &["bahurAjAnAm"]); + assert_has_subantas_p(&bahuraja, Stri, Saptami, Eka, &["bahurAjAyAm"]); + assert_has_subantas_p(&bahuraja, Stri, Saptami, Dvi, &["bahurAjayoH"]); + assert_has_subantas_p(&bahuraja, Stri, Saptami, Bahu, &["bahurAjAsu"]); + + // cAp + let karishagandhya = Pratipadika::builder() + .text("kArIzaganDyA") + .is_nyap(true) + .build() + .unwrap(); + assert_has_subantas_p(&karishagandhya, Stri, Prathama, Eka, &["kArIzaganDyA"]); + assert_has_subantas_p(&karishagandhya, Stri, Prathama, Dvi, &["kArIzaganDye"]); + assert_has_subantas_p(&karishagandhya, Stri, Prathama, Bahu, &["kArIzaganDyAH"]); + assert_has_subantas_p(&karishagandhya, Stri, Dvitiya, Eka, &["kArIzaganDyAm"]); + assert_has_subantas_p(&karishagandhya, Stri, Dvitiya, Dvi, &["kArIzaganDye"]); + assert_has_subantas_p(&karishagandhya, Stri, Dvitiya, Bahu, &["kArIzaganDyAH"]); + assert_has_subantas_p(&karishagandhya, Stri, Trtiya, Eka, &["kArIzaganDyayA"]); + assert_has_subantas_p(&karishagandhya, Stri, Trtiya, Dvi, &["kArIzaganDyAByAm"]); + assert_has_subantas_p(&karishagandhya, Stri, Trtiya, Bahu, &["kArIzaganDyABiH"]); + assert_has_subantas_p(&karishagandhya, Stri, Caturthi, Eka, &["kArIzaganDyAyE"]); + assert_has_subantas_p(&karishagandhya, Stri, Caturthi, Dvi, &["kArIzaganDyAByAm"]); + assert_has_subantas_p(&karishagandhya, Stri, Caturthi, Bahu, &["kArIzaganDyAByaH"]); + assert_has_subantas_p(&karishagandhya, Stri, Panchami, Eka, &["kArIzaganDyAyAH"]); + assert_has_subantas_p(&karishagandhya, Stri, Panchami, Dvi, &["kArIzaganDyAByAm"]); + assert_has_subantas_p(&karishagandhya, Stri, Panchami, Bahu, &["kArIzaganDyAByaH"]); + assert_has_subantas_p(&karishagandhya, Stri, Sasthi, Eka, &["kArIzaganDyAyAH"]); + assert_has_subantas_p(&karishagandhya, Stri, Sasthi, Dvi, &["kArIzaganDyayoH"]); + assert_has_subantas_p(&karishagandhya, Stri, Sasthi, Bahu, &["kArIzaganDyAnAm"]); + assert_has_subantas_p(&karishagandhya, Stri, Saptami, Eka, &["kArIzaganDyAyAm"]); + assert_has_subantas_p(&karishagandhya, Stri, Saptami, Dvi, &["kArIzaganDyayoH"]); + assert_has_subantas_p(&karishagandhya, Stri, Saptami, Bahu, &["kArIzaganDyAsu"]); + + let drshad = Pratipadika::new("dfzad"); + assert_has_subantas_p(&drshad, Pum, Prathama, Eka, &["dfzat"]); + assert_has_subantas_p(&drshad, Pum, Prathama, Dvi, &["dfzadO"]); + assert_has_subantas_p(&drshad, Pum, Prathama, Bahu, &["dfzadaH"]); + assert_has_subantas_p(&drshad, Pum, Dvitiya, Eka, &["dfzadam"]); + assert_has_subantas_p(&drshad, Pum, Dvitiya, Dvi, &["dfzadO"]); + assert_has_subantas_p(&drshad, Pum, Dvitiya, Bahu, &["dfzadaH"]); + assert_has_subantas_p(&drshad, Pum, Trtiya, Eka, &["dfzadA"]); + assert_has_subantas_p(&drshad, Pum, Trtiya, Dvi, &["dfzadByAm"]); + assert_has_subantas_p(&drshad, Pum, Trtiya, Bahu, &["dfzadBiH"]); + assert_has_subantas_p(&drshad, Pum, Caturthi, Eka, &["dfzade"]); + assert_has_subantas_p(&drshad, Pum, Caturthi, Dvi, &["dfzadByAm"]); + assert_has_subantas_p(&drshad, Pum, Caturthi, Bahu, &["dfzadByaH"]); + assert_has_subantas_p(&drshad, Pum, Panchami, Eka, &["dfzadaH"]); + assert_has_subantas_p(&drshad, Pum, Panchami, Dvi, &["dfzadByAm"]); + assert_has_subantas_p(&drshad, Pum, Panchami, Bahu, &["dfzadByaH"]); + assert_has_subantas_p(&drshad, Pum, Sasthi, Eka, &["dfzadaH"]); + assert_has_subantas_p(&drshad, Pum, Sasthi, Dvi, &["dfzadoH"]); + assert_has_subantas_p(&drshad, Pum, Sasthi, Bahu, &["dfzadAm"]); + assert_has_subantas_p(&drshad, Pum, Saptami, Eka, &["dfzadi"]); + assert_has_subantas_p(&drshad, Pum, Saptami, Dvi, &["dfzadoH"]); + assert_has_subantas_p(&drshad, Pum, Saptami, Bahu, &["dfzatsu"]); +} + #[test] fn sutra_4_1_4() { assert_has_stri("aja", &["ajA"]); @@ -98,8 +288,185 @@ fn sutra_4_1_49() { // TODO: others; } +#[test] +fn sutra_4_1_98() { + assert_has_taddhitanta(&prati("kuYja"), T::cPaY, &["kOYjAyana"]); + assert_has_taddhitanta(&prati("braDna"), T::cPaY, &["brADnAyana"]); + // gotre? + assert_has_taddhitanta(&prati("kuYja"), T::iY, &["kOYji"]); +} + +#[test] +fn sutra_4_1_105() { + assert_has_taddhitanta(&prati("garga"), T::yaY, &["gArgya"]); + assert_has_taddhitanta(&prati("vatsa"), T::yaY, &["vAtsya"]); +} + +#[test] +fn sutra_4_1_106() { + assert_has_taddhitanta(&prati("maDu"), T::yaY, &["mADavya"]); + assert_has_taddhitanta(&prati("maDu"), T::aR, &["mADava"]); + assert_has_taddhitanta(&prati("baBru"), T::yaY, &["bABravya"]); + assert_has_taddhitanta(&prati("baBru"), T::aR, &["bABrava"]); + // TODO: bABravyAyaRI +} + +#[test] +fn sutra_4_1_107() { + assert_has_taddhitanta(&prati("kapi"), T::yaY, &["kApya"]); + assert_has_taddhitanta(&prati("boDa"), T::yaY, &["bODya"]); + // ANgirase + assert_has_taddhitanta(&prati("kapi"), T::Qak, &["kApeya"]); + assert_has_taddhitanta(&prati("boDa"), T::iY, &["bODi"]); + // TODO: kApyAyanI +} + +#[test] +fn sutra_4_1_108() { + assert_has_taddhitanta(&prati("vataRqa"), T::yaY, &["vAtaRqya"]); + assert_has_taddhitanta(&prati("vataRqa"), T::aR, &["vAtaRqa"]); +} + +#[test] +fn sutra_4_1_110() { + assert_has_taddhitanta(&prati("aSva"), T::PaY, &["ASvAyana"]); + assert_has_taddhitanta(&prati("aSman"), T::PaY, &["ASmAyana"]); +} + +#[test] +fn sutra_4_1_111() { + assert_has_taddhitanta(&prati("Barga"), T::PaY, &["BArgAyaRa"]); + assert_has_taddhitanta(&prati("Barga"), T::iY, &["BArgi"]); +} + +#[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"]); +} + +#[test] +fn sutra_4_1_121() { + assert_has_taddhitanta(&nyap("dattA"), T::Qak, &["dAtteya"]); + assert_has_taddhitanta(&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"]); +} + +#[test] +fn sutra_4_1_122() { + assert_has_taddhitanta(&prati("atri"), T::Qak, &["Atreya"]); + assert_has_taddhitanta(&prati("niDi"), T::Qak, &["nEDeya"]); + // itaH? + assert_has_taddhitanta(&prati("dakza"), T::Qak, &[]); + assert_has_taddhitanta(&prati("dakza"), T::iY, &["dAkzi"]); + assert_has_taddhitanta(&prati("plakza"), T::Qak, &[]); + assert_has_taddhitanta(&prati("plakza"), T::iY, &["plAkzi"]); + // TODO: an-iYaH + // dvi-acaH? + assert_has_taddhitanta(&prati("marIci"), T::Qak, &[]); + assert_has_taddhitanta(&prati("marIci"), T::aR, &["mArIca"]); +} + +#[test] +fn sutra_4_1_123() { + assert_has_taddhitanta(&prati("SuBra"), T::Qak, &["SOBreya"]); + assert_has_taddhitanta(&prati("vizwapura"), T::Qak, &["vEzwapureya"]); +} + +#[test] +fn sutra_4_1_124() { + assert_has_taddhitanta(&prati("vikarRa"), T::Qak, &["vEkarReya"]); + assert_has_taddhitanta(&prati("kuzItaka"), T::Qak, &["kOzItakeya"]); + assert_has_taddhitanta(&prati("vikarRa"), T::iY, &["vEkarRi"]); + assert_has_taddhitanta(&prati("kuzItaka"), T::iY, &["kOzItaki"]); +} + +#[ignore] +#[test] +fn sutra_4_1_125() { + assert_has_taddhitanta(&prati("BrU"), T::Qak, &["BrOveya"]); +} + +#[ignore] +#[test] +fn sutra_4_1_126() { + assert_has_taddhitanta(&prati("kalyARI"), T::Qak, &["kalyARineya"]); + assert_has_taddhitanta(&prati("suBagA"), T::Qak, &["sOBAgineya"]); + assert_has_taddhitanta(&prati("durBagA"), T::Qak, &["dOrBAgineya"]); +} + +#[ignore] +#[test] +fn sutra_4_1_127() { + assert_has_taddhitanta(&nyap("kulawA"), T::Qak, &["kOlawineya", "kOlaweya"]); + // TODO: Qrak +} + +#[test] +fn sutra_4_1_128() { + assert_has_taddhitanta(&prati("cawakA"), T::Erak, &["cAwakEra"]); +} + +#[test] +fn sutra_4_1_128_v1() { + assert_has_taddhitanta(&prati("cawaka"), T::Erak, &["cAwakEra"]); +} + +#[test] +fn sutra_4_1_129() { + assert_has_taddhitanta(&prati("goDA"), T::Qrak, &["gODera"]); +} + +#[test] +fn sutra_4_1_130() { + assert_has_taddhitanta(&prati("goDA"), T::Arak, &["gODAra"]); +} + +#[test] +fn sutra_4_1_132() { + assert_has_taddhitanta(&prati("pitfzvasf"), T::CaR, &["pEtfzvasrIya"]); +} + +#[test] +fn sutra_4_1_133() { + assert_has_taddhitanta(&prati("pitfzvasf"), T::Qak, &["pEtfzvaseya"]); +} + +#[test] +fn sutra_4_1_134() { + assert_has_taddhitanta(&prati("mAtfzvasf"), T::CaR, &["mAtfzvasrIya"]); + assert_has_taddhitanta(&prati("mAtfzvasf"), T::Qak, &["mAtfzvaseya"]); +} + +#[test] +fn sutra_4_1_136() { + assert_has_taddhitanta(&prati("gfzwi"), T::QaY, &["gArzweya"]); + assert_has_taddhitanta(&prati("hfzwi"), T::QaY, &["hArzweya"]); +} + +#[ignore] +#[test] +fn sutra_4_1_137() { + assert_has_taddhitanta(&prati("rAjan"), T::yat, &["rAjanya"]); + assert_has_taddhitanta(&prati("SvaSura"), T::yat, &["SvaSurya"]); +} + +#[test] +fn sutra_4_1_138() { + assert_has_taddhitanta(&prati("kzatra"), T::Ga, &["kzatriya"]); +} + +#[test] +fn sutra_4_1_139() { + assert_has_taddhitanta(&prati("kula"), T::Ka, &["kulIna"]); +} + #[test] fn sutra_4_1_146() { - assert_has_taddhitanta(&prati("revatI"), Taddhita::Wak, &["rEvatika"]); - assert_has_taddhitanta(&prati("aSvapAlI"), Taddhita::Wak, &["ASvapAlika"]); + assert_has_taddhitanta(&prati("revatI"), T::Wak, &["rEvatika"]); + assert_has_taddhitanta(&prati("aSvapAlI"), T::Wak, &["ASvapAlika"]); } diff --git a/vidyut-prakriya/tests/pada_4_4.rs b/vidyut-prakriya/tests/pada_4_4.rs new file mode 100644 index 0000000..045de1a --- /dev/null +++ b/vidyut-prakriya/tests/pada_4_4.rs @@ -0,0 +1,24 @@ +extern crate test_utils; +use test_utils::*; +use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Taddhita as T; +use vidyut_prakriya::args::*; + +#[test] +fn sutra_4_4_20() { + assert_has_krdanta(&[], &d("qupa\\ca~^z", Bhvadi), Krt::ktri, &["paktrima"]); + assert_has_krdanta(&[], &d("quva\\pa~^", Bhvadi), Krt::ktri, &["uptrima"]); + assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::ktri, &["kftrima"]); +} + +#[test] +fn sutra_4_4_52() { + assert_has_taddhitanta(&prati("lavaRa"), T::WaY, &["lAvaRika"]); +} + +#[test] +fn sutra_4_4_53() { + // TODO: strI-linga + assert_has_taddhitanta(&prati("kiSara"), T::zWan, &["kiSarika"]); + assert_has_taddhitanta(&prati("narada"), T::zWan, &["naradika"]); +} diff --git a/vidyut-prakriya/tests/pada_5_1.rs b/vidyut-prakriya/tests/pada_5_1.rs index a7b03ab..6895778 100644 --- a/vidyut-prakriya/tests/pada_5_1.rs +++ b/vidyut-prakriya/tests/pada_5_1.rs @@ -1,10 +1,30 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Taddhita as T; -use vidyut_prakriya::args::*; -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +#[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"]); + // TODO: others +} + +#[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"]); + // a-ti-Sat + assert_has_taddhitanta(&prati("saptati"), T::WaY, &["sAptatika"]); + assert_has_taddhitanta(&prati("catvAriMSat"), T::WaY, &["cAtvAriMSatka"]); +} + +#[test] +fn sutra_5_1_106() { + assert_has_taddhitanta(&prati("ftu"), T::Gas, &["ftviya"]); } #[test] @@ -14,3 +34,11 @@ fn sutra_5_1_119() { assert_has_taddhitanta(&prati("go"), T::tva, &["gotva"]); assert_has_taddhitanta(&prati("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"]); +} diff --git a/vidyut-prakriya/tests/pada_5_2.rs b/vidyut-prakriya/tests/pada_5_2.rs index cae62d3..a18b5bd 100644 --- a/vidyut-prakriya/tests/pada_5_2.rs +++ b/vidyut-prakriya/tests/pada_5_2.rs @@ -1,10 +1,26 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Taddhita as T; -use vidyut_prakriya::args::*; -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +#[ignore] +#[test] +fn sutra_5_2_1() { + assert_has_taddhitanta(&prati("mudra"), T::KaY, &["mOdrIna"]); + assert_has_taddhitanta(&prati("kudrava"), T::KaY, &["kOdravIna"]); + assert_has_taddhitanta(&prati("kulatTa"), T::KaY, &["kOlatTIna"]); +} + +#[test] +fn sutra_5_2_2() { + assert_has_taddhitanta(&prati("vrIhi"), T::Qak, &["vrEheya"]); + assert_has_taddhitanta(&prati("SAli"), T::Qak, &["SAleya"]); +} + +#[test] +fn sutra_5_2_3() { + assert_has_taddhitanta(&prati("yava"), T::yat, &["yavya"]); + assert_has_taddhitanta(&prati("yavaka"), T::yat, &["yavakya"]); + assert_has_taddhitanta(&prati("zazwika"), T::yat, &["zazwikya"]); } #[test] @@ -15,6 +31,27 @@ fn sutra_5_2_94() { assert_has_taddhitanta(&prati("plakza"), T::matup, &["plakzavat"]); } +#[test] +fn sutra_5_2_96() { + assert_has_taddhitanta(&prati("cUqA"), T::lac, &["cUqAla"]); + assert_has_taddhitanta(&prati("cUqA"), T::matup, &["cUqAvat"]); + // AtaH + assert_has_taddhitanta(&prati("hasta"), T::matup, &["hastavat"]); + assert_has_taddhitanta(&prati("pAda"), T::matup, &["pAdavat"]); +} + +#[test] +fn sutra_5_2_100() { + assert_has_taddhitanta(&prati("loman"), T::Sa, &["lomaSa"]); + assert_has_taddhitanta(&prati("loman"), T::matup, &["lomavat"]); + assert_has_taddhitanta(&prati("pAman"), T::na, &["pAmana"]); + assert_has_taddhitanta(&prati("pAman"), T::matup, &["pAmavat"]); + assert_has_taddhitanta(&prati("picCa"), T::ilac, &["picCila"]); + assert_has_taddhitanta(&prati("picCa"), T::matup, &["picCavat"]); + assert_has_taddhitanta(&prati("uras"), T::ilac, &["urasila"]); + assert_has_taddhitanta(&prati("uras"), T::matup, &["urasvat"]); +} + #[test] fn sutra_5_2_121() { assert_has_taddhitanta(&prati("yaSas"), T::vini, &["yaSasvin"]); diff --git a/vidyut-prakriya/tests/pada_5_3.rs b/vidyut-prakriya/tests/pada_5_3.rs index 7627d71..dbafb26 100644 --- a/vidyut-prakriya/tests/pada_5_3.rs +++ b/vidyut-prakriya/tests/pada_5_3.rs @@ -1,10 +1,11 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Taddhita as T; -use vidyut_prakriya::args::*; -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +#[ignore] +#[test] +fn sutra_5_3_3() { + assert_has_taddhitanta(&prati("idam"), T::ha, &["iha"]); } #[ignore] @@ -107,3 +108,52 @@ fn sutra_5_3_24() { fn sutra_5_3_25() { assert_has_taddhitanta(&prati("tad"), T::TAl, &["taTA"]); } + +#[test] +fn sutra_5_3_42() { + assert_has_taddhitanta(&prati("eka"), T::DA, &["ekaDA"]); + assert_has_taddhitanta(&prati("dvi"), T::DA, &["dviDA"]); + assert_has_taddhitanta(&prati("tri"), T::DA, &["triDA"]); + assert_has_taddhitanta(&prati("catur"), T::DA, &["caturDA"]); + assert_has_taddhitanta(&prati("paYcan"), T::DA, &["paYcaDA"]); +} + +#[test] +fn sutra_5_3_55() { + assert_has_taddhitanta(&prati("AQya"), T::tamap, &["AQyatama"]); + assert_has_taddhitanta(&prati("darSanIya"), T::tamap, &["darSanIyatama"]); + assert_has_taddhitanta(&prati("sukumAra"), T::tamap, &["sukumAratama"]); + assert_has_taddhitanta(&prati("pawu"), T::izWan, &["pawizWa"]); + assert_has_taddhitanta(&prati("laGu"), T::izWan, &["laGizWa"]); + assert_has_taddhitanta(&prati("guru"), T::izWan, &["garizWa"]); + assert_has_taddhitanta(&prati("SrezWa"), T::tamap, &["SrezWatama"]); +} + +#[test] +fn sutra_5_3_57() { + assert_has_taddhitanta(&prati("AQya"), T::tarap, &["AQyatara"]); + assert_has_taddhitanta(&prati("sukumAra"), T::tarap, &["sukumAratara"]); + assert_has_taddhitanta(&prati("pawu"), T::Iyasun, &["pawIyas"]); + // TODO: others +} + +#[test] +fn sutra_5_3_66() { + assert_has_taddhitanta(&prati("vEyAkaraRa"), T::rUpap, &["vEyAkaraRarUpa"]); + assert_has_taddhitanta(&prati("yAjYika"), T::rUpap, &["yAjYikarUpa"]); + assert_has_taddhitanta(&prati("cora"), T::rUpap, &["corarUpa"]); + assert_has_taddhitanta(&prati("dasyu"), T::rUpap, &["dasyurUpa"]); + // TODO: pacatirUpam, etc. +} + +#[test] +fn sutra_5_3_67() { + assert_has_taddhitanta(&prati("pawu"), T::kalpap, &["pawukalpa"]); + assert_has_taddhitanta(&prati("pawu"), T::deSya, &["pawudeSya"]); + assert_has_taddhitanta(&prati("pawu"), T::deSIyar, &["pawudeSIya"]); + + assert_has_taddhitanta(&prati("mfdu"), T::kalpap, &["mfdukalpa"]); + assert_has_taddhitanta(&prati("mfdu"), T::deSya, &["mfdudeSya"]); + assert_has_taddhitanta(&prati("mfdu"), T::deSIyar, &["mfdudeSIya"]); + // TODO: pacatikalpam, etc. +} diff --git a/vidyut-prakriya/tests/pada_5_4.rs b/vidyut-prakriya/tests/pada_5_4.rs new file mode 100644 index 0000000..31d184c --- /dev/null +++ b/vidyut-prakriya/tests/pada_5_4.rs @@ -0,0 +1,92 @@ +extern crate test_utils; +use test_utils::*; +use vidyut_prakriya::args::Taddhita as T; + +#[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"]); +} + +#[test] +fn sutra_5_4_3_v1() { + assert_has_taddhitanta(&prati("caYcut"), T::kan, &["caYcutka"]); + assert_has_taddhitanta(&prati("bfhat"), T::kan, &["bfhatka"]); +} + +#[test] +fn sutra_5_4_17() { + assert_has_taddhitanta(&prati("paYcan"), T::kftvasuc, &["paYcakftvas"]); + assert_has_taddhitanta(&prati("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, &[]); +} + +#[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"]); +} + +#[ignore] +#[test] +fn sutra_5_4_19() { + assert_has_taddhitanta(&prati("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"]); +} + +#[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"]); +} + +#[test] +fn sutra_5_4_26() { + assert_has_taddhitanta(&prati("atiTi"), T::Yya, &["AtiTya"]); +} + +#[test] +fn sutra_5_4_27() { + assert_has_taddhitanta(&prati("deva"), T::tal, &["devatA"]); +} + +#[ignore] +#[test] +fn sutra_5_4_39() { + assert_has_taddhitanta(&prati("mft"), T::tikan, &["mfttikA"]); +} + +#[test] +fn sutra_5_4_44() { + assert_has_taddhitanta(&prati("vAsudeva"), T::tasi, &["vAsudevatas"]); + assert_has_taddhitanta(&prati("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"]); +} + +#[test] +fn sutra_5_4_54() { + assert_has_taddhitanta(&prati("agni"), T::sAti, &["agnisAt"]); + assert_has_taddhitanta(&prati("udaka"), T::sAti, &["udakasAt"]); +} diff --git a/vidyut-prakriya/tests/pada_6_1.rs b/vidyut-prakriya/tests/pada_6_1.rs index f8e76cb..7bf7651 100644 --- a/vidyut-prakriya/tests/pada_6_1.rs +++ b/vidyut-prakriya/tests/pada_6_1.rs @@ -8,14 +8,18 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } +fn nic_san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Nic, Sanadi::San]) +} + +fn san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::San]) +} + fn yan(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Yan]) } @@ -49,8 +53,22 @@ fn sutra_6_1_3() { // ndrA assert_has_lat(&[], &san("Ikza~\\", Bhvadi), &["Icikzizate"]); // saMyoga - assert_has_lat_p(&["pra"], &san("ana~", Adadi), &["prARiRizati"]); + assert_has_lat(&["pra"], &san("ana~", Adadi), &["prARiRizati"]); // ajAdi + assert_has_lat(&[], &san("drA\\", Adadi), &["didrAsati"]); + + // TODO: indidrIyizati +} + +#[ignore] +#[test] +fn sutra_6_1_3_v1() { + assert_has_lat(&[], &san(&d("ubja~", Tudadi)), &["ubjijizati"]); +} + +#[test] +fn sutra_6_1_3_v2() { + assert_has_lat(&[], &yan(&d("f\\", Bhvadi)), &["arAryate"]); } #[test] @@ -103,6 +121,11 @@ fn sutra_6_1_6() { assert_has_lat_3p(d("vevIN", Adadi), &["vevyate"]); } +#[test] +fn sutra_6_1_7() { + // TODO: no comprehensive list of tujAdi dhatus anywhere -- how to test? +} + #[test] fn sutra_6_1_8() { assert_has_lit_p(&[], &d("qupa\\ca~^z", Bhvadi), &["papAca"]); @@ -111,7 +134,8 @@ fn sutra_6_1_8() { // liwi assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::tfc, &["kartf"]); assert_has_krdanta(&[], &d("hf\\Y", Bhvadi), Krt::tfc, &["hartf"]); - // TODO: nonAva + // TODO: nonAva (amantra) + // assert_has_lit_p(&[], &yan_luk(&d("nu", Adadi)), &["nonAva"]); } #[test] @@ -143,6 +167,7 @@ fn sutra_6_1_10() { assert_has_lat_p(&[], &d("YiBI\\", Juhotyadi), &["biBeti"]); assert_has_lat_p(&[], &d("hrI\\", Juhotyadi), &["jihreti"]); } + #[test] fn sutra_6_1_11() { let nic = |u, g| d(u, g).with_sanadi(&[Sanadi::Nic]); @@ -200,6 +225,123 @@ fn sutra_6_1_15() { assert_has_krdanta(&[], &svi, Krt::ktavatu, &["SUnavat"]); } +#[test] +fn sutra_6_1_16() { + let grah = d("graha~^", Kryadi); + assert_has_krdanta(&[], &grah, Krt::kta, &["gfhIta"]); + assert_has_krdanta(&[], &grah, Krt::ktavatu, &["gfhItavat"]); + assert_has_lat_p(&[], &grah, &["gfhRAti"]); + assert_has_lat_a(&[], &yan(&grah), &["jarIgfhyate"]); + + let jya = d("jyA\\", Kryadi); + assert_has_krdanta(&[], &jya, Krt::kta, &["jIna"]); + assert_has_krdanta(&[], &jya, Krt::ktavatu, &["jInavat"]); + assert_has_lat_p(&[], &jya, &["jinAti"]); + assert_has_lat_a(&[], &yan(&jya), &["jejIyate"]); + + let ve = d("ve\\Y", Bhvadi); + assert_has_parasmai_tinanta( + &[], + &ve, + Lit, + Prathama, + Dvi, + &["UyatuH", "UvatuH", "vavatuH"], + ); + assert_has_parasmai_tinanta(&[], &ve, Lit, Prathama, Bahu, &["UyuH", "UvuH", "vavuH"]); + + let vyadh = d("vya\\Da~", Divadi); + assert_has_krdanta(&[], &vyadh, Krt::kta, &["vidDa"]); + assert_has_krdanta(&[], &vyadh, Krt::ktavatu, &["vidDavat"]); + assert_has_lat_p(&[], &vyadh, &["viDyati"]); + assert_has_lat_a(&[], &yan(&vyadh), &["veviDyate"]); + + let vash = d("vaSa~", Adadi); + assert_has_krdanta(&[], &vash, Krt::kta, &["uSita"]); + assert_has_krdanta(&[], &vash, Krt::ktavatu, &["uSitavat"]); + assert_has_parasmai_tinanta(&[], &vash, Lat, Prathama, Dvi, &["uzwaH"]); + assert_has_parasmai_tinanta(&[], &vash, Lat, Prathama, Bahu, &["uSanti"]); + + let vyac = d("vyaca~", Tudadi); + assert_has_krdanta(&[], &vyac, Krt::kta, &["vicita"]); + assert_has_krdanta(&[], &vyac, Krt::ktavatu, &["vicitavat"]); + assert_has_lat_p(&[], &vyac, &["vicati"]); + assert_has_lat_a(&[], &yan(&vyac), &["vevicyate"]); + assert_has_krdanta(&["ud"], &vyac, Krt::tfc, &["udvicitf"]); + assert_has_krdanta(&["ud"], &vyac, Krt::tumun, &["udvicitum"]); + assert_has_krdanta(&["ud"], &vyac, Krt::tavya, &["udvicitavya"]); + + let vrasc = d("o~vrascU~", Tudadi); + assert_has_krdanta(&[], &vrasc, Krt::kta, &["vfkRa"]); + assert_has_krdanta(&[], &vrasc, Krt::ktavatu, &["vfkRavat"]); + assert_has_lat_p(&[], &vrasc, &["vfScati"]); + assert_has_lat_a(&[], &yan(&vrasc), &["varIvfScyate"]); + + let prach = d("pra\\Ca~", Tudadi); + assert_has_krdanta(&[], &prach, Krt::kta, &["pfzwa"]); + assert_has_krdanta(&[], &prach, Krt::ktavatu, &["pfzwavat"]); + assert_has_lat_p(&[], &prach, &["pfcCati"]); + assert_has_lat_a(&[], &yan(&prach), &["parIpfcCyate"]); + assert_has_krdanta(&[], &prach, Krt::naN, &["praSna"]); + + let bhrasj = d("Bra\\sja~^", Tudadi); + assert_has_krdanta(&[], &bhrasj, Krt::kta, &["Bfzwa"]); + assert_has_krdanta(&[], &bhrasj, Krt::ktavatu, &["Bfzwavat"]); + assert_has_lat_p(&[], &bhrasj, &["Bfjjati"]); + assert_has_lat_a(&[], &yan(&bhrasj), &["barIBfjjyate"]); +} + +#[ignore] +#[test] +fn sutra_6_1_17() { + let assert_has_nal = |x, y, z| assert_has_tip(x, y, Lit, z); + let assert_has_thal = |x, y, z| assert_has_sip(x, y, Lit, z); + + let vac = d("va\\ca~", Adadi); + assert_has_nal(&[], &vac, &["uvAca"]); + assert_has_thal(&[], &vac, &["uvaciTa", "uvakTa"]); + + let svap = d("Yizva\\pa~", Adadi); + assert_has_nal(&[], &svap, &["suzvApa"]); + assert_has_thal(&[], &svap, &["suzvapiTa", "suzvapTa"]); + + let yaj = d("ya\\ja~^", Bhvadi); + assert_has_nal(&[], &yaj, &["iyAja"]); + assert_has_thal(&[], &yaj, &["iyajiTa", "iyazWa"]); + + let vap = d("quva\\pa~^", Bhvadi); + assert_has_nal(&[], &vap, &["uvApa"]); + assert_has_thal(&[], &vap, &["uvapiTa", "uvapTa"]); + + let grah = d("graha~^", Kryadi); + assert_has_nal(&[], &grah, &["jagrAha"]); + assert_has_thal(&[], &grah, &["jagrahiTa"]); + + let jya = d("jyA\\", Kryadi); + assert_has_nal(&[], &jya, &["jijyO"]); + assert_has_thal(&[], &jya, &["jijyiTa"]); + + let vye = d("vye\\Y", Bhvadi); + assert_has_nal(&[], &vye, &["uvAya"]); + assert_has_thal(&[], &vye, &["uvayiTa"]); + + let vyadh = d("vya\\Da~", Divadi); + assert_has_nal(&[], &vyadh, &["vivyADa"]); + assert_has_thal(&[], &vyadh, &["vivyaDiTa"]); + + let vash = d("vaSa~", Adadi); + assert_has_nal(&[], &vash, &["uvASa"]); + assert_has_thal(&[], &vash, &["uvaSiTa"]); + + let vyac = d("vyaca~", Tudadi); + assert_has_nal(&[], &vyac, &["vivyAca"]); + assert_has_thal(&[], &vyac, &["vivyaciTa"]); + + let vrasc = d("o~vrascU~", Tudadi); + assert_has_nal(&[], &vrasc, &["vavraSca"]); + assert_has_thal(&[], &vrasc, &["vavraSciTa"]); +} + #[test] fn sutra_6_1_18() { let svap_nic = d("Yizva\\pa~", Adadi).with_sanadi(&[Sanadi::Nic]); @@ -217,10 +359,10 @@ fn sutra_6_1_19() { let svap = d("Yizva\\pa~", Adadi); let syam = d("syamu~", Bhvadi); - let ve = d("vye\\Y", Bhvadi); + let vye = d("vye\\Y", Bhvadi); assert_has_lat(&[], &yan(&svap), &["sozupyate"]); assert_has_lat(&[], &yan(&syam), &["sesimyate"]); - assert_has_lat(&[], &yan(&ve), &["vevIyate"]); + assert_has_lat(&[], &yan(&vye), &["vevIyate"]); // yaNi assert_has_krdanta(&[], &svap, Krt::najiN, &["svapnaj"]); } @@ -274,6 +416,12 @@ fn sutra_6_1_23() { ); } +#[test] +fn sutra_6_1_28() { + let pyay = d("o~pyAyI~\\", Bhvadi); + assert_has_krdanta(&[], &pyay, Krt::kta, &["pIna"]); +} + #[test] fn sutra_6_1_29() { let pyay = d("o~pyAyI~\\", Bhvadi); @@ -294,6 +442,14 @@ fn sutra_6_1_30() { assert_has_lat(&[], &yan(&svi), &["SoSUyate", "SeSvIyate"]); } +#[ignore] +#[test] +fn sutra_6_1_31() { + let svi = d("wuo~Svi", Bhvadi); + assert_has_lat_p(&[], &nic_san(&svi), &["SuSAvayizati"]); + assert_has_lat_p(&[], &nic(&svi), &["aSUsavat", "aSiSvayat"]); +} + #[test] fn sutra_6_1_38_and_sutra_6_1_39_and_sutra_6_1_40() { let ve = d("ve\\Y", Bhvadi); @@ -444,10 +600,10 @@ fn sutra_6_1_55() { #[test] fn sutra_6_1_56() { - assert_has_lat_a( + assert_has_lat( &[], &nic(&d("YiBI\\", Juhotyadi)), - &["BIzayate", "BApayate"], + &["BAyayati", "BAyayate", "BIzayate", "BApayate"], ); } @@ -457,7 +613,7 @@ fn sutra_6_1_57() { assert_has_lat( &["vi"], &nic(&d("zmi\\N", Bhvadi)), - &["vismApayate", "vismAyayati"], + &["vismAyayati", "vismAyayate", "vismApayate"], ); } @@ -505,6 +661,65 @@ fn sutra_6_1_59() { assert_has_krdanta(&[], &dfp, Krt::kta, &["dfpta"]); } +#[test] +fn sutra_6_1_64() { + use Vibhakti::*; + assert_has_lat(&[], &d("zaha~\\", Bhvadi), &["sahate"]); + assert_has_lat_p(&[], &d("zi\\ca~^", Tudadi), &["siYcati"]); + // DAtu? + // assert_has_subantas("zoqaSan", Pum, Prathama, Bahu, &["zoqaSa"]); + assert_has_subantas("zaRqa", Pum, Prathama, Eka, &["zaRqaH"]); + assert_has_subantas("zaqika", Pum, Prathama, Eka, &["zaqikaH"]); + // AdeH? + assert_has_lat(&[], &d("kaza~", Bhvadi), &["kazati"]); + assert_has_lat_p(&[], &d("laza~^", Bhvadi), &["lazati", "lazyati"]); + assert_has_lat(&[], &d("kf\\za~", Tudadi), &["kfzati"]); + assert_has_lat(&[], &d("zWivu~", Bhvadi), &["zWIvati"]); + assert_has_lat(&[], &d("zvazka~\\", Bhvadi), &["zvazkate"]); + assert_has_lat(&[], &yan(&d("zWivu~", Divadi)), &["wezWIvyate"]); + // TODO: others +} + +#[test] +fn sutra_6_1_65() { + assert_has_lat_p(&[], &d("RI\\Y", Bhvadi), &["nayati"]); + assert_has_lat_p(&[], &d("Ra\\ma~", Bhvadi), &["namati"]); + assert_has_lat_p(&[], &d("Ra\\ha~^", Divadi), &["nahyati"]); + // dhAtu-AdeH + assert_has_lat_p(&[], &d("aRa~", Bhvadi), &["aRati"]); + // TODO: others +} + +#[test] +fn sutra_6_1_66() { + assert_has_krdanta(&[], &d("divu~", Divadi), Krt::kvasu, &["didivas"]); + assert_has_krdanta(&[], &d("UyI~\\", Bhvadi), Krt::kta, &["Uta"]); + assert_has_krdanta(&[], &d("knUyI~\\", Bhvadi), Krt::kta, &["knUta"]); + + // TODO: gODera + assert_has_jha(&[], &d("qupa\\ca~^z", Bhvadi), VidhiLin, &["paceran"]); + assert_has_jha(&[], &d("ya\\ja~^", Bhvadi), VidhiLin, &["yajeran"]); + + // vali? + assert_has_lat_karmani(&[], &d("UyI~\\", Bhvadi), &["Uyyate"]); + assert_has_lat_karmani(&[], &d("knUyI~\\", Bhvadi), &["knUyyate"]); + + // TODO: others +} + +#[test] +fn sutra_6_1_69() { + // eN + assert_has_subantas("agni", Pum, V::Sambodhana, Eka, &["agne"]); + assert_has_subantas("vAyu", Pum, V::Sambodhana, Eka, &["vAyo"]); + // hrasva + assert_has_subantas("devadatta", Pum, V::Sambodhana, Eka, &["devadatta"]); + assert_has_subantas("nadI", Stri, V::Sambodhana, Eka, &["nadi"]); + assert_has_subantas("vaDU", Stri, V::Sambodhana, Eka, &["vaDu"]); + assert_has_subantas("kuRqa", Napumsaka, V::Sambodhana, Eka, &["kuRqa"]); + assert_has_subantas("katarat", Napumsaka, V::Sambodhana, Eka, &["katarat"]); +} + // saMhitAyAm ... #[test] @@ -576,8 +791,8 @@ fn sutra_6_1_93() { #[test] fn sutra_6_1_94() { let il = d("ila~", Curadi); - assert_has_lat(&["upa"], &il, &["upelayati"]); - assert_has_lat(&["pra"], &il, &["prelayati"]); + assert_has_lat_p(&["upa"], &il, &["upelayati"]); + assert_has_lat_p(&["pra"], &il, &["prelayati"]); let uz = d("uza~", Bhvadi); assert_has_lat(&["upa"], &uz, &["upozati"]); @@ -659,8 +874,8 @@ fn sutra_6_1_103() { fn sutra_6_1_104() { assert_has_subantas("vfkza", Pum, V::Prathama, Dvi, &["vfkzO"]); assert_has_subantas("plakza", Pum, V::Prathama, Dvi, &["plakzO"]); - assert_has_subantas_p(&stri("KawvA"), Stri, V::Prathama, Dvi, &["Kawve"]); - assert_has_subantas_p(&stri("kuRqA"), Stri, V::Prathama, Dvi, &["kuRqe"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, V::Prathama, Dvi, &["Kawve"]); + assert_has_subantas_p(&nyap("kuRqA"), Stri, V::Prathama, Dvi, &["kuRqe"]); // At assert_has_subantas("agni", Pum, V::Prathama, Dvi, &["agnI"]); // ici @@ -778,6 +993,13 @@ fn sutra_6_1_137() { assert_has_krdanta(&["upa"], &kf, Krt::tavya, &["upaskartavya", "upakartavya"]); } +#[test] +fn sutra_6_1_139() { + let kr = d("qukf\\Y", Tanadi); + assert_has_krdanta(&["upa"], &kr, Krt::kta, &["upaskfta", "upakfta"]); + assert_has_lat_a(&["upa"], &kr, &["upaskurute", "upakurute"]); +} + #[test] fn sutra_6_1_140() { let kr = d("kF", Tudadi); diff --git a/vidyut-prakriya/tests/pada_6_3.rs b/vidyut-prakriya/tests/pada_6_3.rs index b3d0687..21b6f0f 100644 --- a/vidyut-prakriya/tests/pada_6_3.rs +++ b/vidyut-prakriya/tests/pada_6_3.rs @@ -1,31 +1,22 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Lakara::*; +use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} +#[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"]); -fn assert_has_lun_3d(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta( - prefixes, - dhatu, - Lakara::Lun, - Purusha::Prathama, - Vacana::Dvi, - expected, - ); -} -fn assert_has_lun_2d(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta( - prefixes, - dhatu, - Lakara::Lun, - Purusha::Madhyama, - Vacana::Dvi, - expected, - ); + // 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"]); } #[test] @@ -52,6 +43,6 @@ fn sutra_6_3_112() { assert_has_krdanta(&[], &vah, Krt::kta, &["UQa"]); assert_has_krdanta(&[], &vah, Krt::ktavatu, &["UQavat"]); - assert_has_lun_3d(&["ud"], &vah, &["udavoQAm"]); - assert_has_lun_2d(&["ud"], &vah, &["udavoQam"]); + assert_has_tas(&["ud"], &vah, Lun, &["udavoQAm"]); + assert_has_thas(&["ud"], &vah, Lun, &["udavoQam"]); } diff --git a/vidyut-prakriya/tests/pada_6_4.rs b/vidyut-prakriya/tests/pada_6_4.rs index afd9796..9ea95ed 100644 --- a/vidyut-prakriya/tests/pada_6_4.rs +++ b/vidyut-prakriya/tests/pada_6_4.rs @@ -9,10 +9,6 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } @@ -25,20 +21,64 @@ fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +fn prati_dhatu(text: &str) -> Pratipadika { + Pratipadika::builder() + .text(text) + .is_dhatu(true) + .build() + .unwrap() } -fn assert_has_hi(prefixes: &[&str], d: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, &d, Lot, Madhyama, Eka, expected); +fn prati_udit(text: &str) -> Pratipadika { + Pratipadika::builder() + .text(text) + .is_udit(true) + .build() + .unwrap() } -fn assert_has_vas(prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, &d, la, Uttama, Dvi, expected); +fn assert_has_hi(prefixes: &[&str], d: &Dhatu, expected: &[&str]) { + assert_has_sip(prefixes, &d, Lot, expected); } -fn assert_has_mas(prefixes: &[&str], d: &Dhatu, la: Lakara, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, &d, la, Uttama, Bahu, expected); +#[test] +fn sutra_6_4_1() { + use Vibhakti::*; + + // halaH + assert_has_krdanta(&[], &d("hve\\Y", Bhvadi), Krt::kta, &["hUta"]); + assert_has_krdanta(&[], &d("jyA\\", Kryadi), Krt::kta, &["jIna"]); + assert_has_krdanta(&["sam"], &d("vye\\Y", Bhvadi), Krt::kta, &["saMvIta"]); + // angasya? + let ve = d("ve\\Y", Bhvadi); + assert_has_krdanta(&["nir"], &ve, Krt::kta, &["niruta"]); + assert_has_krdanta(&["dur"], &ve, Krt::kta, &["duruta"]); + + // nAmi dIrgha + assert_has_subantas("agni", Pum, Sasthi, Bahu, &["agnInAm"]); + assert_has_subantas("vAyu", Pum, Sasthi, Bahu, &["vAyUnAm"]); + // angasya? + assert_has_subantas("krimiRA", Stri, Dvitiya, Eka, &["krimiRAm"]); + assert_has_subantas("pAmanA", Stri, Dvitiya, Eka, &["pAmanAm"]); + + // ato bhisa ais + assert_has_subantas("vfkza", Pum, Trtiya, Bahu, &["vfkzEH"]); + assert_has_subantas("plakza", Pum, Trtiya, Bahu, &["plakzEH"]); + // angasya + assert_has_subantas_p( + &nyap("brAhmaRaBissA"), + Stri, + Prathama, + Eka, + &["brAhmaRaBissA"], + ); + assert_has_subantas_p( + &nyap("odanaBissadA"), + Stri, + Prathama, + Eka, + &["odanaBissadA"], + ); } #[test] @@ -110,23 +150,36 @@ fn sutra_6_4_8() { assert_has_subantas("takzan", Pum, Sambodhana, Eka, &["takzan"]); } -#[ignore] #[test] fn sutra_6_4_10() { use Vibhakti::*; - assert_has_subantas("Sreyas", Pum, Prathama, Eka, &["SreyAn"]); - assert_has_subantas("Sreyas", Pum, Prathama, Dvi, &["SreyAMsO"]); - assert_has_subantas("Sreyas", Pum, Prathama, Bahu, &["SreyAMsaH"]); - assert_has_subantas("Sreyas", Napumsaka, Prathama, Bahu, &["SreyAMsi"]); + let shreyas = prati_udit("Sreyas"); + assert_has_subantas_p(&shreyas, Pum, Prathama, Eka, &["SreyAn"]); + assert_has_subantas_p(&shreyas, Pum, Prathama, Dvi, &["SreyAMsO"]); + assert_has_subantas_p(&shreyas, Pum, Prathama, Bahu, &["SreyAMsaH"]); + assert_has_subantas_p(&shreyas, Napumsaka, Prathama, Bahu, &["SreyAMsi"]); assert_has_subantas("payas", Napumsaka, Prathama, Bahu, &["payAMsi"]); assert_has_subantas("yaSas", Napumsaka, Prathama, Bahu, &["yaSAMsi"]); // mahat - assert_has_subantas("mahat", Pum, Prathama, Eka, &["mahAn"]); - assert_has_subantas("mahat", Pum, Prathama, Dvi, &["mahAntO"]); - assert_has_subantas("mahat", Pum, Prathama, Bahu, &["mahAntaH"]); + let mahat = prati_udit("mahat"); + assert_has_subantas_p(&mahat, Pum, Prathama, Eka, &["mahAn"]); + assert_has_subantas_p(&mahat, Pum, Prathama, Dvi, &["mahAntO"]); + assert_has_subantas_p(&mahat, Pum, Prathama, Bahu, &["mahAntaH"]); // asambudDo - assert_has_subantas("Sreyas", Pum, Sambodhana, Eka, &["Sreyan"]); - assert_has_subantas("mahat", Pum, Sambodhana, Eka, &["mahan"]); + assert_has_subantas_p(&shreyas, Pum, Sambodhana, Eka, &["Sreyan"]); + assert_has_subantas_p(&mahat, Pum, Sambodhana, Eka, &["mahan"]); +} + +#[test] +fn sutra_6_4_14() { + use Vibhakti::*; + assert_has_subantas_p(&prati_udit("Bavat"), Pum, Prathama, Eka, &["BavAn"]); + assert_has_subantas_p(&prati_udit("kftavat"), Pum, Prathama, Eka, &["kftavAn"]); + assert_has_subantas_p(&prati_udit("gomat"), Pum, Prathama, Eka, &["gomAn"]); + assert_has_subantas_p(&prati_udit("yavamat"), Pum, Prathama, Eka, &["yavamAn"]); + assert_has_subantas("suyaSas", Pum, Prathama, Eka, &["suyaSAH"]); + assert_has_subantas("suSrotas", Pum, Prathama, Eka, &["suSrotAH"]); + // TODO: others } #[test] @@ -596,6 +649,7 @@ fn sutra_6_4_48() { assert_has_lat_karmani(&[], &san(&hf), &["jihIrzyate"]); } +#[ignore] #[test] fn sutra_6_4_49() { let bhid = d("Bi\\di~^r", Rudhadi); @@ -620,20 +674,20 @@ fn sutra_6_4_51() { assert_has_lun_p(&[], &nic(&d("aSa~", Kryadi)), &["ASiSat"]); assert_has_lun_p(&[], &nic(&d("awa~", Bhvadi)), &["Awiwat"]); - let kf = nic(&d("qukf\\Y", Tanadi)); - let hf = nic(&d("hf\\Y", Bhvadi)); - assert_has_krdanta(&[], &kf, Krt::yuc, &["kAraRA"]); - assert_has_krdanta(&[], &hf, Krt::yuc, &["hAraRA"]); - assert_has_krdanta(&[], &kf, Krt::Rvul, &["kAraka"]); - assert_has_krdanta(&[], &hf, Krt::Rvul, &["hAraka"]); - assert_has_lat_karmani(&[], &kf, &["kAryate"]); - assert_has_lat_karmani(&[], &hf, &["hAryate"]); + let kf_nic = nic(&d("qukf\\Y", Tanadi)); + let hf_nic = nic(&d("hf\\Y", Bhvadi)); + assert_has_krdanta(&[], &kf_nic, Krt::yuc, &["kAraRA"]); + assert_has_krdanta(&[], &hf_nic, Krt::yuc, &["hAraRA"]); + assert_has_krdanta(&[], &kf_nic, Krt::Rvul, &["kAraka"]); + assert_has_krdanta(&[], &hf_nic, Krt::Rvul, &["hAraka"]); + assert_has_lat_karmani(&[], &kf_nic, &["kAryate"]); + assert_has_lat_karmani(&[], &hf_nic, &["hAryate"]); // TODO: jYIpsati // aniwi - assert_has_krdanta(&[], &kf, Krt::tfc, &["kArayitf"]); - assert_has_krdanta(&[], &hf, Krt::tfc, &["hArayitf"]); + assert_has_krdanta(&[], &kf_nic, Krt::tfc, &["kArayitf"]); + assert_has_krdanta(&[], &hf_nic, Krt::tfc, &["hArayitf"]); } #[test] @@ -644,12 +698,45 @@ fn sutra_6_4_52() { assert_has_krdanta(&[], &d("lakza~", Curadi), Krt::kta, &["lakzita"]); } +#[ignore] +#[test] +fn sutra_6_4_55() { + let kf_nic = nic(&d("qukf\\Y", Tanadi)); + let hf_nic = nic(&d("hf\\Y", Bhvadi)); + + // Am + assert_has_lit_p( + &[], + &kf_nic, + &["kArayAYcakAra", "kArayAmAsa", "kArayAmbaBUva"], + ); + assert_has_lit_p( + &[], + &hf_nic, + &["hArayAYcakAra", "hArayAmAsa", "hArayAmbaBUva"], + ); + // anta + assert_has_krdanta(&[], &nic(&d("gaqi~", Bhvadi)), Krt::Jac, &["gaRqayanta"]); + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::Jac, &["maRqayanta"]); + // Alu + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::Aluc, &["spfhayAlu"]); + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::Aluc, &["gfhayAlu"]); + // Ayya + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::Ayya, &["spfhayAyya"]); + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::Ayya, &["gfhayAyya"]); + // itnu + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::itnuc, &["gfhayAyya"]); + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::izRuc, &["pozayizRu"]); + assert_has_krdanta(&[], &nic(&d("maqi~\\", Bhvadi)), Krt::izRuc, &["pArayizRu"]); +} + #[ignore] #[test] fn sutra_6_4_62() { let ci = d("ci\\Y", Svadi); assert_has_lrt_karmani(&[], &ci, &["cAyizyate", "cezyate"]); assert_has_lrn_karmani(&[], &ci, &["acAyizyata", "acezyata"]); + let daa = d("qudA\\Y", Juhotyadi); assert_has_lrn_karmani(&[], &daa, &["dAyizyate", "dAsyate"]); assert_has_lrn_karmani(&[], &daa, &["adAyizyata", "adAsyata"]); @@ -807,6 +894,7 @@ fn sutra_6_4_68() { assert_has_ashirlin_p(&["nis"], &d("vA\\", Adadi), &["nirvAyAt"]); } +#[ignore] #[test] fn sutra_6_4_69() { assert_has_krdanta(&["pra"], &d("qudA\\Y", Juhotyadi), Krt::ktvA, &["pradAya"]); @@ -898,7 +986,7 @@ fn sutra_6_4_78() { #[test] fn sutra_6_4_79() { - let stri = stri("strI"); + let stri = nyap("strI"); assert_has_subantas_p(&stri, Stri, V::Prathama, Eka, &["strI"]); assert_has_subantas_p(&stri, Stri, V::Prathama, Dvi, &["striyO"]); assert_has_subantas_p(&stri, Stri, V::Prathama, Bahu, &["striyaH"]); @@ -906,7 +994,7 @@ fn sutra_6_4_79() { #[test] fn sutra_6_4_80() { - let stri = stri("strI"); + let stri = nyap("strI"); assert_has_subantas_p(&stri, Stri, V::Dvitiya, Eka, &["strIm", "striyam"]); assert_has_subantas_p(&stri, Stri, V::Dvitiya, Bahu, &["strIH", "striyaH"]); } @@ -944,11 +1032,11 @@ fn sutra_6_4_83() { #[test] fn sutra_6_4_88() { let bhu = d("BU", Bhvadi); - assert_has_tinanta(&[], &bhu, Lun, Prathama, Bahu, &["aBUvan"]); - assert_has_tinanta(&[], &bhu, Lun, Uttama, Eka, &["aBUvam"]); - assert_has_tinanta(&[], &bhu, Lit, Prathama, Eka, &["baBUva"]); - assert_has_tinanta(&[], &bhu, Lit, Prathama, Dvi, &["baBUvatuH"]); - assert_has_tinanta(&[], &bhu, Lit, Prathama, Bahu, &["baBUvuH"]); + assert_has_jhi(&[], &bhu, Lun, &["aBUvan"]); + assert_has_mip(&[], &bhu, Lun, &["aBUvam"]); + assert_has_tip(&[], &bhu, Lit, &["baBUva"]); + assert_has_tas(&[], &bhu, Lit, &["baBUvatuH"]); + assert_has_jhi(&[], &bhu, Lit, &["baBUvuH"]); } #[test] @@ -958,10 +1046,10 @@ fn sutra_6_4_89() { assert_has_krdanta(&["ni"], &guh, Krt::Rvul, &["nigUhaka"]); assert_has_krdanta(&["ni"], &guh, Krt::Rini, &["nigUhin"]); assert_has_krdanta(&["ni"], &guh, Krt::Ramul, &["nigUham"]); - assert_has_parasmai_tinanta(&["ni"], &guh, Lat, Prathama, Bahu, &["nigUhanti"]); + assert_has_jhi(&["ni"], &guh, Lat, &["nigUhanti"]); assert_has_krdanta(&[], &guh, Krt::GaY, &["gUha"]); - assert_has_parasmai_tinanta(&["ni"], &guh, Lit, Prathama, Dvi, &["nijuguhatuH"]); - assert_has_parasmai_tinanta(&["ni"], &guh, Lit, Prathama, Bahu, &["nijuguhuH"]); + assert_has_tas(&["ni"], &guh, Lit, &["nijuguhatuH"]); + assert_has_jhi(&["ni"], &guh, Lit, &["nijuguhuH"]); // aci assert_has_krdanta(&["ni"], &guh, Krt::tfc, &["nigoQf", "nigUhitf"]); assert_has_krdanta(&["ni"], &guh, Krt::tumun, &["nigoQum", "nigUhitum"]); @@ -992,25 +1080,25 @@ fn sutra_6_4_92() { #[test] fn sutra_6_4_98() { let gam = d("ga\\mx~", Bhvadi); - assert_has_tinanta(&[], &gam, Lit, Prathama, Dvi, &["jagmatuH"]); - assert_has_tinanta(&[], &gam, Lit, Prathama, Bahu, &["jagmuH"]); + assert_has_tas(&[], &gam, Lit, &["jagmatuH"]); + assert_has_jhi(&[], &gam, Lit, &["jagmuH"]); let han = d("ha\\na~", Adadi); - assert_has_tinanta(&[], &han, Lit, Prathama, Dvi, &["jaGnatuH"]); - assert_has_tinanta(&[], &han, Lit, Prathama, Bahu, &["jaGnuH"]); + assert_has_tas(&[], &han, Lit, &["jaGnatuH"]); + assert_has_jhi(&[], &han, Lit, &["jaGnuH"]); let jan = d("janI~\\", Divadi); - assert_has_tinanta(&[], &jan, Lit, Prathama, Eka, &["jajYe"]); - assert_has_tinanta(&[], &jan, Lit, Prathama, Dvi, &["jajYAte"]); - assert_has_tinanta(&[], &jan, Lit, Prathama, Bahu, &["jajYire"]); + assert_has_ta(&[], &jan, Lit, &["jajYe"]); + assert_has_aataam(&[], &jan, Lit, &["jajYAte"]); + assert_has_jha(&[], &jan, Lit, &["jajYire"]); let khan = d("Kanu~^", Bhvadi); - assert_has_parasmai_tinanta(&[], &khan, Lit, Prathama, Dvi, &["caKnatuH"]); - assert_has_parasmai_tinanta(&[], &khan, Lit, Prathama, Bahu, &["caKnuH"]); + assert_has_tas(&[], &khan, Lit, &["caKnatuH"]); + assert_has_jhi(&[], &khan, Lit, &["caKnuH"]); let ad = d("a\\da~", Adadi); - assert_has_tinanta(&[], &ad, Lit, Prathama, Dvi, &["jakzatuH", "AdatuH"]); - assert_has_tinanta(&[], &ad, Lit, Prathama, Bahu, &["jakzuH", "AduH"]); + assert_has_tas(&[], &ad, Lit, &["jakzatuH", "AdatuH"]); + assert_has_jhi(&[], &ad, Lit, &["jakzuH", "AduH"]); // kNiti assert_has_krdanta(&[], &gam, Krt::lyuw, &["gamana"]); @@ -1025,6 +1113,45 @@ fn sutra_6_4_98() { assert_has_lat_karmani(&[], &han, &["hanyate"]); } +#[test] +fn sutra_6_4_100() { + let hu = d("hu\\", Juhotyadi); + assert_has_hi(&[], &hu, &["juhuDi", "juhutAt"]); + assert_has_hi( + &[], + &d("Bi\\di~^r", Rudhadi), + &["BinDi", "BindDi", "BintAt", "BinttAt"], + ); + assert_has_hi( + &[], + &d("Ci\\di~^r", Rudhadi), + &["CinDi", "CindDi", "CintAt", "CinttAt"], + ); + + // hu-jhal + assert_has_hi(&[], &d("qukrI\\Y", Kryadi), &["krIRIhi", "krIRItAt"]); + assert_has_hi(&[], &d("prI\\Y", Kryadi), &["prIRIhi", "prIRItAt"]); + // heH + assert_has_tas(&[], &hu, Lot, &["juhutAm"]); + // hali + assert_has_hi(&[], &d("rudi~r", Adadi), &["rudihi", "ruditAt"]); + + // TODO: others +} + +#[test] +fn sutra_6_4_104() { + assert_has_lun_karmani(&[], &d("qukf\\Y", Tanadi), &["akAri"]); + assert_has_lun_karmani(&[], &d("hf\\Y", Bhvadi), &["ahAri"]); + assert_has_lun_karmani(&[], &d("lUY", Kryadi), &["alAvi"]); + assert_has_lun_karmani(&[], &d("qupa\\ca~^z", Bhvadi), &["apAci"]); + + // ciR + assert_has_lat_karmani(&[], &d("Bi\\di~^r", Rudhadi), &["Bidyate"]); + + // TODO: tarAm +} + #[test] fn sutra_6_4_105() { assert_has_hi(&[], &d("qupa\\ca~^z", Bhvadi), &["paca", "pacatAt"]); @@ -1093,9 +1220,39 @@ fn sutra_6_4_108() { #[test] fn sutra_6_4_109() { let kf = d("qukf\\Y", Tanadi); - assert_has_parasmai_tinanta(&[], &kf, VidhiLin, Prathama, Eka, &["kuryAt"]); - assert_has_parasmai_tinanta(&[], &kf, VidhiLin, Prathama, Dvi, &["kuryAtAm"]); - assert_has_parasmai_tinanta(&[], &kf, VidhiLin, Prathama, Bahu, &["kuryuH"]); + assert_has_tip(&[], &kf, VidhiLin, &["kuryAt"]); + assert_has_tas(&[], &kf, VidhiLin, &["kuryAtAm"]); + assert_has_jhi(&[], &kf, VidhiLin, &["kuryuH"]); +} + +#[test] +fn sutra_6_4_110() { + let kf = d("qukf\\Y", Tanadi); + assert_has_tas(&[], &kf, Lat, &["kurutaH"]); + assert_has_jhi(&[], &kf, Lat, &["kurvanti"]); + // sArvadhAtuka + assert_has_hi(&[], &kf, &["kuru", "kurutAt"]); + // kNiti + assert_has_tip(&[], &kf, Lat, &["karoti"]); + assert_has_sip(&[], &kf, Lat, &["karozi"]); + assert_has_mip(&[], &kf, Lat, &["karomi"]); +} + +#[test] +fn sutra_6_4_111() { + let rudh = d("ru\\Di~^r", Rudhadi); + assert_has_tas(&[], &rudh, Lat, &["runDaH", "rundDaH"]); + assert_has_jhi(&[], &rudh, Lat, &["runDanti"]); + let bhid = d("Bi\\di~^r", Rudhadi); + assert_has_tas(&[], &bhid, Lat, &["BintaH", "BinttaH"]); + assert_has_jhi(&[], &bhid, Lat, &["Bindanti"]); + // asteH + let as_ = d("asa~", Adadi); + assert_has_tas(&[], &as_, Lat, &["staH"]); + assert_has_jhi(&[], &as_, Lat, &["santi"]); + // kNiti + assert_has_lat_p(&[], &bhid, &["Binatti"]); + assert_has_lat_p(&[], &as_, &["asti"]); } #[test] @@ -1116,8 +1273,8 @@ fn sutra_6_4_112() { assert_has_atmane_tinanta(&["sam"], &haa, Lan, Prathama, Bahu, &["samajihata"]); // SnAByastayoH - assert_has_tinanta(&[], &d("yA\\", Adadi), Lat, Prathama, Bahu, &["yAnti"]); - assert_has_tinanta(&[], &d("vA\\", Adadi), Lat, Prathama, Bahu, &["vAnti"]); + assert_has_jhi(&[], &d("yA\\", Adadi), Lat, &["yAnti"]); + assert_has_jhi(&[], &d("vA\\", Adadi), Lat, &["vAnti"]); // AtaH assert_has_parasmai_tinanta( @@ -1137,10 +1294,10 @@ fn sutra_6_4_112() { fn sutra_6_4_113() { let lu = d("lUY", Kryadi); let pu = d("pUY", Kryadi); - assert_has_parasmai_tinanta(&[], &lu, Lat, Prathama, Dvi, &["lunItaH"]); - assert_has_parasmai_tinanta(&[], &pu, Lat, Prathama, Dvi, &["punItaH"]); - assert_has_parasmai_tinanta(&[], &lu, Lat, Madhyama, Dvi, &["lunITaH"]); - assert_has_parasmai_tinanta(&[], &pu, Lat, Madhyama, Dvi, &["punITaH"]); + assert_has_tas(&[], &lu, Lat, &["lunItaH"]); + assert_has_tas(&[], &pu, Lat, &["punItaH"]); + assert_has_thas(&[], &lu, Lat, &["lunITaH"]); + assert_has_thas(&[], &pu, Lat, &["punITaH"]); assert_has_lat_a(&[], &lu, &["lunIte"]); assert_has_lat_a(&[], &pu, &["punIte"]); @@ -1155,26 +1312,12 @@ fn sutra_6_4_113() { assert_has_atmane_tinanta(&["sam"], &haa, Lat, Madhyama, Bahu, &["saYjihIDve"]); // hali - assert_has_parasmai_tinanta(&[], &lu, Lat, Prathama, Bahu, &["lunanti"]); + assert_has_jhi(&[], &lu, Lat, &["lunanti"]); assert_has_atmane_tinanta(&[], &maa, Lat, Prathama, Bahu, &["mimate"]); // aGoH - assert_has_parasmai_tinanta( - &[], - &d("qudA\\Y", Juhotyadi), - Lat, - Prathama, - Dvi, - &["dattaH"], - ); - assert_has_parasmai_tinanta( - &[], - &d("quDA\\Y", Juhotyadi), - Lat, - Prathama, - Dvi, - &["DattaH"], - ); + assert_has_tas(&[], &d("qudA\\Y", Juhotyadi), Lat, &["dattaH"]); + assert_has_tas(&[], &d("quDA\\Y", Juhotyadi), Lat, &["DattaH"]); // kNiti assert_has_lat_p(&[], &lu, &["lunAti"]); @@ -1262,9 +1405,233 @@ fn sutra_6_4_119() { assert_has_hi(&[], &d("asa~", Adadi), &["eDi", "stAt"]); } +#[test] +fn sutra_6_4_120() { + let ran = d("raRa~", Bhvadi); + assert_has_tas(&[], &ran, Lit, &["reRatuH"]); + assert_has_jhi(&[], &ran, Lit, &["reRuH"]); + let yam = d("yama~", Bhvadi); + assert_has_tas(&[], &yam, Lit, &["yematuH"]); + assert_has_jhi(&[], &yam, Lit, &["yemuH"]); + let pac = d("qupa\\ca~^z", Bhvadi); + assert_has_tas(&[], &pac, Lit, &["pecatuH"]); + assert_has_jhi(&[], &pac, Lit, &["pecuH"]); + let dam = d("damu~", Divadi); + assert_has_tas(&[], &dam, Lit, &["dematuH"]); + assert_has_jhi(&[], &dam, Lit, &["demuH"]); + + // ataH? + let div = d("divu~", Divadi); + assert_has_tas(&[], &div, Lit, &["didivatuH"]); + assert_has_jhi(&[], &div, Lit, &["didivuH"]); + + // taparakaraRa? + let ras = d("rAsf~\\", Bhvadi); + assert_has_atmane_tinanta(&[], &ras, Lit, Prathama, Eka, &["rarAse"]); + assert_has_atmane_tinanta(&[], &ras, Lit, Prathama, Dvi, &["rarAsAte"]); + assert_has_atmane_tinanta(&[], &ras, Lit, Prathama, Bahu, &["rarAsire"]); + + // ekahalmadhya? + let shram = d("Sramu~", Divadi); + assert_has_tas(&[], &shram, Lit, &["SaSramatuH"]); + assert_has_jhi(&[], &shram, Lit, &["SaSramuH"]); + let tsar = d("tsara~", Bhvadi); + assert_has_tas(&[], &tsar, Lit, &["tatsaratuH"]); + assert_has_jhi(&[], &tsar, Lit, &["tatsaruH"]); + + // anAdeze? + let kan = d("kaRa~", Bhvadi); + assert_has_tas(&[], &kan, Lit, &["cakaRatuH"]); + assert_has_jhi(&[], &kan, Lit, &["cakaRuH"]); + // TODO: how? + // let gan = d("gaRa", Curadi); + // assert_has_tas(&[], &gan, Lit, &["jagaRatuH"]); + // assert_has_jhi(&[], &gan, Lit, &["jagaRuH"]); + let bhan = d("BaRa~", Bhvadi); + assert_has_tas(&[], &bhan, Lit, &["baBaRatuH"]); + assert_has_jhi(&[], &bhan, Lit, &["baBaRuH"]); + + let nam = d("Ra\\ma~", Bhvadi); + assert_has_tas(&[], &nam, Lit, &["nematuH"]); + assert_has_jhi(&[], &nam, Lit, &["nemuH"]); + let sah = d("zaha~\\", Bhvadi); + assert_has_atmane_tinanta(&[], &sah, Lit, Prathama, Eka, &["sehe"]); + assert_has_atmane_tinanta(&[], &sah, Lit, Prathama, Dvi, &["sehAte"]); + assert_has_atmane_tinanta(&[], &sah, Lit, Prathama, Bahu, &["sehire"]); + + // kNiti? + assert_has_mip(&[], &pac, Lit, &["papaca", "papAca"]); + assert_has_mip(&[], &d("paWa~", Bhvadi), Lit, &["papaWa", "papAWa"]); +} + +#[test] +fn sutra_6_4_121() { + assert_has_sip(&[], &d("qupa\\ca~^z", Bhvadi), Lit, &["peciTa", "papakTa"]); + assert_has_sip(&[], &d("Sa\\kx~", Svadi), Lit, &["SekiTa", "SaSakTa"]); + // ataH + assert_has_sip(&[], &d("divu~", Divadi), Lit, &["dideviTa"]); + // ekahalmadhya + assert_has_sip(&[], &d("takzU~", Bhvadi), Lit, &["tatakziTa"]); + assert_has_sip(&[], &d("rakza~", Bhvadi), Lit, &["rarakziTa"]); + // anAdezAdi + assert_has_sip(&[], &d("kaRa~", Bhvadi), Lit, &["cakaRiTa"]); + assert_has_sip(&[], &d("BaRa~", Bhvadi), Lit, &["baBaRiTa"]); +} + +#[ignore] +#[test] +fn sutra_6_4_131() { + use V::*; + assert_has_subantas("vidvas", Pum, Sasthi, Eka, &["viduzaH"]); + assert_has_subantas("vidvas", Pum, Trtiya, Eka, &["viduzA"]); + assert_has_subantas("vidvas", Pum, Caturthi, Eka, &["viduze"]); + assert_has_subantas("pecivas", Pum, Sasthi, Eka, &["pecuzaH"]); + assert_has_subantas("pecivas", Pum, Trtiya, Eka, &["pecuzA"]); + assert_has_subantas("pecivas", Pum, Caturthi, Eka, &["pecuze"]); + assert_has_subantas("papivas", Pum, Sasthi, Eka, &["papuzaH"]); +} + +#[test] +fn sutra_6_4_133() { + use V::*; + assert_has_subantas("Svan", Pum, Sasthi, Eka, &["SunaH"]); + assert_has_subantas("Svan", Pum, Trtiya, Eka, &["SunA"]); + assert_has_subantas("Svan", Pum, Caturthi, Eka, &["Sune"]); + assert_has_subantas("yuvan", Pum, Sasthi, Eka, &["yUnaH"]); + assert_has_subantas("yuvan", Pum, Trtiya, Eka, &["yUnA"]); + assert_has_subantas("yuvan", Pum, Caturthi, Eka, &["yUne"]); + assert_has_subantas("maGavan", Pum, Sasthi, Eka, &["maGonaH"]); + assert_has_subantas("maGavan", Pum, Trtiya, Eka, &["maGonA"]); + assert_has_subantas("maGavan", Pum, Caturthi, Eka, &["maGone"]); + + // atadDite? + assert_has_taddhitanta(&prati("Svan"), T::aY, &["SOva"]); + assert_has_taddhitanta(&prati("yuvan"), T::aR, &["yOvana"]); + assert_has_taddhitanta(&prati("maGavan"), T::aR, &["mAGavana"]); + + // TODO: others +} + +#[test] +fn sutra_6_4_134() { + use V::*; + assert_has_subantas("rAjan", Pum, Sasthi, Eka, &["rAjYaH"]); + assert_has_subantas("rAjan", Pum, Trtiya, Eka, &["rAjYA"]); + assert_has_subantas("rAjan", Pum, Caturthi, Eka, &["rAjYe"]); + assert_has_subantas("takzan", Pum, Trtiya, Eka, &["takzRA"]); + assert_has_subantas("takzan", Pum, Caturthi, Eka, &["takzRe"]); +} + +#[ignore] +#[test] +fn sutra_6_4_135() { + use V::*; + assert_has_subantas("ukzan", Pum, Sasthi, Eka, &["rAjYaH"]); + assert_has_subantas("BrUnahan", Pum, Trtiya, Eka, &["rAjYA"]); + assert_has_subantas("DrtarAjan", Pum, Caturthi, Eka, &["rAjYe"]); + assert_has_subantas("sAman", Pum, Trtiya, Eka, &["takzRA"]); + assert_has_subantas("vima", Pum, Caturthi, Eka, &["takzRe"]); +} + +#[test] +fn sutra_6_4_136() { + use V::*; + assert_has_subantas("rAjan", Pum, Saptami, Eka, &["rAjYi", "rAjani"]); + assert_has_subantas("sAman", Napumsaka, Saptami, Eka, &["sAmni", "sAmani"]); + assert_has_subantas("sAman", Napumsaka, Prathama, Dvi, &["sAmnI", "sAmanI"]); +} + +#[test] +fn sutra_6_4_137() { + use V::*; + assert_has_subantas("parvan", Pum, Trtiya, Eka, &["parvaRA"]); + assert_has_subantas("parvan", Pum, Caturthi, Eka, &["parvaRe"]); + assert_has_subantas("aTarvan", Pum, Trtiya, Eka, &["aTarvaRA"]); + assert_has_subantas("aTarvan", Pum, Caturthi, Eka, &["aTarvaRe"]); + + // saMyogAt? + // TODO + // assert_has_subantas("pratidIvan", Napumsaka, Trtiya, Eka, &["pratidIvnA"]); + // assert_has_subantas("pratidIvan", Napumsaka, Caturthi, Eka, &["pratidIvne"]); + assert_has_subantas("sAman", Napumsaka, Trtiya, Eka, &["sAmnA"]); + assert_has_subantas("sAman", Napumsaka, Caturthi, Eka, &["sAmne"]); + + // vamAntAt? + assert_has_subantas("takzan", Pum, Trtiya, Eka, &["takzRA"]); + assert_has_subantas("takzan", Pum, Caturthi, Eka, &["takzRe"]); +} + +#[test] +fn sutra_6_4_140() { + use V::*; + let kilalapa = &prati_dhatu("kilAlapA"); + assert_has_subantas_p(&kilalapa, Pum, Dvitiya, Bahu, &["kilAlapaH"]); + assert_has_subantas_p(&kilalapa, Pum, Trtiya, Eka, &["kilAlapA"]); + assert_has_subantas_p(&kilalapa, Pum, Caturthi, Eka, &["kilAlape"]); + let shubhamya = &prati_dhatu("SuBaMyA"); + assert_has_subantas_p(&shubhamya, Pum, Dvitiya, Bahu, &["SuBaMyaH"]); + assert_has_subantas_p(&shubhamya, Pum, Trtiya, Eka, &["SuBaMyA"]); + assert_has_subantas_p(&shubhamya, Pum, Caturthi, Eka, &["SuBaMye"]); + + // AtaH? + let ni = &prati_dhatu("nI"); + assert_has_subantas_p(&ni, Pum, Trtiya, Eka, &["niyA"]); + assert_has_subantas_p(&ni, Pum, Caturthi, Eka, &["niye"]); + + // dhAtoH? + assert_has_subantas("KawvA", Stri, Dvitiya, Bahu, &["KawvAH"]); + assert_has_subantas("mAlA", Stri, Dvitiya, Bahu, &["mAlAH"]); +} + +#[ignore] +#[test] +fn sutra_6_4_142() { + assert_has_taddhitanta(&prati("viMSati"), T::qvun, &["viMSaka"]); + // TODO: assert_has_taddhitanta(&prati("viMSati"), T::waq, &["viMSa"]); + + // qiti? + assert_has_subantas("viMSati", Pum, V::Trtiya, Eka, &["viMSatyA"]); +} + +#[ignore] +#[test] +fn sutra_6_4_143() { + assert_has_taddhitanta(&prati("kumuda"), T::qmatup, &["kumudvat"]); + assert_has_taddhitanta(&prati("naqa"), T::qmatup, &["naqvat"]); + assert_has_taddhitanta(&prati("vetasa"), T::qmatup, &["vetasvat"]); + // TODO: others + assert_has_taddhitanta(&prati("triMSat"), T::qvun, &["triMSaka"]); +} + +#[test] +fn sutra_6_4_144() { + use V::*; + assert_has_taddhitanta(&prati("agniSarman"), T::iY, &["AgniSarmi"]); + assert_has_taddhitanta(&prati("uquloman"), T::iY, &["Oqulomi"]); + + // naH? + // taddhite? + assert_has_subantas("Sarman", Napumsaka, Trtiya, Eka, &["SarmaRA"]); + assert_has_subantas("Sarman", Napumsaka, Caturthi, Eka, &["SarmaRe"]); +} + +#[test] +fn sutra_6_4_144_v1() { + assert_has_taddhitanta(&prati("sabrahmacArin"), T::aR, &["sAbrahmacAra"]); + assert_has_taddhitanta(&prati("pIWasarpin"), T::aR, &["pEWasarpa"]); + assert_has_taddhitanta(&prati("kalApin"), T::aR, &["kAlApa"]); + assert_has_taddhitanta(&prati("kuTumin"), T::aR, &["kOTuma"]); + assert_has_taddhitanta(&prati("tEtilin"), T::aR, &["tEtila"]); + assert_has_taddhitanta(&prati("jAjalin"), T::aR, &["jAjala"]); + assert_has_taddhitanta(&prati("lANgalin"), T::aR, &["lANgala"]); + assert_has_taddhitanta(&prati("SilAlin"), T::aR, &["SElAla"]); + assert_has_taddhitanta(&prati("SiKaRqin"), T::aR, &["SEKaRqa"]); + assert_has_taddhitanta(&prati("sukarasadman"), T::aR, &["sOkarasadma"]); + assert_has_taddhitanta(&prati("suparvan"), T::aR, &["sOparva"]); +} + #[test] fn sutra_6_4_146() { - use Taddhita as T; assert_has_taddhitanta(&prati("baBru"), T::yaY, &["bABravya"]); assert_has_taddhitanta(&prati("maRqu"), T::yaY, &["mARqavya"]); assert_has_taddhitanta(&prati("SaNku"), T::yat, &["SaNkavya"]); @@ -1274,3 +1641,141 @@ fn sutra_6_4_146() { assert_has_taddhitanta(&prati("kapawu"), T::aR, &["kApawava"]); // TODO: svAyamBuva } + +#[test] +fn sutra_6_4_155() { + let patu = prati("pawu"); + assert_has_taddhitanta(&patu, T::izWan, &["pawizWa"]); + assert_has_taddhitanta(&patu, T::imanic, &["pawiman"]); + assert_has_taddhitanta(&patu, T::Iyasun, &["pawIyas"]); + let laghu = prati("laGu"); + assert_has_taddhitanta(&laghu, T::izWan, &["laGizWa"]); + assert_has_taddhitanta(&laghu, T::imanic, &["laGiman"]); + assert_has_taddhitanta(&laghu, T::Iyasun, &["laGIyas"]); +} + +#[test] +fn sutra_6_4_156() { + assert_has_taddhitanta(&prati("sTUla"), T::izWan, &["sTavizWa"]); + assert_has_taddhitanta(&prati("sTUla"), T::Iyasun, &["sTavIyas"]); + assert_has_taddhitanta(&prati("dUra"), T::izWan, &["davizWa"]); + assert_has_taddhitanta(&prati("dUra"), T::Iyasun, &["davIyas"]); + assert_has_taddhitanta(&prati("yuvan"), T::izWan, &["yavizWa"]); + assert_has_taddhitanta(&prati("yuvan"), T::Iyasun, &["yavIyas"]); + assert_has_taddhitanta(&prati("hrasva"), T::izWan, &["hrasizWa"]); + assert_has_taddhitanta(&prati("hrasva"), T::imanic, &["hrasiman"]); + assert_has_taddhitanta(&prati("hrasva"), T::Iyasun, &["hrasIyas"]); + assert_has_taddhitanta(&prati("kzipra"), T::izWan, &["kzepizWa"]); + assert_has_taddhitanta(&prati("kzipra"), T::imanic, &["kzepiman"]); + assert_has_taddhitanta(&prati("kzipra"), T::Iyasun, &["kzepIyas"]); + assert_has_taddhitanta(&prati("kzudra"), T::izWan, &["kzodizWa"]); + assert_has_taddhitanta(&prati("kzudra"), T::imanic, &["kzodiman"]); + assert_has_taddhitanta(&prati("kzudra"), T::Iyasun, &["kzodIyas"]); +} + +#[test] +fn sutra_6_4_157() { + assert_has_taddhitanta(&prati("priya"), T::izWan, &["prezWa"]); + assert_has_taddhitanta(&prati("priya"), T::imanic, &["preman"]); + assert_has_taddhitanta(&prati("priya"), T::Iyasun, &["preyas"]); + assert_has_taddhitanta(&prati("sTira"), T::izWan, &["sTezWa"]); + assert_has_taddhitanta(&prati("sTira"), T::imanic, &[]); + assert_has_taddhitanta(&prati("sTira"), T::Iyasun, &["sTeyas"]); + assert_has_taddhitanta(&prati("sPira"), T::izWan, &["sPezWa"]); + assert_has_taddhitanta(&prati("sPira"), T::imanic, &[]); + assert_has_taddhitanta(&prati("sPira"), T::Iyasun, &["sPeyas"]); + assert_has_taddhitanta(&prati("uru"), T::izWan, &["varizWa"]); + assert_has_taddhitanta(&prati("uru"), T::imanic, &["variman"]); + assert_has_taddhitanta(&prati("uru"), T::Iyasun, &["varIyas"]); + assert_has_taddhitanta(&prati("bahula"), T::izWan, &["baMhizWa"]); + assert_has_taddhitanta(&prati("bahula"), T::imanic, &["baMhiman"]); + assert_has_taddhitanta(&prati("bahula"), T::Iyasun, &["baMhIyas"]); + assert_has_taddhitanta(&prati("guru"), T::izWan, &["garizWa"]); + assert_has_taddhitanta(&prati("guru"), T::imanic, &["gariman"]); + assert_has_taddhitanta(&prati("guru"), T::Iyasun, &["garIyas"]); + assert_has_taddhitanta(&prati("vfdDa"), T::izWan, &["varzizWa"]); + assert_has_taddhitanta(&prati("vfdDa"), T::imanic, &[]); + assert_has_taddhitanta(&prati("vfdDa"), T::Iyasun, &["varzIyas"]); + assert_has_taddhitanta(&prati("tfpra"), T::izWan, &["trapizWa"]); + assert_has_taddhitanta(&prati("tfpra"), T::imanic, &[]); + assert_has_taddhitanta(&prati("tfpra"), T::Iyasun, &["trapIyas"]); + assert_has_taddhitanta(&prati("dIrGa"), T::izWan, &["drAGizWa"]); + assert_has_taddhitanta(&prati("dIrGa"), T::imanic, &["drAGiman"]); + assert_has_taddhitanta(&prati("dIrGa"), T::Iyasun, &["drAGIyas"]); + assert_has_taddhitanta(&prati("vfndAraka"), T::izWan, &["vfndizWa"]); + assert_has_taddhitanta(&prati("vfndAraka"), T::imanic, &[]); + assert_has_taddhitanta(&prati("vfndAraka"), T::Iyasun, &["vfndIyas"]); +} + +#[test] +fn sutra_6_4_158() { + assert_has_taddhitanta(&prati("bahu"), T::imanic, &["BUman"]); + assert_has_taddhitanta(&prati("bahu"), T::Iyasun, &["BUyas"]); +} + +#[test] +fn sutra_6_4_159() { + assert_has_taddhitanta(&prati("bahu"), T::izWan, &["BUyizWa"]); +} + +#[test] +fn sutra_6_4_160() { + assert_has_taddhitanta(&prati("jya"), T::Iyasun, &["jyAyas"]); +} + +#[test] +fn sutra_6_4_161() { + assert_has_taddhitanta(&prati("pfTu"), T::izWan, &["praTizWa"]); + assert_has_taddhitanta(&prati("pfTu"), T::imanic, &["praTiman"]); + assert_has_taddhitanta(&prati("pfTu"), T::Iyasun, &["praTIyas"]); + assert_has_taddhitanta(&prati("mfdu"), T::izWan, &["mradizWa"]); + assert_has_taddhitanta(&prati("mfdu"), T::imanic, &["mradiman"]); + assert_has_taddhitanta(&prati("mfdu"), T::Iyasun, &["mradIyas"]); + // ftaH? + assert_has_taddhitanta(&prati("pawu"), T::izWan, &["pawizWa"]); + assert_has_taddhitanta(&prati("pawu"), T::imanic, &["pawiman"]); + assert_has_taddhitanta(&prati("pawu"), T::Iyasun, &["pawIyas"]); + // halAdeH? + assert_has_taddhitanta(&prati("fju"), T::izWan, &["fjizWa"]); + assert_has_taddhitanta(&prati("fju"), T::imanic, &["fjiman"]); + assert_has_taddhitanta(&prati("fju"), T::Iyasun, &["fjIyas"]); + // laGoH? + assert_has_taddhitanta(&prati("kfzRA"), T::izWan, &["kfzRizWa"]); + // TODO: assert_has_taddhitanta(&prati("kfzRA"), T::imanic, &["kfzRiman"]); + assert_has_taddhitanta(&prati("kfzRA"), T::Iyasun, &["kfzRIyas"]); + // TODO: others +} + +#[test] +fn sutra_6_4_164() { + assert_has_taddhitanta(&prati("saNkUwin"), T::aR, &["sANkUwina"]); + assert_has_taddhitanta(&prati("saMrAvin"), T::aR, &["sAMrAviRa"]); + assert_has_taddhitanta(&prati("sammArjin"), T::aR, &["sAmmArjina"]); + assert_has_taddhitanta(&prati("sragvin"), T::aR, &["srAgviRa"]); + // aRi? + assert_has_taddhitanta(&prati("daRqin"), T::aY, &["dARqa"]); +} + +#[test] +fn sutra_6_4_165() { + assert_has_taddhitanta(&prati("gATin"), T::aR, &["gATina"]); + assert_has_taddhitanta(&prati("vidaTin"), T::aR, &["vEdaTina"]); + assert_has_taddhitanta(&prati("keSin"), T::aR, &["kESina"]); + assert_has_taddhitanta(&prati("gaRin"), T::aR, &["gARina"]); + assert_has_taddhitanta(&prati("paRin"), T::aR, &["pARina"]); +} + +#[test] +fn sutra_6_4_166() { + assert_has_taddhitanta(&prati("SaNKin"), T::aR, &["SANKina"]); + assert_has_taddhitanta(&prati("madrin"), T::aR, &["mAdriRa"]); + assert_has_taddhitanta(&prati("vajrin"), T::aR, &["vAjriRa"]); +} + +#[test] +fn sutra_6_4_167() { + assert_has_taddhitanta(&prati("sAman"), T::aR, &["sAmana"]); + assert_has_taddhitanta(&prati("veman"), T::aR, &["vEmana"]); + assert_has_taddhitanta(&prati("sutvan"), T::aR, &["sOtvana"]); + assert_has_taddhitanta(&prati("jitvan"), T::aR, &["jEtvana"]); +} diff --git a/vidyut-prakriya/tests/pada_7_1.rs b/vidyut-prakriya/tests/pada_7_1.rs index e9eaeaf..6790d85 100644 --- a/vidyut-prakriya/tests/pada_7_1.rs +++ b/vidyut-prakriya/tests/pada_7_1.rs @@ -7,18 +7,10 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() -} - fn stri(text: &str) -> Pratipadika { Pratipadika::builder() .text(text) @@ -27,38 +19,6 @@ fn stri(text: &str) -> Pratipadika { .unwrap() } -pub fn assert_has_lat_p_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lat, Purusha::Prathama, Bahu, expected); -} - -pub fn assert_has_lit_p_1d(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lit, Purusha::Uttama, Dvi, expected); -} - -pub fn assert_has_lot_2s(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lot, Purusha::Madhyama, Eka, expected); -} - -pub fn assert_has_lot_p_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lot, Purusha::Prathama, Bahu, expected); -} - -pub fn assert_has_lan_p_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lan, Purusha::Prathama, Bahu, expected); -} - -pub fn assert_has_lat_a_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_atmane_tinanta(prefixes, dhatu, Lat, Purusha::Prathama, Bahu, expected); -} - -pub fn assert_has_lot_a_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_atmane_tinanta(prefixes, dhatu, Lot, Purusha::Prathama, Bahu, expected); -} - -pub fn assert_has_lan_a_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_atmane_tinanta(prefixes, dhatu, Lan, Purusha::Prathama, Bahu, expected); -} - #[test] fn sutra_7_1_1() { let nand = d("wunadi~", Bhvadi); @@ -85,78 +45,95 @@ fn sutra_7_1_2() { assert_has_taddhitanta(&prati("gArga"), T::Ca, &["gArgIya"]); assert_has_taddhitanta(&prati("vAtsa"), T::Ca, &["vAtsIya"]); assert_has_taddhitanta(&prati("kzatra"), T::Ga, &["kzatriya"]); - // TODO: add others. + + // pratyayagrahanam + assert_has_lat(&[], &d("Pakka~", Bhvadi), &["Pakkati"]); + assert_has_lat(&[], &d("QOkf~\\", Bhvadi), &["QOkate"]); + assert_has_lat_p(&[], &d("Kanu~^", Bhvadi), &["Kanati"]); + assert_has_lat_p(&[], &d("Ci\\di~^r", Rudhadi), &["Cinatti"]); + assert_has_lat(&[], &d("GurRa~\\", Bhvadi), &["GUrRate"]); + + // TODO: others } #[test] fn sutra_7_1_3() { - assert_has_lat_p_3p(&[], &d("qukf\\Y", Tanadi), &["kurvanti"]); - assert_has_lat_p_3p(&[], &d("zu\\Y", Svadi), &["sunvanti"]); - assert_has_lat_p_3p(&[], &d("ci\\Y", Svadi), &["cinvanti"]); + assert_has_jhi(&[], &d("qukf\\Y", Tanadi), Lat, &["kurvanti"]); + assert_has_jhi(&[], &d("zu\\Y", Svadi), Lat, &["sunvanti"]); + assert_has_jhi(&[], &d("ci\\Y", Svadi), Lat, &["cinvanti"]); // TODO: do the rest. + + // pratyayasya + let ujjh = d("ujJa", Tudadi); + assert_has_krdanta(&[], &ujjh, Krt::tfc, &["ujJitf"]); + assert_has_krdanta(&[], &ujjh, Krt::tumun, &["ujJitum"]); + assert_has_krdanta(&[], &ujjh, Krt::tavya, &["ujJitavya"]); } #[test] fn sutra_7_1_4() { let daa = d("qudA\\Y", Juhotyadi); - assert_has_lat_p_3p(&[], &daa, &["dadati"]); - assert_has_lot_p_3p(&[], &daa, &["dadatu"]); + assert_has_jhi(&[], &daa, Lat, &["dadati"]); + assert_has_jhi(&[], &daa, Lot, &["dadatu"]); let dhaa = d("quDA\\Y", Juhotyadi); - assert_has_lat_p_3p(&[], &dhaa, &["daDati"]); - assert_has_lot_p_3p(&[], &dhaa, &["daDatu"]); + assert_has_jhi(&[], &dhaa, Lat, &["daDati"]); + assert_has_jhi(&[], &dhaa, Lot, &["daDatu"]); let jaks = d("jakza~", Adadi); - assert_has_lat_p_3p(&[], &jaks, &["jakzati"]); - assert_has_lot_p_3p(&[], &jaks, &["jakzatu"]); + assert_has_jhi(&[], &jaks, Lat, &["jakzati"]); + assert_has_jhi(&[], &jaks, Lot, &["jakzatu"]); let jaagr = d("jAgf", Adadi); - assert_has_lat_p_3p(&[], &jaagr, &["jAgrati"]); - assert_has_lot_p_3p(&[], &jaagr, &["jAgratu"]); + assert_has_jhi(&[], &jaagr, Lat, &["jAgrati"]); + assert_has_jhi(&[], &jaagr, Lot, &["jAgratu"]); - assert_has_lan_p_3p(&[], &dhaa, &["adaDuH"]); - assert_has_lan_p_3p(&[], &jaagr, &["ajAgaruH"]); + assert_has_jhi(&[], &dhaa, Lan, &["adaDuH"]); + assert_has_jhi(&[], &jaagr, Lan, &["ajAgaruH"]); } #[test] fn sutra_7_1_5() { let ci = d("ci\\Y", Svadi); - assert_has_lat_a_3p(&[], &ci, &["cinvate"]); - assert_has_lot_a_3p(&[], &ci, &["cinvatAm"]); - assert_has_lan_a_3p(&[], &ci, &["acinvata"]); + assert_has_jha(&[], &ci, Lat, &["cinvate"]); + assert_has_jha(&[], &ci, Lot, &["cinvatAm"]); + assert_has_jha(&[], &ci, Lan, &["acinvata"]); - assert_has_lat_a_3p(&[], &d("pUY", Kryadi), &["punate"]); + assert_has_jha(&[], &d("pUY", Kryadi), Lat, &["punate"]); let lu = d("lUY", Kryadi); - assert_has_lat_a_3p(&[], &lu, &["lunate"]); - assert_has_lot_a_3p(&[], &lu, &["lunatAm"]); - assert_has_lan_a_3p(&[], &lu, &["alunata"]); + assert_has_jha(&[], &lu, Lat, &["lunate"]); + assert_has_jha(&[], &lu, Lot, &["lunatAm"]); + assert_has_jha(&[], &lu, Lan, &["alunata"]); - assert_has_lat_a_3p(&[], &d("cyu\\N", Bhvadi), &["cyavante"]); - assert_has_lat_a_3p(&[], &d("plu\\N", Bhvadi), &["plavante"]); + assert_has_jha(&[], &d("cyu\\N", Bhvadi), Lat, &["cyavante"]); + assert_has_jha(&[], &d("plu\\N", Bhvadi), Lat, &["plavante"]); } #[test] fn sutra_7_1_6() { let shi = d("SIN", Adadi); - assert_has_lat_a_3p(&[], &shi, &["Serate"]); - assert_has_lot_a_3p(&[], &shi, &["SeratAm"]); - assert_has_lan_a_3p(&[], &shi, &["aSerata"]); + assert_has_jha(&[], &shi, Lat, &["Serate"]); + assert_has_jha(&[], &shi, Lot, &["SeratAm"]); + assert_has_jha(&[], &shi, Lan, &["aSerata"]); } #[test] fn sutra_7_1_7() { let vid = d("vida~", Adadi); - assert_has_lat_a_3p(&["sam"], &vid, &["saMvidate", "saMvidrate"]); - assert_has_lot_a_3p( + assert_has_jha(&["sam"], &vid, Lat, &["saMvidate", "saMvidrate"]); + assert_has_jha( &["sam"], &vid, + Lot, &["saMvidatAm", "saMvidratAm", "saMvidANkurvatAm"], ); - assert_has_lan_a_3p(&["sam"], &vid, &["samavidata", "samavidrata"]); + assert_has_jha(&["sam"], &vid, Lan, &["samavidata", "samavidrata"]); } +// 7.1.8 is chAndasa + #[test] fn sutra_7_1_9() { assert_has_subantas("vfkza", Pum, Trtiya, Bahu, &["vfkzEH"]); @@ -164,6 +141,8 @@ fn sutra_7_1_9() { assert_has_subantas("atijarasa", Pum, Trtiya, Bahu, &["atijarasEH"]); } +// 7.1.10 is chAndasa + #[test] fn sutra_7_1_11() { assert_has_subantas("idam", Pum, Trtiya, Bahu, &["eBiH"]); @@ -324,6 +303,8 @@ fn sutra_7_1_25() { assert_has_subantas("nema", Napumsaka, Dvitiya, Eka, &["nemam"]); } +// 7.1.26 is chAndasa. + #[test] fn sutra_7_1_27() { assert_has_subantas("asmad", Pum, Sasthi, Eka, &["mama"]); @@ -388,7 +369,7 @@ fn sutra_7_1_34() { #[test] fn sutra_7_1_35() { assert_has_lot(&[], &d("jIva~", Bhvadi), &["jIvatAt", "jIvatu"]); - assert_has_lot_2s(&[], &d("jIva~", Bhvadi), &["jIvatAt", "jIva"]); + assert_has_sip(&[], &d("jIva~", Bhvadi), Lot, &["jIvatAt", "jIva"]); assert_has_lot_p(&[], &d("brUY", Adadi), &["brUtAt", "bravItu"]); } @@ -415,7 +396,7 @@ fn sutra_7_1_37() { // TODO: others } -// 7.1.38 - 7.1.50 are *chandasi*. +// 7.1.38 - 7.1.50 are chAndasa. #[ignore] #[test] @@ -445,7 +426,29 @@ fn sutra_7_1_54() { assert_has_subantas("vAyu", Pum, Sasthi, Bahu, &["vAyUnAm"]); assert_has_subantas("kartf", Pum, Sasthi, Bahu, &["kartFRAm"]); - // TODO: nadI, Ap + assert_has_subantas_p(&nyap("kumArI"), Stri, Sasthi, Bahu, &["kumArIRAm"]); + assert_has_subantas_p(&nyap("kiSorI"), Stri, Sasthi, Bahu, &["kiSorIRAm"]); + assert_has_subantas_p(&nyap("gOrI"), Stri, Sasthi, Bahu, &["gOrIRAm"]); + assert_has_subantas_p(&nyap("SArNgaravI"), Stri, Sasthi, Bahu, &["SArNgaravIRAm"]); + assert_has_subantas_p(&nyap("lakzmI"), Stri, Sasthi, Bahu, &["lakzmIRAm"]); + assert_has_subantas_p( + &nyap("brahmabanDU"), + Stri, + Sasthi, + Bahu, + &["brahmabanDUnAm"], + ); + assert_has_subantas_p(&nyap("vIrabanDU"), Stri, Sasthi, Bahu, &["vIrabanDUnAm"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, Sasthi, Bahu, &["KawvAnAm"]); + assert_has_subantas_p(&nyap("mAlA"), Stri, Sasthi, Bahu, &["mAlAnAm"]); + assert_has_subantas_p(&nyap("bahurAjA"), Stri, Sasthi, Bahu, &["bahurAjAnAm"]); + assert_has_subantas_p( + &nyap("kArIzaganDyA"), + Stri, + Sasthi, + Bahu, + &["kArIzaganDyAnAm"], + ); } #[ignore] @@ -465,13 +468,21 @@ fn sutra_7_1_58() { assert_has_krdanta(&[], &kund, Krt::tfc, &["kuRqitf"]); assert_has_krdanta(&[], &kund, Krt::tumun, &["kuRqitum"]); assert_has_krdanta(&[], &kund, Krt::tavya, &["kuRqitavya"]); + assert_has_krdanta(&[], &kund, Krt::a, &["kuRqA"]); let hund = d("huqi~\\", Bhvadi); assert_has_krdanta(&[], &hund, Krt::tfc, &["huRqitf"]); assert_has_krdanta(&[], &hund, Krt::tumun, &["huRqitum"]); assert_has_krdanta(&[], &hund, Krt::tavya, &["huRqitavya"]); + assert_has_krdanta(&[], &hund, Krt::a, &["huRqA"]); + + // no idit + assert_has_lat_p(&[], &d("qupa\\ca~^z", Bhvadi), &["pacati"]); + assert_has_lat_p(&[], &d("paWa~", Bhvadi), &["paWati"]); - // TODO: kundA, hundA + // irit is not idit + assert_has_krdanta(&[], &d("Bi\\di~^r", Rudhadi), Krt::tfc, &["Bettf"]); + assert_has_krdanta(&[], &d("Ci\\di~^r", Rudhadi), Krt::tfc, &["Cettf"]); } #[test] @@ -479,7 +490,7 @@ fn sutra_7_1_59() { let muc = d("mu\\cx~^", Tudadi); assert_has_lat_p(&[], &muc, &["muYcati"]); assert_has_lat_p(&[], &d("lu\\px~^", Tudadi), &["lumpati"]); - assert_has_lat_p(&[], &d("vidx~^", Tudadi), &["vindati"]); + assert_has_lat_p(&[], &d("vi\\dx~^", Tudadi), &["vindati"]); assert_has_lat_p(&[], &d("li\\pa~^", Tudadi), &["limpati"]); assert_has_lat_p(&[], &d("zi\\ca~^", Tudadi), &["siYcati"]); assert_has_lat_p(&[], &d("kftI~", Tudadi), &["kfntati"]); @@ -511,9 +522,8 @@ fn sutra_7_1_60() { assert_has_krdanta(&[], &masj, Krt::lyuw, &["majjana"]); assert_has_krdanta(&[], &nas, Krt::lyuw, &["naSana"]); - // TODO: enable these. - // assert_has_krdanta(&[], &masj, Krt::kta, &["magna"]); - // assert_has_krdanta(&[], &masj, Krt::ktavatu, &["magnavat"]); + assert_has_krdanta(&[], &masj, Krt::kta, &["magna"]); + assert_has_krdanta(&[], &masj, Krt::ktavatu, &["magnavat"]); } #[test] @@ -526,6 +536,8 @@ fn sutra_7_1_61() { &["ranDayati"], ); assert_has_krdanta(&[], &radh, Krt::Rvul, &["ranDaka"]); + assert_has_krdanta(&[], &radh, Krt::Rini, &["ranDin"]); + assert_has_krdanta(&[], &radh, Krt::Ramul, &["ranDam"]); assert_has_krdanta(&[], &radh, Krt::GaY, &["ranDa"]); assert_has_lat_p( @@ -534,11 +546,12 @@ fn sutra_7_1_61() { &["jamBayati"], ); assert_has_krdanta(&[], &jabh, Krt::Rvul, &["jamBaka"]); + assert_has_krdanta(&[], &jabh, Krt::Rini, &["jamBin"]); + assert_has_krdanta(&[], &jabh, Krt::Ramul, &["jamBam"]); assert_has_krdanta(&[], &jabh, Krt::GaY, &["jamBa"]); assert_has_krdanta(&[], &radh, Krt::tfc, &["radDf", "raDitf"]); assert_has_krdanta(&[], &jabh, Krt::yat, &["jaBya"]); - // TODO: other radh/jabh padas } #[test] @@ -549,8 +562,10 @@ fn sutra_7_1_62() { assert_has_krdanta(&[], &radh, Krt::tavya, &["raDitavya", "radDavya"]); assert_has_krdanta(&[], &radh, Krt::lyuw, &["ranDana"]); assert_has_krdanta(&[], &radh, Krt::Rvul, &["ranDaka"]); - assert_has_lit_p_1d(&[], &radh, &["raranDiva"]); - // TODO: other radh padas + assert_has_vas(&[], &radh, Lit, &["raranDiva"]); + assert_has_mas(&[], &radh, Lit, &["raranDima"]); + + // TODO: redhivas (we get *redhvas instead) } #[test] @@ -578,7 +593,7 @@ fn sutra_7_1_64() { &["lamBayati"], ); assert_has_krdanta(&[], &labh, Krt::Rvul, &["lamBaka"]); - assert_has_krdanta(&[], &labh, Krt::GaY, &["lamBa"]); + // TODO: lamBa? assert_has_lat(&[], &labh, &["laBate"]); assert_has_lit(&[], &labh, &["leBe"]); assert_has_krdanta(&[], &labh, Krt::tfc, &["labDf"]); @@ -598,6 +613,28 @@ fn sutra_7_1_66() { assert_has_krdanta(&["upa"], &labh, Krt::yat, &["upalamBya", "upalaBya"]); } +#[test] +fn sutra_7_1_67() { + let labh = d("qula\\Ba~\\z", Bhvadi); + assert_has_krdanta(&["pra"], &labh, Krt::Kal, &["pralamBa"]); + assert_has_krdanta(&["pra"], &labh, Krt::GaY, &["pralamBa"]); + assert_has_krdanta(&["vi", "pra"], &labh, Krt::GaY, &["vipralamBa"]); + // otherwise, ... + assert_has_krdanta(&[], &labh, Krt::GaY, &["lABa"]); +} + +#[test] +fn sutra_7_1_68() { + let labh = d("qula\\Ba~\\z", Bhvadi); + assert_has_krdanta(&["su"], &labh, Krt::GaY, &["sulABa"]); + assert_has_krdanta(&["dur"], &labh, Krt::GaY, &["durlABa"]); + + // kevalAbhyAm + assert_has_krdanta(&["su", "pra"], &labh, Krt::GaY, &["supralamBa"]); + assert_has_krdanta(&["dur", "pra"], &labh, Krt::GaY, &["duzpralamBa"]); + assert_has_krdanta(&["ati", "su"], &labh, Krt::GaY, &["atisulamBa"]); +} + #[test] fn sutra_7_1_69() { let labh = d("qula\\Ba~\\z", Bhvadi); @@ -621,7 +658,21 @@ fn sutra_7_1_72() { assert_has_subantas("trapu", Napumsaka, Prathama, Bahu, &["trapURi"]); assert_has_subantas("jatu", Napumsaka, Prathama, Bahu, &["jatUni"]); - // TODO: others + // napuMsakasya + assert_has_subantas("agnicit", Pum, Prathama, Eka, &["agnicit"]); + + // jhal-acaH + assert_has_subantas("bahupur", Napumsaka, Prathama, Bahu, &["bahupuri"]); + assert_has_subantas("vimaladiv", Napumsaka, Prathama, Bahu, &["vimaladivi"]); + assert_has_subantas("catur", Napumsaka, Prathama, Bahu, &["catvAri"]); + assert_has_subantas("ahan", Napumsaka, Prathama, Bahu, &["ahAni"]); + + assert_has_subantas("Sreyas", Napumsaka, Prathama, Bahu, &["SreyAMsi"]); + assert_has_subantas("BUyas", Napumsaka, Prathama, Bahu, &["BUyAMsi"]); + assert_has_subantas("kurvat", Napumsaka, Prathama, Bahu, &["kurvanti"]); + assert_has_subantas("kfzat", Napumsaka, Prathama, Bahu, &["kfzanti"]); + + // TODO: bahUrji } #[test] @@ -696,6 +747,14 @@ fn sutra_7_1_88() { assert_has_subantas("fBukzin", Pum, Caturthi, Eka, &["fBukze"]); } +#[ignore] +#[test] +fn sutra_7_1_89() { + assert_has_subantas("pums", Pum, Prathama, Eka, &["pumAn"]); + assert_has_subantas("pums", Pum, Prathama, Dvi, &["pumAMsO"]); + assert_has_subantas("pums", Pum, Prathama, Bahu, &["pumAMsaH"]); +} + #[test] fn sutra_7_1_90() { assert_has_subantas("go", Pum, Prathama, Eka, &["gOH"]); @@ -706,24 +765,8 @@ fn sutra_7_1_90() { #[test] fn sutra_7_1_91() { - use Purusha::*; - let assert = assert_has_parasmai_tinanta; - assert( - &[], - &d("qukf\\Y", Tanadi), - Lit, - Uttama, - Eka, - &["cakara", "cakAra"], - ); - assert( - &[], - &d("qupa\\ca~^z", Bhvadi), - Lit, - Uttama, - Eka, - &["papaca", "papAca"], - ); + assert_has_mip(&[], &d("qukf\\Y", Tanadi), Lit, &["cakara", "cakAra"]); + assert_has_mip(&[], &d("qupa\\ca~^z", Bhvadi), Lit, &["papaca", "papAca"]); } #[test] diff --git a/vidyut-prakriya/tests/pada_7_2.rs b/vidyut-prakriya/tests/pada_7_2.rs index f2796d9..ef4c0be 100644 --- a/vidyut-prakriya/tests/pada_7_2.rs +++ b/vidyut-prakriya/tests/pada_7_2.rs @@ -9,54 +9,10 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() -} - fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } -pub fn assert_has_lit_p_1d(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta( - prefixes, - dhatu, - Lakara::Lit, - Purusha::Uttama, - Vacana::Dvi, - expected, - ); -} - -pub fn assert_has_lit_p_2s(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta( - prefixes, - dhatu, - Lakara::Lit, - Purusha::Madhyama, - Vacana::Eka, - expected, - ); -} - -pub fn assert_has_lit_a_1d(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - let args = TinantaArgs::builder() - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Uttama) - .vacana(Vacana::Dvi) - .lakara(Lakara::Lit) - .pada(Pada::Atmane) - .build() - .unwrap(); - - let actual = derive_tinantas(&dhatu.clone().with_prefixes(prefixes), &args); - assert_padas(actual, expected); -} - #[test] fn sutra_7_2_1() { assert_has_lun_p(&[], &d("ci\\Y", Svadi), &["acEzIt"]); @@ -480,20 +436,21 @@ fn sutra_7_2_12() { #[test] fn sutra_7_2_13() { - assert_has_lit_p_1d(&[], &d("qukf\\Y", Tanadi), &["cakfva"]); - assert_has_lit_p_1d(&[], &d("sf\\", Bhvadi), &["sasfva"]); - assert_has_lit_p_1d(&[], &d("Bf\\Y", Bhvadi), &["baBfva"]); - assert_has_lit_p_1d( + assert_has_vas(&[], &d("qukf\\Y", Tanadi), Lit, &["cakfva"]); + assert_has_vas(&[], &d("sf\\", Bhvadi), Lit, &["sasfva"]); + assert_has_vas(&[], &d("Bf\\Y", Bhvadi), Lit, &["baBfva"]); + assert_has_vas( &[], &d("quBf\\Y", Juhotyadi), + Lit, &["baBfva", "biBarAYcakfva", "biBarAmAsiva", "biBarAmbaBUviva"], ); - assert_has_lit_p_1d(&[], &d("vfY", Svadi), &["vavfva"]); - assert_has_lit_a_1d(&[], &d("vfN", Kryadi), &["vavfvahe"]); - assert_has_lit_p_1d(&[], &d("zwu\\Y", Adadi), &["tuzwuva"]); - assert_has_lit_p_1d(&[], &d("dru\\", Bhvadi), &["dudruva"]); - assert_has_lit_p_1d(&[], &d("sru\\", Bhvadi), &["susruva"]); - assert_has_lit_p_1d(&[], &d("Sru\\", Bhvadi), &["SuSruva"]); + assert_has_vas(&[], &d("vfY", Svadi), Lit, &["vavfva"]); + assert_has_vahi(&[], &d("vfN", Kryadi), Lit, &["vavfvahe"]); + assert_has_vas(&[], &d("zwu\\Y", Adadi), Lit, &["tuzwuva"]); + assert_has_vas(&[], &d("dru\\", Bhvadi), Lit, &["dudruva"]); + assert_has_vas(&[], &d("sru\\", Bhvadi), Lit, &["susruva"]); + assert_has_vas(&[], &d("Sru\\", Bhvadi), Lit, &["SuSruva"]); } #[test] @@ -633,11 +590,55 @@ fn sutra_7_2_37() { assert_has_krdanta(&[], &grah, Krt::tfc, &["grahItf"]); assert_has_krdanta(&[], &grah, Krt::tumun, &["grahItum"]); assert_has_krdanta(&[], &grah, Krt::tavya, &["grahItavya"]); - assert_has_lit_p_1d(&[], &grah, &["jagfhiva"]); + assert_has_vas(&[], &grah, Lit, &["jagfhiva"]); assert_has_lut_karmani(&[], &grah, &["grAhitA", "grahItA"]); assert_has_lrt_karmani(&[], &grah, &["grAhizyate", "grahIzyate"]); } +#[test] +fn sutra_7_2_38() { + let vf1 = d("vfN", Kryadi); + let vf2 = d("vfY", Kryadi); + assert_has_krdanta(&[], &vf1, Krt::tfc, &["varitf", "varItf"]); + assert_has_krdanta(&["pra", "AN"], &vf2, Krt::tfc, &["prAvaritf", "prAvarItf"]); + // Ft + let tf = &d("tF", Bhvadi); + assert_has_krdanta(&[], &tf, Krt::tfc, &["taritf", "tarItf"]); + assert_has_krdanta( + &["AN"], + &d("stFY", Kryadi), + Krt::tfc, + &["Astaritf", "AstarItf"], + ); + // vFtaH? + assert_has_lrt_p(&[], &d("qukf\\Y", Tanadi), &["karizyati"]); + assert_has_lrt_p(&[], &d("hf\\Y", Bhvadi), &["harizyati"]); + // aliwi + assert_has_sip(&[], &d("vF", Kryadi), Lit, &["vavariTa"]); + assert_has_sip(&[], &tf, Lit, &["teriTa"]); +} + +#[test] +fn sutra_7_2_44() { + let svf = d("svf", Bhvadi); + assert_has_krdanta(&[], &svf, Krt::tfc, &["svartf", "svaritf"]); + let su = d("zUN", Adadi); + assert_has_krdanta(&["pra"], &su, Krt::tfc, &["prasotf", "prasavitf"]); + let su2 = d("zUN", Divadi); + assert_has_krdanta(&[], &su2, Krt::tfc, &["sotf", "savitf"]); + let dhu = d("DUY", Svadi); + assert_has_krdanta(&[], &dhu, Krt::tfc, &["Dotf", "Davitf"]); + let gah = d("gAhU~\\", Bhvadi); + assert_has_krdanta(&["vi"], &gah, Krt::tfc, &["vigAQf", "vigAhitf"]); + let gup = d("gupU~", Bhvadi); + assert_has_krdanta(&[], &gup, Krt::tfc, &["goptf", "gopitf", "gopAyitf"]); + + // Exclude su and dhu in tudAdi + assert_has_krdanta(&[], &d("zU", Tudadi), Krt::tfc, &["savitf"]); + // TODO: Davitf or Duvitf? + assert_has_krdanta(&[], &d("DU", Tudadi), Krt::tfc, &["Davitf"]); +} + #[test] fn sutra_7_2_45() { assert_has_krdanta(&[], &d("ra\\Da~", Divadi), Krt::tfc, &["radDf", "raDitf"]); @@ -868,26 +869,76 @@ fn sutra_7_2_58() { assert_has_lat(&["aDi"], &san(&gam), &["aDijigaMsate"]); } +#[test] +fn sutra_7_2_59() { + let vft = d("vftu~\\", Bhvadi); + assert_has_lrt(&[], &vft, &["vartsyati", "vartizyate"]); + assert_has_lrn(&[], &vft, &["avartsyat", "avartizyata"]); + assert_has_lat(&[], &san(&vft), &["vivftsati", "vivartizate"]); + + let vfdh = d("vfDu~\\", Bhvadi); + assert_has_lrt(&[], &vfdh, &["vartsyati", "varDizyate"]); + assert_has_lrn(&[], &vfdh, &["avartsyat", "avarDizyata"]); + assert_has_lat(&[], &san(&vfdh), &["vivftsati", "vivarDizate"]); + + let shfdh = d("SfDu~\\", Bhvadi); + assert_has_lrt(&[], &shfdh, &["Sartsyati", "SarDizyate"]); + assert_has_lrn(&[], &shfdh, &["aSartsyat", "aSarDizyata"]); + assert_has_lat(&[], &san(&shfdh), &["SiSftsati", "SiSarDizate"]); + + let syand = d("syandU~\\", Bhvadi); + assert_has_lrt(&[], &syand, &["syantsyati", "syandizyate", "syantsyate"]); + assert_has_lrn(&[], &syand, &["asyantsyat", "asyandizyata", "asyantsyata"]); + assert_has_lat( + &[], + &san(&syand), + &["sisyantsati", "sisyandizate", "sisyantsate"], + ); +} + +#[test] +fn sutra_7_2_60() { + let kfp = d("kfpU~\\", Bhvadi); + assert_has_lut_p(&[], &kfp, &["kalptA"]); + assert_has_lrt_p(&[], &kfp, &["kalpsyati"]); + assert_has_lrn_p(&[], &kfp, &["akalpsyat"]); + assert_has_lat_p(&[], &san(&kfp), &["cikxpsati"]); + // parasmaipadezu + assert_has_tinanta( + &[], + &kfp, + Lut, + Madhyama, + Eka, + &["kalptAsi", "kalptAse", "kalpitAse"], + ); + assert_has_lrt_a(&[], &kfp, &["kalpizyate", "kalpsyate"]); + assert_has_ashirlin_a(&[], &kfp, &["kalpizIzwa", "kxpsIzwa"]); + assert_has_lrn_a(&[], &kfp, &["akalpizyata", "akalpsyata"]); + assert_has_lat_a(&[], &san(&kfp), &["cikalpizate", "cikxpsate"]); +} + #[test] fn sutra_7_2_61() { // The four dhatus below (yA, ci, ni, hu) are vew per 7.2.63. let yaa = d("yA\\", Adadi); assert_has_krdanta(&[], &yaa, Krt::tfc, &["yAtf"]); - assert_has_lit_p_2s(&[], &yaa, &["yayATa", "yayiTa"]); + assert_has_sip(&[], &yaa, Lit, &["yayATa", "yayiTa"]); let ci = d("ci\\Y", Svadi); assert_has_krdanta(&[], &ci, Krt::tfc, &["cetf"]); - assert_has_lit_p_2s(&[], &ci, &["ciceTa", "cicayiTa", "cikeTa", "cikayiTa"]); + assert_has_sip(&[], &ci, Lit, &["ciceTa", "cicayiTa", "cikeTa", "cikayiTa"]); let ni = d("RI\\Y", Bhvadi); assert_has_krdanta(&[], &ni, Krt::tfc, &["netf"]); - assert_has_lit_p_2s(&[], &ni, &["nineTa", "ninayiTa"]); + assert_has_sip(&[], &ni, Lit, &["nineTa", "ninayiTa"]); let hu = d("hu\\", Juhotyadi); assert_has_krdanta(&[], &hu, Krt::tfc, &["hotf"]); - assert_has_lit_p_2s( + assert_has_sip( &[], &hu, + Lit, &[ "juhoTa", "juhaviTa", @@ -900,53 +951,58 @@ fn sutra_7_2_61() { // acaH let bhid = d("Bi\\di~^r", Rudhadi); assert_has_krdanta(&[], &bhid, Krt::tfc, &["Bettf"]); - assert_has_lit_p_2s(&[], &bhid, &["biBediTa"]); + assert_has_sip(&[], &bhid, Lit, &["biBediTa"]); // tAsvat let lu = d("lUY", Kryadi); assert_has_krdanta(&[], &lu, Krt::ktvA, &["lUtvA"]); - assert_has_lit_p_2s(&[], &lu, &["lulaviTa"]); + assert_has_sip(&[], &lu, Lit, &["lulaviTa"]); // Tali assert_has_parasmai_tinanta(&[], &yaa, Lit, Uttama, Dvi, &["yayiva"]); assert_has_parasmai_tinanta(&[], &yaa, Lit, Uttama, Bahu, &["yayima"]); // nityagrahaRam let dhu = d("DUY", Kryadi); assert_has_krdanta(&["vi"], &dhu, Krt::tfc, &["viDotf", "viDavitf"]); - assert_has_lit_p_2s(&["vi"], &dhu, &["viduDaviTa"]); + assert_has_sip(&["vi"], &dhu, Lit, &["viduDaviTa"]); } #[test] fn sutra_7_2_62() { let yaj = d("ya\\ja~^", Bhvadi); - assert_has_lit_p_2s(&[], &yaj, &["iyazWa", "iyajiTa"]); + assert_has_sip(&[], &yaj, Lit, &["iyazWa", "iyajiTa"]); } #[test] fn sutra_7_2_63() { let smf = d("smf\\", Bhvadi); assert_has_krdanta(&[], &smf, Krt::tfc, &["smartf"]); - assert_has_lit_p_2s(&[], &smf, &["sasmarTa"]); + assert_has_sip(&[], &smf, Lit, &["sasmarTa"]); let dhvf = d("Dvf\\", Bhvadi); assert_has_krdanta(&[], &dhvf, Krt::tfc, &["Dvartf"]); - assert_has_lit_p_2s(&[], &dhvf, &["daDvarTa"]); + assert_has_sip(&[], &dhvf, Lit, &["daDvarTa"]); // vikalpa for others - assert_has_lit_p_2s(&[], &d("yA\\", Adadi), &["yayiTa", "yayATa"]); - assert_has_lit_p_2s(&[], &d("vA\\", Adadi), &["vaviTa", "vavATa"]); - assert_has_lit_p_2s(&[], &d("qupa\\ca~^z", Adadi), &["peciTa", "papakTa"]); - assert_has_lit_p_2s(&[], &d("Sa\\kx~", Adadi), &["SekiTa", "SaSakTa"]); + assert_has_sip(&[], &d("yA\\", Adadi), Lit, &["yayiTa", "yayATa"]); + assert_has_sip(&[], &d("vA\\", Adadi), Lit, &["vaviTa", "vavATa"]); + assert_has_sip(&[], &d("qupa\\ca~^z", Adadi), Lit, &["peciTa", "papakTa"]); + assert_has_sip(&[], &d("Sa\\kx~", Adadi), Lit, &["SekiTa", "SaSakTa"]); } #[test] fn sutra_7_2_65() { - assert_has_lit_p_2s(&[], &d("sf\\ja~", Tudadi), &["sasrazWa", "sasarjiTa"]); - assert_has_lit_p_2s(&[], &d("df\\Si~r", Bhvadi), &["dadrazWa", "dadarSiTa"]); + assert_has_sip(&[], &d("sf\\ja~", Tudadi), Lit, &["sasrazWa", "sasarjiTa"]); + assert_has_sip(&[], &d("df\\Si~r", Bhvadi), Lit, &["dadrazWa", "dadarSiTa"]); } #[test] fn sutra_7_2_66() { // TODO: check jaGasTa - assert_has_lit_p_2s(&[], &d("a\\da~", Adadi), &["AdiTa", "jaGasiTa", "jaGasTa"]); - assert_has_lit_p_2s(&[], &d("f\\", Bhvadi), &["AriTa"]); - assert_has_lit_p_2s(&[], &d("vye\\Y", Bhvadi), &["vivyayiTa"]); + assert_has_sip( + &[], + &d("a\\da~", Adadi), + Lit, + &["AdiTa", "jaGasiTa", "jaGasTa"], + ); + assert_has_sip(&[], &d("f\\", Bhvadi), Lit, &["AriTa"]); + assert_has_sip(&[], &d("vye\\Y", Bhvadi), Lit, &["vivyayiTa"]); } #[test] @@ -1352,7 +1408,7 @@ fn sutra_7_2_100() { #[test] fn sutra_7_2_101() { use Vibhakti::*; - let jara = stri("jarA"); + let jara = nyap("jarA"); assert_has_subantas_p(&jara, Stri, Trtiya, Eka, &["jarasA", "jarayA"]); assert_has_subantas_p(&jara, Stri, Caturthi, Eka, &["jarase", "jarAyE"]); // aci diff --git a/vidyut-prakriya/tests/pada_7_3.rs b/vidyut-prakriya/tests/pada_7_3.rs index 8fa02a4..1a2da3d 100644 --- a/vidyut-prakriya/tests/pada_7_3.rs +++ b/vidyut-prakriya/tests/pada_7_3.rs @@ -4,18 +4,11 @@ use vidyut_prakriya::args::Gana::*; 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::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() -} - fn nic(u: &str, g: Gana) -> Dhatu { d(u, g).with_sanadi(&[Sanadi::Nic]) } @@ -24,24 +17,33 @@ fn yan_luk(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::YanLuk]) } -fn assert_has_lat_p_3d(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lat, Prathama, Dvi, expected) -} - -fn assert_has_lan_p_1s(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lan, Uttama, Eka, expected) +#[test] +fn sutra_7_3_1() { + assert_has_taddhitanta(&prati("devikA"), T::aR, &["dAvika"]); + assert_has_taddhitanta(&prati("SiMSapA"), T::aR, &["SAMSapa"]); + // TODO: dityavAh + assert_has_taddhitanta(&prati("dIrGasatra"), T::aR, &["dArGasatra"]); + assert_has_taddhitanta(&prati("Sreyas"), T::aR, &["SrAyasa"]); } -fn assert_has_lot_p_1s(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lot, Uttama, Eka, expected) +#[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"]); } -fn assert_has_lan_p_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, Lan, Prathama, Bahu, expected) -} +#[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"]); -fn assert_has_vidhilin_p_3p(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { - assert_has_parasmai_tinanta(prefixes, dhatu, VidhiLin, Prathama, Bahu, expected) + // TODO: others } #[test] @@ -176,7 +178,7 @@ fn sutra_7_3_40() { assert_has_lat( &[], &nic("YiBI\\", Juhotyadi), - &["BIzayate", "BApayate", "BAyayati"], + &["BIzayate", "BApayate", "BAyayati", "BAyayate"], ); } @@ -195,6 +197,13 @@ fn sutra_7_3_43() { assert_has_lat_p(&[], &nic("ru\\ha~", Bhvadi), &["ropayati", "rohayati"]); } +#[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"]); +} + #[test] fn sutra_7_3_52() { let pac = d("qupa\\ca~^z", Bhvadi); @@ -210,13 +219,14 @@ fn sutra_7_3_52() { #[test] fn sutra_7_3_54() { let han = d("ha\\na~", Adadi); + assert_has_parasmai_tinanta(&[], &han, Lat, Prathama, Bahu, &["Gnanti"]); + let han_nic = han.clone().with_sanadi(&[Sanadi::Nic]); assert_has_lat_p(&[], &han_nic, &["GAtayati"]); assert_has_krdanta(&[], &han, Krt::Rvul, &["GAtaka"]); assert_has_krdanta(&[], &han, Krt::Rini, &["GAtin"]); assert_has_krdanta(&[], &han, Krt::Ramul, &["GAtam"]); assert_has_krdanta(&[], &han, Krt::GaY, &["GAta"]); - assert_has_parasmai_tinanta(&[], &han, Lat, Prathama, Bahu, &["Gnanti"]); assert_has_parasmai_tinanta(&[], &han, Lot, Prathama, Bahu, &["Gnantu"]); assert_has_parasmai_tinanta(&[], &han, Lan, Prathama, Bahu, &["aGnan"]); // hanteH @@ -246,7 +256,7 @@ fn sutra_7_3_56() { assert_has_lat(&["pra"], &hi_yan, &["prajeGIyate"]); assert_has_lit(&["pra"], &hi, &["prajiGAya"]); // acaNi - assert_has_lun(&["pra"], &hi_nic, &["prAjIhayat"]); + assert_has_lun_p(&["pra"], &hi_nic, &["prAjIhayat"]); } #[test] @@ -300,10 +310,9 @@ fn sutra_7_3_60() { assert_has_krdanta(&["pari"], &vraj, Krt::Ryat, &["parivrAjya"]); } -#[ignore] #[test] fn sutra_7_3_63() { - let vanc = d("vancu~", Curadi); + let vanc = d("vancu~", Bhvadi); assert_has_krdanta(&[], &vanc, Krt::Ryat, &["vaYcya", "vaNkya"]); } @@ -508,12 +517,12 @@ fn sutra_7_3_82() { #[test] fn sutra_7_3_83() { - assert_has_lan_p_3p(&[], &d("hu\\", Juhotyadi), &["ajuhavuH"]); - assert_has_lan_p_3p(&[], &d("YiBI\\", Juhotyadi), &["abiBayuH"]); - assert_has_lan_p_3p(&[], &d("quBf\\Y", Juhotyadi), &["abiBaruH"]); + assert_has_jhi(&[], &d("hu\\", Juhotyadi), Lan, &["ajuhavuH"]); + assert_has_jhi(&[], &d("YiBI\\", Juhotyadi), Lan, &["abiBayuH"]); + assert_has_jhi(&[], &d("quBf\\Y", Juhotyadi), Lan, &["abiBaruH"]); - assert_has_vidhilin_p_3p(&[], &d("ci\\Y", Svadi), &["cinuyuH"]); - assert_has_vidhilin_p_3p(&[], &d("zu\\Y", Svadi), &["sunuyuH"]); + assert_has_jhi(&[], &d("ci\\Y", Svadi), VidhiLin, &["cinuyuH"]); + assert_has_jhi(&[], &d("zu\\Y", Svadi), VidhiLin, &["sunuyuH"]); } #[test] @@ -552,7 +561,7 @@ fn sutra_7_3_85() { &jagf, &["jajAgAra", "jAgarAYcakAra", "jAgarAmAsa", "jAgarAmbaBUva"], ); - assert_has_lat_p_3d(&[], &jagf, &["jAgftaH"]); + assert_has_tas(&[], &jagf, Lat, &["jAgftaH"]); } #[test] @@ -577,21 +586,21 @@ fn sutra_7_3_87() { let vij = d("vi\\ji~^r", Juhotyadi); let viz = d("vi\\zx~^", Juhotyadi); - assert_has_lot_p_1s(&[], &nij, &["nenijAni"]); - assert_has_lot_p_1s(&[], &vij, &["vevijAni"]); - assert_has_lot_p_1s(&["pari"], &viz, &["parivevizARi"]); + assert_has_mip(&[], &nij, Lot, &["nenijAni"]); + assert_has_mip(&[], &vij, Lot, &["vevijAni"]); + assert_has_mip(&["pari"], &viz, Lot, &["parivevizARi"]); - assert_has_lan_p_1s(&[], &nij, &["anenijam"]); - assert_has_lan_p_1s(&[], &vij, &["avevijam"]); - assert_has_lan_p_1s(&["pari"], &viz, &["paryavevizam"]); + assert_has_mip(&[], &nij, Lan, &["anenijam"]); + assert_has_mip(&[], &vij, Lan, &["avevijam"]); + assert_has_mip(&["pari"], &viz, Lan, &["paryavevizam"]); - assert_has_lot_p_1s(&[], &d("vida~", Adadi), &["vedAni", "vidANkaravARi"]); + assert_has_mip(&[], &d("vida~", Adadi), Lot, &["vedAni", "vidANkaravARi"]); assert_has_lat_p(&[], &nij, &["nenekti"]); assert_has_lit_p(&[], &nij, &["nineja"]); let hu = d("hu\\", Juhotyadi); - assert_has_lot_p_1s(&[], &hu, &["juhavAni"]); - assert_has_lan_p_1s(&[], &hu, &["ajuhavam"]); + assert_has_mip(&[], &hu, Lot, &["juhavAni"]); + assert_has_mip(&[], &hu, Lan, &["ajuhavam"]); // TODO: other examples } @@ -847,21 +856,21 @@ fn sutra_7_3_104() { #[test] fn sutra_7_3_105() { use Vibhakti::*; - assert_has_subantas_p(&stri("KawvA"), Stri, Trtiya, Eka, &["KawvayA"]); - assert_has_subantas_p(&stri("mAlA"), Stri, Trtiya, Eka, &["mAlayA"]); - assert_has_subantas_p(&stri("KawvA"), Stri, Sasthi, Dvi, &["KawvayoH"]); - assert_has_subantas_p(&stri("mAlA"), Stri, Sasthi, Dvi, &["mAlayoH"]); - assert_has_subantas_p(&stri("bahurAjA"), Stri, Trtiya, Eka, &["bahurAjayA"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, Trtiya, Eka, &["KawvayA"]); + assert_has_subantas_p(&nyap("mAlA"), Stri, Trtiya, Eka, &["mAlayA"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, Sasthi, Dvi, &["KawvayoH"]); + assert_has_subantas_p(&nyap("mAlA"), Stri, Sasthi, Dvi, &["mAlayoH"]); + assert_has_subantas_p(&nyap("bahurAjA"), Stri, Trtiya, Eka, &["bahurAjayA"]); assert_has_subantas_p( - &stri("kArIzaganDyA"), + &nyap("kArIzaganDyA"), Stri, Trtiya, Eka, &["kArIzaganDyayA"], ); - assert_has_subantas_p(&stri("bahurAjA"), Stri, Sasthi, Dvi, &["bahurAjayoH"]); + assert_has_subantas_p(&nyap("bahurAjA"), Stri, Sasthi, Dvi, &["bahurAjayoH"]); assert_has_subantas_p( - &stri("kArIzaganDyA"), + &nyap("kArIzaganDyA"), Stri, Sasthi, Dvi, @@ -872,10 +881,10 @@ fn sutra_7_3_105() { #[test] fn sutra_7_3_106() { - assert_has_subantas_p(&stri("KawvA"), Stri, V::Sambodhana, Eka, &["Kawve"]); - assert_has_subantas_p(&stri("bahurAjA"), Stri, V::Sambodhana, Eka, &["bahurAje"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, V::Sambodhana, Eka, &["Kawve"]); + assert_has_subantas_p(&nyap("bahurAjA"), Stri, V::Sambodhana, Eka, &["bahurAje"]); assert_has_subantas_p( - &stri("kArIzaganDyA"), + &nyap("kArIzaganDyA"), Stri, V::Sambodhana, Eka, @@ -885,13 +894,13 @@ fn sutra_7_3_106() { #[test] fn sutra_7_3_107() { - assert_has_subantas_p(&stri("ambA"), Stri, V::Sambodhana, Eka, &["amba"]); - assert_has_subantas_p(&stri("akkA"), Stri, V::Sambodhana, Eka, &["akka"]); - assert_has_subantas_p(&stri("allA"), Stri, V::Sambodhana, Eka, &["alla"]); + assert_has_subantas_p(&nyap("ambA"), Stri, V::Sambodhana, Eka, &["amba"]); + assert_has_subantas_p(&nyap("akkA"), Stri, V::Sambodhana, Eka, &["akka"]); + assert_has_subantas_p(&nyap("allA"), Stri, V::Sambodhana, Eka, &["alla"]); // nadyoH - assert_has_subantas_p(&stri("kumArI"), Stri, V::Sambodhana, Eka, &["kumAri"]); + assert_has_subantas_p(&nyap("kumArI"), Stri, V::Sambodhana, Eka, &["kumAri"]); assert_has_subantas_p( - &stri("SArNgaravI"), + &nyap("SArNgaravI"), Stri, V::Sambodhana, Eka, @@ -907,7 +916,7 @@ fn sutra_7_3_108() { assert_has_subantas("vAyu", Pum, V::Sambodhana, Eka, &["vAyo"]); assert_has_subantas("pawu", Pum, V::Sambodhana, Eka, &["pawo"]); // But, not for these because the prAtipadika was not originally hrasva - assert_has_subantas_p(&stri("kumArI"), Stri, V::Sambodhana, Eka, &["kumAri"]); + assert_has_subantas_p(&nyap("kumArI"), Stri, V::Sambodhana, Eka, &["kumAri"]); assert_has_subantas("brahmabanDU", Stri, V::Sambodhana, Eka, &["brahmabanDu"]); } @@ -962,19 +971,19 @@ fn sutra_7_3_112() { #[test] fn sutra_7_3_113() { use Vibhakti::*; - assert_has_subantas_p(&stri("KawvA"), Stri, Caturthi, Eka, &["KawvAyE"]); - assert_has_subantas_p(&stri("bahurAjA"), Stri, Caturthi, Eka, &["bahurAjAyE"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, Caturthi, Eka, &["KawvAyE"]); + assert_has_subantas_p(&nyap("bahurAjA"), Stri, Caturthi, Eka, &["bahurAjAyE"]); assert_has_subantas_p( - &stri("kArIzaganDyA"), + &nyap("kArIzaganDyA"), Stri, Caturthi, Eka, &["kArIzaganDyAyE"], ); - assert_has_subantas_p(&stri("KawvA"), Stri, Panchami, Eka, &["KawvAyAH"]); - assert_has_subantas_p(&stri("bahurAjA"), Stri, Panchami, Eka, &["bahurAjAyAH"]); + assert_has_subantas_p(&nyap("KawvA"), Stri, Panchami, Eka, &["KawvAyAH"]); + assert_has_subantas_p(&nyap("bahurAjA"), Stri, Panchami, Eka, &["bahurAjAyAH"]); assert_has_subantas_p( - &stri("kArIzaganDyA"), + &nyap("kArIzaganDyA"), Stri, Panchami, Eka, @@ -1003,8 +1012,8 @@ fn sutra_7_3_114() { #[test] fn sutra_7_3_116() { - assert_has_subantas_p(&stri("kumArI"), Stri, V::Saptami, Eka, &["kumAryAm"]); - assert_has_subantas_p(&stri("gOrI"), Stri, V::Saptami, Eka, &["gOryAm"]); + assert_has_subantas_p(&nyap("kumArI"), Stri, V::Saptami, Eka, &["kumAryAm"]); + assert_has_subantas_p(&nyap("gOrI"), Stri, V::Saptami, Eka, &["gOryAm"]); assert_has_subantas("brahmabanDU", Stri, V::Saptami, Eka, &["brahmabanDvAm"]); assert_has_subantas("DIBanDU", Stri, V::Saptami, Eka, &["DIBanDvAm"]); } diff --git a/vidyut-prakriya/tests/pada_7_4.rs b/vidyut-prakriya/tests/pada_7_4.rs index 456101e..76d2be8 100644 --- a/vidyut-prakriya/tests/pada_7_4.rs +++ b/vidyut-prakriya/tests/pada_7_4.rs @@ -6,10 +6,6 @@ use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } @@ -18,14 +14,34 @@ fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } +fn nic_san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Nic, Sanadi::San]) +} + fn yan(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Yan]) } +fn yan_san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Yan, Sanadi::San]) +} + fn yan_luk(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::YanLuk]) } +fn assert_has_ta(upasargas: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(&upasargas, &dhatu, la, Prathama, Eka, &expected); +} + +fn assert_has_atam(upasargas: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(&upasargas, &dhatu, la, Prathama, Dvi, &expected); +} + +fn assert_has_jha(upasargas: &[&str], dhatu: &Dhatu, la: Lakara, expected: &[&str]) { + assert_has_atmane_tinanta(&upasargas, &dhatu, la, Prathama, Bahu, &expected); +} + #[test] fn sutra_7_4_1() { assert_has_lun_p(&[], &nic(&d("qukf\\Y", Tanadi)), &["acIkarat"]); @@ -59,28 +75,71 @@ fn sutra_7_4_3() { assert_has_lun_p(&[], &d("pIqa~", Curadi), &["apIpiqat", "apipIqat"]); } +#[ignore] +#[test] +fn sutra_7_4_4() { + let paa_nic = nic(&d("pA\\", Bhvadi)); + assert_has_tip(&[], &paa_nic, Lun, &["apIpyat"]); + assert_has_tas(&[], &paa_nic, Lun, &["apIpyatAm"]); + assert_has_jhi(&[], &paa_nic, Lun, &["apIpyan"]); +} + +#[test] +fn sutra_7_4_5() { + let stha_nic = nic(&d("zWA\\", Bhvadi)); + assert_has_tip(&[], &stha_nic, Lun, &["atizWipat"]); + assert_has_tas(&[], &stha_nic, Lun, &["atizWipatAm"]); + assert_has_jhi(&[], &stha_nic, Lun, &["atizWipan"]); +} + +#[test] +fn sutra_7_4_6() { + let ghra_nic = nic(&d("GrA\\", Bhvadi)); + assert_has_tip(&[], &ghra_nic, Lun, &["ajiGripat", "ajiGrapat"]); + assert_has_tas(&[], &ghra_nic, Lun, &["ajiGripatAm", "ajiGrapatAm"]); + assert_has_jhi(&[], &ghra_nic, Lun, &["ajiGripan", "ajiGrapan"]); +} + +#[test] +fn sutra_7_4_7() { + assert_has_lun_p(&[], &d("kFta~", Curadi), &["acikIrtat", "acIkftat"]); + assert_has_lun_p(&[], &nic(&d("vftu~\\", Bhvadi)), &["avavartat", "avIvftat"]); + assert_has_lun_p(&[], &d("mfjU~", Curadi), &["amamArjat", "amImfjat"]); +} + +#[test] +fn sutra_7_4_9() { + let de = d("de\\N", Bhvadi); + assert_has_ta(&["ava"], &de, Lit, &["avadigye"]); + assert_has_atam(&["ava"], &de, Lit, &["avadigyAte"]); + assert_has_jha(&["ava"], &de, Lit, &["avadigyire"]); + + // TODO: show that `day` is not included. + // let day = d("daya~\\", Bhvadi); +} + #[test] fn sutra_7_4_10() { let svf = d("svf", Bhvadi); - assert_has_parasmai_tinanta(&[], &svf, Lit, Prathama, Dvi, &["sasvaratuH"]); - assert_has_parasmai_tinanta(&[], &svf, Lit, Prathama, Bahu, &["sasvaruH"]); + assert_has_tas(&[], &svf, Lit, &["sasvaratuH"]); + assert_has_jhi(&[], &svf, Lit, &["sasvaruH"]); let dhvf = d("Dvf\\", Bhvadi); - assert_has_parasmai_tinanta(&[], &dhvf, Lit, Prathama, Dvi, &["daDvaratuH"]); - assert_has_parasmai_tinanta(&[], &dhvf, Lit, Prathama, Bahu, &["daDvaruH"]); + assert_has_tas(&[], &dhvf, Lit, &["daDvaratuH"]); + assert_has_jhi(&[], &dhvf, Lit, &["daDvaruH"]); let smf = d("smf", Bhvadi); - assert_has_parasmai_tinanta(&[], &smf, Lit, Prathama, Dvi, &["sasmaratuH"]); - assert_has_parasmai_tinanta(&[], &smf, Lit, Prathama, Bahu, &["sasmaruH"]); + assert_has_tas(&[], &smf, Lit, &["sasmaratuH"]); + assert_has_jhi(&[], &smf, Lit, &["sasmaruH"]); // ftaH let kzi = d("kzi\\", Tudadi); - assert_has_parasmai_tinanta(&[], &kzi, Lit, Prathama, Dvi, &["cikziyatuH"]); - assert_has_parasmai_tinanta(&[], &kzi, Lit, Prathama, Bahu, &["cikziyuH"]); + assert_has_tas(&[], &kzi, Lit, &["cikziyatuH"]); + assert_has_jhi(&[], &kzi, Lit, &["cikziyuH"]); // saMyogAdeH let kf = d("qukf\\Y", Tanadi); - assert_has_parasmai_tinanta(&[], &kf, Lit, Prathama, Dvi, &["cakratuH"]); - assert_has_parasmai_tinanta(&[], &kf, Lit, Prathama, Bahu, &["cakruH"]); + assert_has_tas(&[], &kf, Lit, &["cakratuH"]); + assert_has_jhi(&[], &kf, Lit, &["cakruH"]); // vrddhi otherwise assert_has_lit_p(&[], &svf, &["sasvAra"]); assert_has_lit_p(&[], &smf, &["sasmAra"]); @@ -242,46 +301,25 @@ fn sutra_7_4_17() { #[test] fn sutra_7_4_18() { let svi = d("wuo~Svi", Bhvadi); - assert_has_parasmai_tinanta( - &[], - &svi, - Lun, - Prathama, - Eka, - &["aSvat", "aSvayIt", "aSiSviyat"], - ); - assert_has_parasmai_tinanta( - &[], - &svi, - Lun, - Prathama, - Dvi, - &["aSvatAm", "aSvayizwAm", "aSiSviyatAm"], - ); - assert_has_parasmai_tinanta( - &[], - &svi, - Lun, - Prathama, - Bahu, - &["aSvan", "aSvayizuH", "aSiSviyan"], - ); + assert_has_tip(&[], &svi, Lun, &["aSvat", "aSvayIt", "aSiSviyat"]); + assert_has_tas(&[], &svi, Lun, &["aSvatAm", "aSvayizwAm", "aSiSviyatAm"]); + assert_has_jhi(&[], &svi, Lun, &["aSvan", "aSvayizuH", "aSiSviyan"]); } #[test] fn sutra_7_4_19() { let pat = d("patx~", Bhvadi); - assert_has_parasmai_tinanta(&[], &pat, Lun, Prathama, Eka, &["apaptat"]); - assert_has_parasmai_tinanta(&[], &pat, Lun, Prathama, Dvi, &["apaptatAm"]); - assert_has_parasmai_tinanta(&[], &pat, Lun, Prathama, Bahu, &["apaptan"]); + assert_has_tip(&[], &pat, Lun, &["apaptat"]); + assert_has_tas(&[], &pat, Lun, &["apaptatAm"]); + assert_has_jhi(&[], &pat, Lun, &["apaptan"]); } #[test] fn sutra_7_4_20() { let vac = d("va\\ca~", Adadi); - assert_has_parasmai_tinanta(&[], &vac, Lun, Prathama, Eka, &["avocat"]); - assert_has_parasmai_tinanta(&[], &vac, Lun, Prathama, Dvi, &["avocatAm"]); - assert_has_parasmai_tinanta(&[], &vac, Lun, Prathama, Bahu, &["avocan"]); + assert_has_tip(&[], &vac, Lun, &["avocat"]); + assert_has_tas(&[], &vac, Lun, &["avocatAm"]); + assert_has_jhi(&[], &vac, Lun, &["avocan"]); } #[test] @@ -334,6 +372,15 @@ fn sutra_7_4_24() { assert_has_ashirlin(&["sam", "AN"], &i, &["sameyAt"]); } +#[test] +fn sutra_7_4_27() { + // TODO: others + + assert_has_lat(&[], &yan(&d("qukf\\Y", Tanadi)), &["cekrIyate"]); + assert_has_lat(&[], &yan(&d("kF", Tudadi)), &["cekIryate"]); + assert_has_lat(&["ni"], &yan(&d("gF", Tudadi)), &["nijegilyate"]); +} + #[test] fn sutra_7_4_28() { let d = d; @@ -503,6 +550,17 @@ fn sutra_7_4_55() { // si -- see examples above. } +#[test] +fn sutra_7_4_58() { + let qauk = d("QOkf~\\", Bhvadi); + let trauk = d("trOkf~\\", Bhvadi); + assert_has_lat(&[], &san(&qauk), &["quQOkizate"]); + assert_has_lat(&[], &san(&trauk), &["tutrOkizate"]); + // caNi + assert_has_lun_p(&[], &nic(&d("mI\\Y", Kryadi)), &["amImapat"]); + assert_has_lun_p(&[], &nic(&d("qudA\\Y", Juhotyadi)), &["adIdapat"]); +} + #[test] fn sutra_7_4_59() { let qauk = d("QOkf~\\", Bhvadi); @@ -577,7 +635,7 @@ fn sutra_7_4_66() { fn sutra_7_4_67() { let dyut = d("dyuta~\\", Bhvadi); assert_has_lit(&["vi"], &dyut, &["vididyute"]); - assert_has_lun(&["vi"], &nic(&dyut), &["vyadidyutat"]); + assert_has_lun_p(&["vi"], &nic(&dyut), &["vyadidyutat"]); assert_has_lat(&["vi"], &san(&dyut), &["vididyotizate", "vididyutizate"]); assert_has_lat(&["vi"], &yan(&dyut), &["videdyutyate"]); @@ -617,6 +675,37 @@ fn sutra_7_4_70() { assert_has_lit_p(&[], &d("paWa~", Bhvadi), &["papAWa"]); } +#[test] +fn sutra_7_4_71() { + let ang = d("agi~", Bhvadi); + assert_has_parasmai_tinanta(&[], &ang, Lit, Prathama, Eka, &["AnaNga"]); + assert_has_parasmai_tinanta(&[], &ang, Lit, Prathama, Dvi, &["AnaNgatuH"]); + assert_has_parasmai_tinanta(&[], &ang, Lit, Prathama, Bahu, &["AnaNguH"]); + let anj = d("anjU~", Rudhadi); + assert_has_parasmai_tinanta(&[], &anj, Lit, Prathama, Eka, &["AnaYja"]); + assert_has_parasmai_tinanta(&[], &anj, Lit, Prathama, Dvi, &["AnaYjatuH"]); + assert_has_parasmai_tinanta(&[], &anj, Lit, Prathama, Bahu, &["AnaYjuH"]); + // dvihalaH + let aw = d("awa~", Bhvadi); + assert_has_parasmai_tinanta(&[], &aw, Lit, Prathama, Eka, &["Awa"]); + assert_has_parasmai_tinanta(&[], &aw, Lit, Prathama, Dvi, &["AwatuH"]); + assert_has_parasmai_tinanta(&[], &aw, Lit, Prathama, Bahu, &["AwuH"]); + // TODO: AnfDatuH +} + +#[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"]); + // aSnAti + let ashnati = d("aSa~", Kryadi); + assert_has_parasmai_tinanta(&[], &ashnati, Lit, Prathama, Eka, &["ASa"]); + assert_has_parasmai_tinanta(&[], &ashnati, Lit, Prathama, Dvi, &["ASatuH"]); + assert_has_parasmai_tinanta(&[], &ashnati, Lit, Prathama, Bahu, &["ASuH"]); +} + #[test] fn sutra_7_4_73() { let bhu = d("BU", Bhvadi); @@ -676,13 +765,375 @@ fn sutra_7_4_79() { // TODO: pApacizate } -#[ignore] +#[test] +fn sutra_7_4_80() { + // pu + let pu = d("pUN", Bhvadi); + let bhu = d("BU", Bhvadi); + assert_has_lat(&[], &san(&pu), &["pipavizate"]); + assert_has_lat_p(&[], &nic_san(&pu), &["pipAvayizati"]); + assert_has_lat_p(&[], &nic_san(&bhu), &["biBAvayizati"]); + let yu = d("yu", Adadi); + let ru = d("ru", Adadi); + let lu = d("lUY", Kryadi); + assert_has_lat(&[], &san(&yu), &["yiyavizati", "yuyUzati"]); + assert_has_lat_p(&[], &nic_san(&yu), &["yiyAvayizati"]); + assert_has_lat_p(&[], &nic_san(&ru), &["rirAvayizati"]); + assert_has_lat_p(&[], &nic_san(&lu), &["lilAvayizati"]); + // ju (sautro dhatu) + let ju = d("ju", Adadi); + assert_has_lat_p(&[], &nic_san(&ju), &["jijAvayizati"]); + // oH + let pac = d("qupa\\ca~^z", Bhvadi); + assert_has_lat_a(&[], &yan(&pac), &["pApacyate"]); + assert_has_lat_a(&[], &yan_san(&pac), &["pApacizate"]); + // puyaNjyapare + let tu = d("tu\\", Adadi); + assert_has_lat_p(&["ava"], &nic_san(&tu), &["avatutAvayizati"]); + assert_has_lat_p(&[], &nic_san(&d("hu\\", Juhotyadi)), &["juhAvayizati"]); + assert_has_lat(&[], &san(&bhu), &["buBUzati"]); +} + +#[test] +fn sutra_7_4_82() { + assert_has_lat(&[], &yan(&d("ciY", Kryadi)), &["cecIyate"]); + assert_has_lat(&[], &yan(&d("lUY", Svadi)), &["lolUyate"]); + assert_has_lat( + &[], + &yan_luk(&d("hu\\", Juhotyadi)), + &["johavIti", "johoti"], + ); + assert_has_lat( + &[], + &yan_luk(&d("kru\\Sa~", Bhvadi)), + &["cokruSIti", "cokrozwi"], + ); +} + #[test] fn sutra_7_4_83() { let pac = d("qupa\\ca~^z", Bhvadi); assert_has_lat_a(&[], &yan(&pac), &["pApacyate"]); - assert_has_lat_p(&[], &yan_luk(&pac), &["pApacIti"]); + assert_has_lat(&[], &yan_luk(&pac), &["pApacIti", "pApakti"]); let yaj = d("ya\\ja~^", Bhvadi); assert_has_lat_a(&[], &yan(&yaj), &["yAyajyate"]); - assert_has_lat_p(&[], &yan_luk(&yaj), &["yAyajIti"]); + assert_has_lat(&[], &yan_luk(&yaj), &["yAyajIti", "yAyazwi"]); +} + +#[test] +fn sutra_7_4_84() { + let vanc = d("vancu~", Bhvadi); + assert_has_lat(&[], &yan(&vanc), &["vanIvacyate"]); + assert_has_lat(&[], &yan_luk(&vanc), &["vanIvaYcIti", "vanIvaNkti"]); + + let srans = d("sransu~\\", Bhvadi); + assert_has_lat(&[], &yan(&srans), &["sanIsrasyate"]); + assert_has_lat(&[], &yan_luk(&srans), &["sanIsraMsIti", "sanIsraMsti"]); + + let dhvans = d("Dvansu~\\", Bhvadi); + assert_has_lat(&[], &yan(&dhvans), &["danIDvasyate"]); + assert_has_lat(&[], &yan_luk(&dhvans), &["danIDvaMsIti", "danIDvaMsti"]); + + let bhrans = d("Bransu~\\", Bhvadi); + assert_has_lat(&[], &yan(&bhrans), &["banIBrasyate"]); + assert_has_lat(&[], &yan_luk(&bhrans), &["banIBraMsIti", "banIBraMsti"]); + + let kas = d("kasa~", Bhvadi); + assert_has_lat(&[], &yan(&kas), &["canIkasyate"]); + assert_has_lat(&[], &yan_luk(&kas), &["canIkasIti", "canIkasti"]); + + let pat = d("patx~", Bhvadi); + assert_has_lat(&[], &yan(&pat), &["panIpatyate"]); + assert_has_lat(&[], &yan_luk(&pat), &["panIpatIti", "panIpatti"]); + + let pad = d("pa\\da~\\", Divadi); + assert_has_lat(&[], &yan(&pad), &["panIpadyate"]); + assert_has_lat(&[], &yan_luk(&pad), &["panIpadIti", "panIpatti"]); + + let skand = d("ska\\ndi~r", Bhvadi); + assert_has_lat(&[], &yan(&skand), &["canIskadyate"]); + assert_has_lat( + &[], + &yan_luk(&skand), + &["canIskandIti", "canIskantti", "canIskanti"], + ); +} + +#[test] +fn sutra_7_4_85() { + let tan = d("tanu~^", Tanadi); + assert_has_lat(&[], &yan(&tan), &["tantanyate"]); + assert_has_lat(&[], &yan_luk(&tan), &["tantanIti", "tantanti"]); + + let gam = d("ga\\mx~", Bhvadi); + assert_has_lat(&[], &yan(&gam), &["jaNgamyate"]); + assert_has_lat(&[], &yan_luk(&gam), &["jaNgamIti", "jaNganti"]); + + let yam = d("ya\\ma~", Bhvadi); + assert_has_lat(&[], &yan(&yam), &["yaMyamyate"]); + assert_has_lat(&[], &yan_luk(&yam), &["yaMyamIti", "yaMyanti"]); + + let ram = d("ra\\ma~\\", Bhvadi); + assert_has_lat(&[], &yan(&ram), &["raMramyate"]); + assert_has_lat(&[], &yan_luk(&ram), &["raMramIti", "raMranti"]); + + // ataH + let tim = d("tima~", Bhvadi); + assert_has_lat(&[], &yan(&tim), &["tetimyate"]); + + // TODO: taparakaraNa + // let bham = d("BAma", Curadi); + // assert_has_lat(&[], &yan(&bham), &["bABamyate"]); + + // anunAsikAntasya + let pac = d("qupa\\ca~^z", Bhvadi); + assert_has_lat(&[], &yan(&pac), &["pApacyate"]); +} + +#[test] +fn sutra_7_4_86() { + let jap = d("japa~", Bhvadi); + assert_has_lat(&[], &yan(&jap), &["jaYjapyate"]); + assert_has_lat(&[], &yan_luk(&jap), &["jaYjapIti", "jaYjapti"]); + + let jabh = d("jaBI~\\", Bhvadi); + assert_has_lat(&[], &yan(&jabh), &["jaYjaByate"]); + assert_has_lat(&[], &yan_luk(&jabh), &["jaYjaBIti", "jaYjabDi"]); + + let dah = d("da\\ha~", Bhvadi); + assert_has_lat(&[], &yan(&dah), &["dandahyate"]); + assert_has_lat(&[], &yan_luk(&dah), &["dandahIti", "dandagDi"]); + + let dash = d("da\\nSa~", Bhvadi); + assert_has_lat(&[], &yan(&dash), &["dandaSyate"]); + assert_has_lat(&[], &yan_luk(&dash), &["dandaSIti", "dandazwi"]); + + let bhanj = d("Ba\\njo~", Rudhadi); + assert_has_lat(&[], &yan(&bhanj), &["bamBajyate"]); + assert_has_lat(&[], &yan_luk(&bhanj), &["bamBaYjIti", "bamBaNkti"]); + + let pash = d("paSa~", Bhvadi); + assert_has_lat(&[], &yan(&pash), &["pampaSyate"]); + assert_has_lat(&[], &yan_luk(&pash), &["pampaSIti", "pampazwi"]); +} + +#[ignore] +#[test] +fn sutra_7_4_87_and_sutra_7_4_88() { + let car = d("cara~", Bhvadi); + assert_has_lat(&[], &yan(&car), &["caYcUryate"]); + // TODO: caYcUrIti or caYcurIti? + assert_has_lat(&[], &yan_luk(&car), &["caYcurIti", "caYcUrti"]); + + let phal = d("Pala~", Bhvadi); + assert_has_lat(&[], &yan(&phal), &["pamPulyate"]); + assert_has_lat(&[], &yan_luk(&phal), &["pamPulIti", "pamPulti"]); +} + +#[test] +fn sutra_7_4_90() { + let vft = d("vftu~\\", Bhvadi); + assert_has_lat(&[], &yan(&vft), &["varIvftyate"]); + assert_has_lat( + &[], + &yan_luk(&vft), + &[ + "varIvarti", + "varIvartti", + "varIvftIti", + "varivarti", + "varivartti", + "varivftIti", + "varvarti", + "varvartti", + "varvftIti", + ], + ); + + let vfdh = d("vfDU~\\", Bhvadi); + assert_has_lat(&[], &yan(&vfdh), &["varIvfDyate"]); + assert_has_lat( + &[], + &yan_luk(&vfdh), + &[ + "varIvarDi", + "varIvardDi", + "varIvfDIti", + "varivarDi", + "varivardDi", + "varivfDIti", + "varvarDi", + "varvardDi", + "varvfDIti", + ], + ); + + let nft = d("nftI~", Divadi); + assert_has_lat(&[], &yan(&nft), &["narInftyate"]); + assert_has_lat( + &[], + &yan_luk(&nft), + &[ + "narInarti", + "narInartti", + "narInftIti", + "narinarti", + "narinartti", + "narinftIti", + "narnarti", + "narnartti", + "narnftIti", + ], + ); +} + +#[test] +fn sutra_7_4_90_v1() { + assert_has_lat(&[], &yan(&d("o~vrascU~", Tudadi)), &["varIvfScyate"]); + assert_has_lat(&[], &yan(&d("pra\\Ca~", Tudadi)), &["parIpfcCyate"]); +} + +#[test] +fn sutra_7_4_91() { + assert_has_lat( + &[], + &yan_luk(&d("nftI~", Divadi)), + &[ + "narnartti", + "narinartti", + "narInartti", + "narnarti", + "narinarti", + "narInarti", + "narnftIti", + "narinftIti", + "narInftIti", + ], + ); + assert_has_lat( + &[], + &yan_luk(&d("vftu~\\", Bhvadi)), + &[ + "varvartti", + "varivartti", + "varIvartti", + "varvarti", + "varivarti", + "varIvarti", + "varvftIti", + "varivftIti", + "varIvftIti", + ], + ); +} + +#[ignore] +#[test] +fn sutra_7_4_92() { + assert_has_lat( + &[], + &yan_luk(&d("qukf\\Y", Tanadi)), + &[ + "carIkarIti", + "carIkarti", + "carikarIti", + "carikarti", + "carkarIti", + "carkarti", + ], + ); + assert_has_lat( + &[], + &yan_luk(&d("hf\\Y", Bhvadi)), + &[ + "jarIharIti", + "jarIharti", + "jarharIti", + "jarharti", + "jariharIti", + "jariharti", + ], + ); + // taparakaraNa + assert_has_lat(&[], &yan_luk(&d("kF", Tudadi)), &["cAkarti"]); +} + +#[test] +fn sutra_7_4_93() { + let pac = &d("qupa\\ca~^z", Bhvadi); + + // sanyataH + assert_has_lun_p(&[], &nic(&d("qukf\\Y", Tanadi)), &["acIkarat"]); + assert_has_lun_p(&[], &nic(&pac), &["apIpacat"]); + // oH puyaRjyapare + assert_has_lun_p(&[], &nic(&d("pUY", Kryadi)), &["apIpavat"]); + assert_has_lun_p(&[], &nic(&d("lUY", Kryadi)), &["alIlavat"]); + // svarati... (7.4.81) + assert_has_lun_p(&[], &nic(&d("sru\\", Bhvadi)), &["asisravat", "asusravat"]); + assert_has_lun_p(&[], &nic(&d("Sru\\", Svadi)), &["aSiSravat", "aSuSravat"]); + assert_has_lun_p(&[], &nic(&d("dru\\", Bhvadi)), &["adidravat", "adudravat"]); + assert_has_lun_p(&[], &nic(&d("pru\\N", Bhvadi)), &["apipravat", "apupravat"]); + assert_has_lun_p(&[], &nic(&d("plu\\N", Bhvadi)), &["apiplavat", "apuplavat"]); + assert_has_lun_p(&[], &nic(&d("cyu\\N", Bhvadi)), &["acicyavat", "acucyavat"]); + // laghuni + assert_has_lun_p(&[], &nic(&d("takzU~", Bhvadi)), &["atatakzat"]); + assert_has_lun_p(&[], &nic(&d("rakza~", Bhvadi)), &["ararakzat"]); + assert_has_lun_p(&[], &nic(&d("jAgf", Adadi)), &["ajajAgarat"]); + // caN-pare? + assert_has_parasmai_tinanta(&[], &pac, Lit, Uttama, Eka, &["papaca", "papAca"]); + // para-grahaRa + assert_has_lun_a(&[], &d("kamu~\\", Bhvadi), &["acakamata", "acIkamata"]); + // an-ak-lopa + assert_has_lun_p(&[], &d("kaTa", Curadi), &["acakaTat"]); + // TODO: others +} + +#[test] +fn sutra_7_4_94() { + let pac = &d("qupa\\ca~^z", Bhvadi); + assert_has_lun_p(&[], &nic(&d("qukf\\Y", Tanadi)), &["acIkarat"]); + assert_has_lun_p(&[], &nic(&d("hf\\Y", Bhvadi)), &["ajIharat"]); + assert_has_lun_p(&[], &nic(&d("lUY", Kryadi)), &["alIlavat"]); + assert_has_lun_p(&[], &nic(&pac), &["apIpacat"]); + // laghoH + // abiBrajat is allowed by 7.4.3. + assert_has_lun_p( + &[], + &nic(&d("wuBrAjf~\\", Bhvadi)), + &["abiBrajat", "abaBrAjat"], + ); + // laghuni + assert_has_lun_p(&[], &nic(&d("takzU~", Bhvadi)), &["atatakzat"]); + assert_has_lun_p(&[], &nic(&d("rakza~", Bhvadi)), &["ararakzat"]); + // caNi + assert_has_mip(&[], &pac, Lit, &["papaca", "papAca"]); + // pare + assert_has_lun_a(&[], &d("kamu~\\", Bhvadi), &["acakamata", "acIkamata"]); + // anaglopa + assert_has_lun_p(&[], &d("kaTa", Curadi), &["acakaTat"]); +} + +#[test] +fn sutra_7_4_95() { + assert_has_lun_p(&[], &nic(&d("smf", Bhvadi)), &["asasmarat"]); + assert_has_lun_p(&[], &nic(&d("dF", Bhvadi)), &["adadarat"]); + assert_has_lun_p(&[], &nic(&d("YitvarA~\\", Bhvadi)), &["atatvarat"]); + assert_has_lun_p(&[], &d("praTa~", Curadi), &["apapraTat"]); + assert_has_lun_p(&[], &nic(&d("mrada~\\", Bhvadi)), &["amamradat"]); + assert_has_lun_p(&[], &nic(&d("stFY", Kryadi)), &["atastarat"]); + assert_has_lun_p(&[], &nic(&d("spaSa~^", Bhvadi)), &["apaspaSat"]); +} + +#[test] +fn sutra_7_4_96() { + let vest = d("vezwa~\\", Bhvadi); + let cest = d("cezwa~\\", Bhvadi); + assert_has_lun_p(&[], &nic(&vest), &["avavezwat", "avivezwat"]); + assert_has_lun_p(&[], &nic(&cest), &["acacezwat", "acicezwat"]); +} + +#[test] +fn sutra_7_4_97() { + let gan = d("gaRa", Curadi); + assert_has_lun_p(&[], &gan, &["ajIgaRat", "ajagaRat"]); } diff --git a/vidyut-prakriya/tests/pada_8_2.rs b/vidyut-prakriya/tests/pada_8_2.rs index cf432a6..3d9ff22 100644 --- a/vidyut-prakriya/tests/pada_8_2.rs +++ b/vidyut-prakriya/tests/pada_8_2.rs @@ -8,10 +8,6 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } @@ -20,8 +16,16 @@ fn yan(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Yan]) } -fn prati(text: &str) -> Pratipadika { - Pratipadika::builder().text(text).build().unwrap() +fn prati_udit(text: &str) -> Pratipadika { + Pratipadika::builder() + .text(text) + .is_udit(true) + .build() + .unwrap() +} + +pub fn assert_has_krta(prefixes: &[&str], dhatu: &Dhatu, expected: &[&str]) { + assert_has_krdanta(&prefixes, &dhatu, Krt::kta, &expected); } #[test] @@ -124,6 +128,26 @@ fn sutra_8_2_21() { // TODO: others. } +#[test] +fn sutra_8_2_23() { + assert_has_subantas_p(&prati_udit("gomat"), Pum, Prathama, Eka, &["gomAn"]); + assert_has_subantas_p(&prati_udit("yavamat"), Pum, Prathama, Eka, &["yavamAn"]); + assert_has_subantas_p(&prati_udit("kftavat"), Pum, Prathama, Eka, &["kftavAn"]); + assert_has_subantas_p(&prati_udit("hatavat"), Pum, Prathama, Eka, &["hatavAn"]); + assert_has_subantas_p(&prati_udit("Sreyas"), Pum, Prathama, Eka, &["SreyAn"]); + assert_has_subantas_p(&prati_udit("BUyas"), Pum, Prathama, Eka, &["BUyAn"]); + // TODO: others +} + +#[ignore] +#[test] +fn sutra_8_2_24() { + assert_has_subantas("mAtf", Stri, Sasthi, Eka, &["mAtuH"]); + assert_has_subantas("pitf", Pum, Sasthi, Eka, &["pituH"]); + assert_has_subantas("Urj", Pum, Prathama, Eka, &["Urk"]); + assert_has_lan(&[], &d("mfjU~", Adadi), &["amArw"]); +} + #[test] fn sutra_8_2_26() { use Purusha::*; @@ -232,12 +256,14 @@ fn sutra_8_2_31() { assert_has_krdanta(&[], &sah, Krt::tfc, &["soQf", "sahitf"]); assert_has_krdanta(&[], &sah, Krt::tumun, &["soQum", "sahitum"]); assert_has_krdanta(&[], &sah, Krt::tavya, &["soQavya", "sahitavya"]); + assert_has_subantas("jalAzAh", Pum, Prathama, Eka, &["jalAzAw"]); let vah = Dhatu::new("va\\ha~^", Bhvadi); assert_has_krdanta(&[], &vah, Krt::tfc, &["voQf"]); assert_has_krdanta(&[], &vah, Krt::tumun, &["voQum"]); assert_has_krdanta(&[], &vah, Krt::tavya, &["voQavya"]); - // TODO: jalAzAt, dityavAw + assert_has_subantas("prazWavAh", Pum, Prathama, Eka, &["prazWavAw"]); + assert_has_subantas("dityavAh", Pum, Prathama, Eka, &["dityavAw"]); } #[test] @@ -252,13 +278,215 @@ fn sutra_8_2_32() { assert_has_krdanta(&[], &duh, Krt::tumun, &["dogDum"]); assert_has_krdanta(&[], &duh, Krt::tavya, &["dogDavya"]); - let lih = Dhatu::new("li\\ha~^", Bhvadi); + let lih = Dhatu::new("li\\ha~^", Adadi); assert_has_krdanta(&[], &lih, Krt::tfc, &["leQf"]); assert_has_krdanta(&[], &lih, Krt::tumun, &["leQum"]); assert_has_krdanta(&[], &lih, Krt::tavya, &["leQavya"]); // TODO: kAzWaDak, etc. } +#[ignore] +#[test] +fn sutra_8_2_33() { + let druh = d("dru\\ha~", Divadi); + assert_has_krdanta(&[], &druh, Krt::tfc, &["drogDf", "droQf", "drohitf"]); + assert_has_krdanta(&[], &druh, Krt::kvip, &["Druk", "Druw"]); + let muh = d("mu\\ha~", Divadi); + assert_has_krdanta(&["ud"], &muh, Krt::tfc, &["unmogDf", "unmoQf", "unmohitf"]); + // TODO: why muN? + // assert_has_krdanta(&[], &muh, Krt::kvip, &["muk", "muN"]); + let snuh = d("zRu\\ha~", Divadi); + assert_has_krdanta( + &["ud"], + &snuh, + Krt::tfc, + &["utsnogDf", "utsnoQf", "utsnohitf"], + ); + assert_has_krdanta(&["ud"], &snuh, Krt::kvip, &["utsnuk", "utsnuw"]); + let snih = d("zRi\\ha~", Divadi); + assert_has_krdanta(&[], &snih, Krt::tfc, &["snegDf", "sneQf", "snehitf"]); + assert_has_krdanta(&[], &snih, Krt::kvip, &["snik", "sniw"]); +} + +#[test] +fn sutra_8_2_34() { + let nah = d("Ra\\ha~^", Divadi); + assert_has_krdanta(&[], &nah, Krt::tfc, &["nadDf"]); + assert_has_krdanta(&[], &nah, Krt::tumun, &["nadDum"]); + assert_has_krdanta(&[], &nah, Krt::tavya, &["nadDavya"]); + // TODO: upAnat, etc. +} + +#[test] +fn sutra_8_2_35() { + let bru = d("brUY", Adadi); + assert_has_sip(&[], &bru, Lat, &["AtTa", "bravIzi"]); + // otherwise -- + assert_has_tip(&[], &bru, Lat, &["Aha", "bravIti"]); + assert_has_tas(&[], &bru, Lat, &["AhatuH", "brUtaH"]); + assert_has_jhi(&[], &bru, Lat, &["AhuH", "bruvanti"]); +} + +#[ignore] +#[test] +fn sutra_8_2_36() { + let vrasc = d("o~vrascU~", Tudadi); + assert_has_krdanta(&[], &vrasc, Krt::tfc, &["vrazwf", "vraScitf"]); + assert_has_krdanta(&[], &vrasc, Krt::tumun, &["vrazwum", "vraScitum"]); + assert_has_krdanta(&[], &vrasc, Krt::tavya, &["vrazwavya", "vraScitavya"]); + assert_has_krdanta(&[], &vrasc, Krt::kvip, &["vfw"]); + + let bhrasj = d("Bra\\sja~^", Tudadi); + assert_has_krdanta(&[], &bhrasj, Krt::tfc, &["Brazwf", "Barzwf"]); + assert_has_krdanta(&[], &bhrasj, Krt::tumun, &["Brazwum", "Barzwum"]); + assert_has_krdanta(&[], &bhrasj, Krt::tavya, &["Brazwavya", "Barzwavya"]); + assert_has_krdanta(&[], &bhrasj, Krt::kvip, &["Bfw"]); + + let sfj = d("sf\\ja~\\", Tudadi); + assert_has_krdanta(&[], &sfj, Krt::tfc, &["srazwf"]); + assert_has_krdanta(&[], &sfj, Krt::tumun, &["srazwum"]); + assert_has_krdanta(&[], &sfj, Krt::tavya, &["srazwavya"]); + assert_has_krdanta(&[], &sfj, Krt::kvip, &["sfw"]); + + let mfj = d("mfjU~", Adadi); + assert_has_krdanta(&[], &mfj, Krt::tfc, &["mArzwf", "mArjitf"]); + assert_has_krdanta(&[], &mfj, Krt::tumun, &["mArzwum", "mArjitum"]); + assert_has_krdanta(&[], &mfj, Krt::tavya, &["mArzwavya", "mArjitavya"]); + assert_has_krdanta(&[], &mfj, Krt::kvip, &["mfw"]); + + let yaj = d("ya\\ja~^", Bhvadi); + assert_has_krdanta(&[], &yaj, Krt::tfc, &["yazwf"]); + assert_has_krdanta(&[], &yaj, Krt::tumun, &["yazwum"]); + assert_has_krdanta(&[], &yaj, Krt::tavya, &["yazwavya"]); + + let raj = d("rAjf~^", Bhvadi); + assert_has_krdanta(&[], &raj, Krt::kvip, &["rAw"]); + + let bhraj = d("BrAjf~\\", Bhvadi); + assert_has_krdanta(&[], &bhraj, Krt::kvip, &["BrAw"]); + + let prach = d("pra\\Ca~", Tudadi); + assert_has_krdanta(&[], &prach, Krt::tfc, &["prazwf"]); + assert_has_krdanta(&[], &prach, Krt::tumun, &["prazwum"]); + assert_has_krdanta(&[], &prach, Krt::tavya, &["prazwavya"]); + + let lish = d("li\\Sa~", Tudadi); + assert_has_krdanta(&[], &lish, Krt::tfc, &["lezwf"]); + assert_has_krdanta(&[], &lish, Krt::tumun, &["lezwum"]); + assert_has_krdanta(&[], &lish, Krt::tavya, &["lezwavya"]); + assert_has_krdanta(&[], &lish, Krt::kvip, &["liw"]); + + let vish = d("vi\\Sa~", Tudadi); + assert_has_krdanta(&[], &vish, Krt::tfc, &["vezwf"]); + assert_has_krdanta(&[], &vish, Krt::tumun, &["vezwum"]); + assert_has_krdanta(&[], &vish, Krt::tavya, &["vezwavya"]); + assert_has_krdanta(&[], &vish, Krt::kvip, &["viw"]); + + // TODO: others +} + +#[ignore] +#[test] +fn sutra_8_2_37() { + let budh = d("bu\\Da~\\", Divadi); + assert_has_lrt(&[], &budh, &["Botsyate"]); + assert_has_dhvam(&[], &budh, Lun, &["aBudDvam"]); + assert_has_krdanta(&[], &budh, Krt::kvip, &["But"]); + + let guh = d("guhU~^", Bhvadi); + assert_has_lrt_a(&["ni"], &guh, &["niGokzyate", "nigUhizyate"]); + assert_has_dhvam( + &["ni"], + &guh, + Lun, + &["nyaGUQvam", "nyaGukzaDvam", "nyagUhiDvam", "nyagUhiQvam"], + ); + assert_has_krdanta(&[], &guh, Krt::kvip, &["Guw"]); + + let duh = d("du\\ha~^", Adadi); + assert_has_lrt_a(&[], &duh, &["Dokzyate"]); + assert_has_dhvam(&[], &duh, Lun, &["aDugDvam", "aDukzaDvam"]); + assert_has_krdanta(&[], &duh, Krt::kvip, &["Duk"]); + + // baS? + assert_has_lrt(&[], &d("kru\\Da~", Divadi), &["krotsyati"]); + + // Jazantasya? + assert_has_lrt_p(&[], &d("qudA\\Y", Juhotyadi), &["dAsyati"]); + + // sDvoH? + assert_has_krdanta(&[], &budh, Krt::tfc, &["bodDf"]); + assert_has_krdanta(&[], &budh, Krt::tumun, &["bodDum"]); + assert_has_krdanta(&[], &budh, Krt::tavya, &["bodDavya"]); + + // TODO: others +} + +#[test] +fn sutra_8_2_38() { + let dha = d("quDA\\Y", Juhotyadi); + assert_has_tas(&[], &dha, Lat, &["DattaH"]); + assert_has_thas(&[], &dha, Lat, &["DatTaH"]); + assert_has_thaas(&[], &dha, Lat, &["Datse"]); + assert_has_dhvam(&[], &dha, Lot, &["DadDvam"]); + + // Jazantasya? + assert_has_tip(&[], &dha, Lat, &["daDAti"]); +} + +#[test] +fn sutra_8_2_40() { + let labh = d("qula\\Ba~\\z", Bhvadi); + assert_has_krdanta(&[], &labh, Krt::tfc, &["labDf"]); + assert_has_krdanta(&[], &labh, Krt::tumun, &["labDum"]); + assert_has_krdanta(&[], &labh, Krt::tavya, &["labDavya"]); + assert_has_ta(&[], &labh, Lun, &["alabDa"]); + assert_has_thaas(&[], &labh, Lun, &["alabDAH"]); + + let duh = Dhatu::new("du\\ha~^", Bhvadi); + assert_has_krdanta(&[], &duh, Krt::tfc, &["dogDf"]); + assert_has_krdanta(&[], &duh, Krt::tumun, &["dogDum"]); + assert_has_krdanta(&[], &duh, Krt::tavya, &["dogDavya"]); + assert_has_ta(&[], &duh, Lun, &["adugDa", "aDukzata"]); + assert_has_thaas(&[], &duh, Lun, &["adugDAH", "aDukzaTAH"]); + + let lih = Dhatu::new("li\\ha~^", Adadi); + assert_has_krdanta(&[], &lih, Krt::tfc, &["leQf"]); + assert_has_krdanta(&[], &lih, Krt::tumun, &["leQum"]); + assert_has_krdanta(&[], &lih, Krt::tavya, &["leQavya"]); + assert_has_ta(&[], &lih, Lun, &["alIQa", "alikzata"]); + assert_has_thaas(&[], &lih, Lun, &["alIQAH", "alikzaTAH"]); + + let budh = d("bu\\Da~\\", Divadi); + assert_has_krdanta(&[], &budh, Krt::tfc, &["bodDf"]); + assert_has_krdanta(&[], &budh, Krt::tumun, &["bodDum"]); + assert_has_krdanta(&[], &budh, Krt::tavya, &["bodDavya"]); + assert_has_ta(&[], &budh, Lun, &["abudDa"]); + assert_has_thaas(&[], &budh, Lun, &["abudDAH"]); + + // aDaH? + let dha = d("quDA\\Y", Juhotyadi); + assert_has_tas(&[], &dha, Lat, &["DattaH"]); + assert_has_thas(&[], &dha, Lat, &["DatTaH"]); +} + +#[test] +fn sutra_8_2_41() { + let pish = Dhatu::new("pi\\zx~", Rudhadi); + assert_has_lrt(&[], &pish, &["pekzyati"]); + assert_has_lrn(&[], &pish, &["apekzyat"]); + assert_has_lat(&[], &san(&pish), &["pipikzati"]); + + let lih = Dhatu::new("li\\ha~^", Adadi); + assert_has_lrt_p(&[], &lih, &["lekzyati"]); + assert_has_lrn_p(&[], &lih, &["alekzyat"]); + assert_has_lat_p(&[], &san(&lih), &["lilikzati"]); + + // si? + assert_has_lat_p(&[], &pish, &["pinazwi"]); + assert_has_lat_p(&[], &lih, &["leQi"]); +} + #[test] fn sutra_8_2_42() { let stf = d("stFY", Kryadi); @@ -375,6 +603,14 @@ fn sutra_8_2_45() { assert_has_krdanta(&[], &vri, Krt::ktavatu, &["vrIRavat"]); } +#[ignore] +#[test] +fn sutra_8_2_46() { + let kshi = Dhatu::new("kzi\\", Bhvadi); + assert_has_krdanta(&[], &kshi, Krt::kta, &["kzIRa"]); + // TODO: akzita +} + #[test] fn sutra_8_2_51() { let sus = Dhatu::new("Su\\za~", Divadi); @@ -396,12 +632,16 @@ fn sutra_8_2_53() { assert_has_krdanta(&[], &kzai, Krt::ktavatu, &["kzAmavat"]); } -#[ignore] #[test] fn sutra_8_2_54() { let styai = Dhatu::new("styE\\", Bhvadi); assert_has_krdanta(&["pra"], &styai, Krt::kta, &["prastIma", "prastIta"]); - assert_has_krdanta(&[], &styai, Krt::ktavatu, &["prastImavat", "prastItavat"]); + assert_has_krdanta( + &["pra"], + &styai, + Krt::ktavatu, + &["prastImavat", "prastItavat"], + ); } #[test] @@ -426,6 +666,66 @@ fn sutra_8_2_55() { assert_has_krdanta(&["pra", "ud"], &lagh, Krt::kta, &["prollAGita"]); } +#[test] +fn sutra_8_2_56() { + assert_has_krdanta(&[], &d("Ru\\da~^", Tudadi), Krt::kta, &["nunna", "nutta"]); + assert_has_krdanta(&[], &d("vi\\da~\\", Rudhadi), Krt::kta, &["vinna", "vitta"]); + assert_has_krdanta( + &["sam"], + &d("undI~", Rudhadi), + Krt::kta, + &["samunna", "samutta"], + ); + assert_has_krdanta(&[], &d("trE\\N", Bhvadi), Krt::kta, &["trARa", "trAta"]); + assert_has_krdanta(&[], &d("GrA\\", Bhvadi), Krt::kta, &["GrARa", "GrAta"]); + assert_has_krdanta(&[], &d("hrI\\", Juhotyadi), Krt::kta, &["hrIRa", "hrIta"]); + // only for vinatti + assert_has_krdanta(&[], &d("vida~", Adadi), Krt::kta, &["vidita"]); + assert_has_krdanta(&[], &d("vi\\da~\\", Divadi), Krt::kta, &["vinna"]); + assert_has_krdanta(&[], &d("vi\\dx~^", Tudadi), Krt::kta, &["vinna"]); +} + +#[test] +fn sutra_8_2_57() { + let dhyai = d("DyE\\", Bhvadi); + assert_has_krdanta(&[], &dhyai, Krt::kta, &["DyAta"]); + assert_has_krdanta(&[], &dhyai, Krt::ktavatu, &["DyAtavat"]); + + let khya = d("KyA\\", Adadi); + assert_has_krdanta(&[], &khya, Krt::kta, &["KyAta"]); + assert_has_krdanta(&[], &khya, Krt::ktavatu, &["KyAtavat"]); + + let pf = d("pF", Kryadi); + assert_has_krdanta(&[], &pf, Krt::kta, &["pUrta"]); + assert_has_krdanta(&[], &pf, Krt::ktavatu, &["pUrtavat"]); + + let murch = d("murCA~", Bhvadi); + assert_has_krdanta(&[], &murch, Krt::kta, &["mUrta"]); + assert_has_krdanta(&[], &murch, Krt::ktavatu, &["mUrtavat"]); + + let mad = d("madI~", Divadi); + assert_has_krdanta(&[], &mad, Krt::kta, &["matta"]); + assert_has_krdanta(&[], &mad, Krt::ktavatu, &["mattavat"]); +} + +#[ignore] +#[test] +fn sutra_8_2_58() { + assert_has_krdanta(&[], &d("vi\\dx~^", Tudadi), Krt::kta, &["vinna", "vitta"]); +} + +#[ignore] +#[test] +fn sutra_8_2_59() { + assert_has_krdanta(&[], &d("Bi\\di~^r", Rudhadi), Krt::kta, &["Binna", "Bitta"]); +} + +#[ignore] +#[test] +fn sutra_8_2_60() { + assert_has_krdanta(&[], &d("f\\", Juhotyadi), Krt::kta, &["fta", "fRa"]); +} + #[ignore] #[test] fn sutra_8_2_80() { diff --git a/vidyut-prakriya/tests/pada_8_3.rs b/vidyut-prakriya/tests/pada_8_3.rs index 7db58e5..1ed55d1 100644 --- a/vidyut-prakriya/tests/pada_8_3.rs +++ b/vidyut-prakriya/tests/pada_8_3.rs @@ -6,10 +6,6 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } @@ -385,6 +381,17 @@ fn sutra_8_3_79() { assert_padas(actual, &["cakfQve"]); } +#[test] +fn sutra_8_3_110() { + assert_has_krdanta(&["vi"], &d("sransu~\\", Bhvadi), Krt::Rvul, &["visraMsaka"]); + assert_has_krdanta(&["vi"], &d("sranBu~\\", Bhvadi), Krt::kta, &["visrabDa"]); + assert_has_krdanta(&["vi"], &d("sf\\px~", Tudadi), Krt::kasun, &["visfpas"]); + assert_has_krdanta(&["vi"], &d("sf\\ja~", Tudadi), Krt::lyuw, &["visarjana"]); + assert_has_krdanta(&[], &d("spf\\Sa~", Tudadi), Krt::kamul, &["spfSam"]); + assert_has_krdanta(&["ni"], &d("spfha", Curadi), Krt::kamul, &["nispfham"]); + // TODO: others? +} + #[ignore] #[test] fn sutra_8_3_112() { diff --git a/vidyut-prakriya/tests/pada_8_4.rs b/vidyut-prakriya/tests/pada_8_4.rs index 101214f..664a6de 100644 --- a/vidyut-prakriya/tests/pada_8_4.rs +++ b/vidyut-prakriya/tests/pada_8_4.rs @@ -8,10 +8,6 @@ use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::Vibhakti as V; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn san(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::San]) } @@ -47,9 +43,9 @@ fn sutra_8_4_1() { #[ignore] #[test] fn sutra_8_4_1_v1() { - assert_has_subantas_p(&stri("tri"), Stri, V::Sasthi, Bahu, &["tisfRAm"]); - assert_has_subantas_p(&stri("catur"), Stri, V::Sasthi, Bahu, &["catasfRAm"]); - assert_has_subantas_p(&stri("mAtf"), Stri, V::Sasthi, Bahu, &["mAtFRAm"]); + assert_has_subantas_p(&nyap("tri"), Stri, V::Sasthi, Bahu, &["tisfRAm"]); + assert_has_subantas_p(&nyap("catur"), Stri, V::Sasthi, Bahu, &["catasfRAm"]); + assert_has_subantas_p(&nyap("mAtf"), Stri, V::Sasthi, Bahu, &["mAtFRAm"]); assert_has_subantas("pitf", Pum, V::Sasthi, Bahu, &["pitFRAm"]); } @@ -92,6 +88,8 @@ fn sutra_8_4_2() { assert_has_krdanta(&["pra"], &inv, Krt::anIyar, &["prenvanIya"]); } +// 8.4.3 - 8.4.13 are for a pUrvapada. + #[test] fn sutra_8_4_14() { let nam = d("Ra\\ma~", Bhvadi); @@ -248,9 +246,9 @@ fn sutra_8_4_21() { let an = d("ana~", Adadi); let nic = |d: &Dhatu| d.clone().with_sanadi(&[Sanadi::Nic]); assert_has_lat(&["pra"], &san(&an), &["prARiRizati"]); - assert_has_lun(&["pra"], &nic(&an), &["prARiRat"]); + assert_has_lun_p(&["pra"], &nic(&an), &["prARiRat"]); assert_has_lat(&["parA"], &san(&an), &["parARiRizati"]); - assert_has_lun(&["parA"], &nic(&an), &["parARiRat"]); + assert_has_lun_p(&["parA"], &nic(&an), &["parARiRat"]); } #[test] @@ -349,6 +347,8 @@ fn sutra_8_4_44() { assert_has_krdanta(&[], &d("viCa~", Tudadi), Krt::naN, &["viSna"]); } +// 8.4.46 - 8.4.52 are the "dve" rules + #[test] fn sutra_8_4_53() { let labh = d("qula\\Ba~\\z", Bhvadi); @@ -377,6 +377,17 @@ fn sutra_8_4_53() { ); } +#[test] +fn sutra_8_4_54() { + assert_has_lat_p(&[], &san(&d("Kanu~^", Bhvadi)), &["ciKanizati"]); + assert_has_lat_p(&[], &san(&d("Ci\\di~^r", Rudhadi)), &["cicCitsati"]); + assert_has_lat_p(&[], &san(&d("zWA\\", Bhvadi)), &["tizWAsati"]); + assert_has_lat(&[], &san(&d("BU", Bhvadi)), &["buBUzati"]); + assert_has_lat(&[], &san(&d("a\\da~", Adadi)), &["jiGatsati"]); + assert_has_lat(&[], &san(&d("QOkf~\\", Bhvadi)), &["quQOkizate"]); + // TODO: others +} + #[test] fn sutra_8_4_55() { let bhid = d("Bi\\di~^r", Rudhadi); diff --git a/vidyut-prakriya/tests/regressions.rs b/vidyut-prakriya/tests/regressions.rs index e1366df..f371d03 100644 --- a/vidyut-prakriya/tests/regressions.rs +++ b/vidyut-prakriya/tests/regressions.rs @@ -6,14 +6,19 @@ the Siddhanta-kaumudi. */ extern crate test_utils; use test_utils::*; +use vidyut_prakriya::args::Dhatu; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Purusha::*; +use vidyut_prakriya::args::Sanadi; use vidyut_prakriya::args::Vacana::*; -use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) +fn san(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::San]) +} + +fn yan(dhatu: &Dhatu) -> Dhatu { + dhatu.clone().with_sanadi(&[Sanadi::Yan]) } #[ignore] @@ -39,3 +44,44 @@ fn sk_2397() { &["caskandiTa", "caskanTa", "caskantTa"], ); } + +#[test] +fn sk_2447() { + let urnu = d("UrRuY", Adadi); + assert_has_parasmai_tinanta( + &[], + &urnu, + Lit, + Madhyama, + Eka, + &["UrRunaviTa", "UrRunuviTa"], + ); +} + +#[test] +fn sk_2574() { + // ac-Adi dhatus with can-pratyaya and ak-lopa + // TODO: why does the SK have AndaDat and not AndiDat? + assert_has_lun_p(&[], &d("anDa", Curadi), &["AndaDat"]); + assert_has_lun_p(&[], &d("anka", Curadi), &["AYcakat"]); + assert_has_lun_p(&[], &d("anga", Curadi), &["AYjagat"]); + assert_has_lun_p(&[], &d("vyaya", Curadi), &["avavyayat"]); +} + +#[test] +fn sk_2630() { + assert_has_lit( + &[], + &yan(&d("BU", Bhvadi)), + &["boBUyAYcakre", "boBUyAmAsa", "boBUyAmbaBUva"], + ); +} + +#[test] +fn sk_2758() { + assert_has_lit( + &[], + &san(&d("BU", Bhvadi)), + &["buBUzAYcakAra", "buBUzAmAsa", "buBUzAmbaBUva"], + ); +} diff --git a/vidyut-prakriya/tests/sanadi_tinantas.rs b/vidyut-prakriya/tests/sanadi_tinantas.rs index 5d0544e..15213c2 100644 --- a/vidyut-prakriya/tests/sanadi_tinantas.rs +++ b/vidyut-prakriya/tests/sanadi_tinantas.rs @@ -6,9 +6,9 @@ Test cases marked with *Kale* are from M. R. Kale's *A Higher Sanskrit Grammar*. use vidyut_prakriya::args::*; use vidyut_prakriya::Ashtadhyayi; -fn create_sanadyanta(upadesha: &str, gana: u8, sanadi: Sanadi) -> Vec { +fn create_sanadyanta(upadesha: &str, gana: &str, sanadi: Sanadi) -> Vec { let a = Ashtadhyayi::new(); - let gana = Gana::from_int(gana).unwrap(); + let gana = gana.parse().expect("ok"); let dhatu = Dhatu::builder() .upadesha(upadesha) .gana(gana) @@ -34,7 +34,7 @@ fn run_sanadi_test_cases(cases: &[(&str, u8, &str)], sanadi: Sanadi) { let mut expected: Vec<_> = expected.split('|').collect(); expected.sort(); - let mut actual: Vec<_> = create_sanadyanta(dhatu, *gana, sanadi); + let mut actual: Vec<_> = create_sanadyanta(dhatu, &gana.to_string(), sanadi); if sanadi == Sanadi::Nic { // All Nijantas are ubhayapadI, so to simplify the tests, focus on just parasmaipada. actual.retain(|x| x.ends_with("ti")); diff --git a/vidyut-prakriya/tests/unadi_sutras.rs b/vidyut-prakriya/tests/unadi_sutras.rs index 9724e57..2a3f9de 100644 --- a/vidyut-prakriya/tests/unadi_sutras.rs +++ b/vidyut-prakriya/tests/unadi_sutras.rs @@ -5,10 +5,6 @@ use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::*; -fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::new(u, g) -} - fn nic(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::Nic]) } @@ -32,6 +28,13 @@ fn sutra_1_5() { assert_has_krdanta(&[], &d("tF", Bhvadi), Krt::YuR, &["tAlu"]); } +#[test] +fn sutra_1_45() { + assert_has_krdanta(&[], &d("ava~", Bhvadi), Krt::wizac, &["aviza"]); + // TODO: right mah? + assert_has_krdanta(&[], &d("maha~", Bhvadi), Krt::wizac, &["mahiza"]); +} + #[test] fn sutra_1_69() { assert_has_krdanta(&[], &d("zi\\Y", Svadi), Krt::tun, &["setu"]); @@ -100,6 +103,34 @@ fn sutra_3_86() { // assert_has_krdanta(&[], &d("DurvI~", Bhvadi), Krt::tan, &["DUrta"]); } +#[test] +fn sutra_3_126() { + assert_has_krdanta(&[], &d("jF", Kryadi), Krt::Jac, &["jaranta"]); + assert_has_krdanta(&[], &d("vi\\Sa~", Tudadi), Krt::Jac, &["veSanta"]); +} + +#[test] +fn sutra_3_127() { + assert_has_krdanta(&[], &d("ru\\ha~", Bhvadi), Krt::Jac, &["rohanta"]); + assert_has_krdanta(&[], &d("wunadi~", Bhvadi), Krt::Jac, &["nandanta"]); + assert_has_krdanta(&[], &d("jIva~", Tudadi), Krt::Jac, &["jIvanta"]); + // TODO: zit +} + +#[test] +fn sutra_3_128() { + assert_has_krdanta(&[], &d("tF", Bhvadi), Krt::Jac, &["taranta"]); + assert_has_krdanta(&[], &d("BU", Bhvadi), Krt::Jac, &["Bavanta"]); + assert_has_krdanta(&[], &d("va\\ha~^", Bhvadi), Krt::Jac, &["vahanta"]); + assert_has_krdanta(&[], &d("va\\sa~", Bhvadi), Krt::Jac, &["vasanta"]); + assert_has_krdanta(&[], &d("BAsf~\\", Bhvadi), Krt::Jac, &["BAsanta"]); + assert_has_krdanta(&[], &d("sA\\Da~", Svadi), Krt::Jac, &["sADanta"]); + assert_has_krdanta(&[], &d("gaqi~", Bhvadi), Krt::Jac, &["gaRqanta"]); + assert_has_krdanta(&[], &d("maqi~\\", Tudadi), Krt::Jac, &["maRqanta"]); + assert_has_krdanta(&[], &d("ji\\", Bhvadi), Krt::Jac, &["jayanta"]); + // nandayanta? +} + #[test] fn sutra_3_155() { assert_has_krdanta(&[], &d("pluza~", Kryadi), Krt::ksi, &["plukzi"]); @@ -148,3 +179,18 @@ fn sutra_4_158() { assert_has_krdanta(&[], &d("asu~", Divadi), Krt::zwran, &["astra"]); assert_has_krdanta(&[], &d("Sasu~", Bhvadi), Krt::zwran, &["Sastra"]); } + +#[test] +fn sutra_5_68() { + assert_has_krdanta(&[], &d("praTa~\\", Bhvadi), Krt::amac, &["praTama"]); +} + +#[test] +fn sutra_5_69() { + assert_has_krdanta(&[], &d("cara~", Bhvadi), Krt::amac, &["carama"]); +} + +#[test] +fn sutra_5_70() { + assert_has_krdanta(&[], &d("magi~", Bhvadi), Krt::alac, &["maNgala"]); +}