diff --git a/vidyut-prakriya/Makefile b/vidyut-prakriya/Makefile index dba1ba8..25ac255 100644 --- a/vidyut-prakriya/Makefile +++ b/vidyut-prakriya/Makefile @@ -62,85 +62,85 @@ test_tinantas: ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-basic-kartari.csv \ - --hash "51d6017bcc2516e2af0d028d251b72165e2f19bafb0839e35110f157934609db" + --hash "2dfbc74c55529c9b2ce8dc3202b7c7dca844a4c8f207c2d729ce1fed921fe1b2" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-nic-kartari.csv \ - --hash "503fe8ace23a847f8ea02c23263112a0bbb484aa1971fdba5a811a5096dd2681" + --hash "2901d9a7323bd662909ff4ad75d4e8237dca576a92dae36d3059431584c77f9c" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-san-kartari.csv \ - --hash "9145fff93b263223e270a2cde065bb3fb0c811df24ab42a043eae39e2f756234" + --hash "f54f89f6652176d48781baab2ea006f4ffc3dc637da1b7fa32b53c0bd7775ff2" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-yan-kartari.csv \ - --hash "1998c701f314c8bcdcd48d59300debabd39d3ba586341e5a515815d6a1c2503f" + --hash "69fa8583b872d0c8f21f42815515a7457050a583fad99c062831d817a6094db4" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-yan-luk-kartari.csv \ - --hash "8339c74d2414ee47e76623accfe9064b050164fadb0fa113a469df9b8181e074" + --hash "0c4776f55b80bdb4e69e137c258d7365efa1f4e6f1e8c58753846646041428ec" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-san-nic-kartari.csv \ - --hash "c5977158acab3b00601ef4b78c29c045a6d9586fb9aa0502856fdab73e630bf5" + --hash "58ccd63ddcb785e84253990bb379aad51d93e68b421adf2e0be9c70edf454bd3" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-nic-san-kartari.csv \ - --hash "c292a9b75da8feaa4c4f318900bc257ab703ece640f691ac9c7ac52a683679d2" + --hash "6618699600fdd272c6cfbe1ffad7567f9bdd8950dfabeb859e6cfffed83836f1" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-basic-karmani.csv \ - --hash "a30032f2b32cd8008c91c95b7e03e3e9f11386179bb70fd26f5eccf8748d0afe" + --hash "66fa96d66a1fb52d639cc6516c89c54883d71cad2e3558c9984cfdc2d75a6b5e" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-nic-karmani.csv \ - --hash "7a5358df11a14351e771b917742a83df10d4013e844419ddeadc91c8cc206548" + --hash "218964795f2d8dba96cefa0f49578f0c636575325bd23412bc10d80fbbb1545a" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-san-karmani.csv \ - --hash "725dfe8657b9543aede4a73798b50a89a389c0d74ce5c0c9ecb91f4447d60495" + --hash "a682c39d420379ebc77598154a4804d94f6c35632877f5cc508b46ddbd548ba9" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-yan-karmani.csv \ - --hash "6167063aed3186aae0a01d635156618f6cf7ba09c7d7c2ed93e076dc5ef46841" + --hash "f4c2dedc816bec356e97c46831ce35c2272ffeb2d5bb29bfa332cff393e67c9f" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-san-nic-karmani.csv \ - --hash "8c3925ad25154ad44ceb3f726843fcb0a453a71b93fb2d4a1c55d20a905dd292" + --hash "ef958478945d449bbd093b02a7f4b84f14939c365c67cec65481b168c2ffdc97" ../target/release/test_results \ --data-type tinanta \ --test-cases test-files/tinantas-nic-san-karmani.csv \ - --hash "d679a4a2d3487a99899cb2793c8d890f570016a60d8b5460a62cde92a0dfec76" + --hash "e6ce97fcae9a5855dad2486737e8e28f4a7581190d7b10f9e9592603374504c8" test_krdantas: cargo build --release --bin test_results ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-basic.csv \ - --hash "769a763ab754ee5accf0edefa09b38b1084a069c6bf4e183c3f7039c295511fe" + --hash "90bf0b99a2b641c74a77bbfc1864d904a5ce05ba5aa011f69ea0b12b6e2693e4" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-nic.csv \ - --hash "7be488ee87ad8402487d39cc6e3c0fe8be7a9480e88b02a5eec5e05c4a790d0c" + --hash "58fb5d4eef55f5b0d8475e87665cba0038d6daf882399c60a03972e5abc7ed28" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-san.csv \ - --hash "a2de7869bf2c6b534c7075ac37803c232f1c24f6fcc58713d85c4f89bbe79d55" + --hash "a689755607b5b634f36ffdb9f01aba212df68eab3d1ddf5cf1cbd8b25ffafaa3" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-yan.csv \ - --hash "038ac65be234cfde608106385964b3a67e66fe508d6f91a14b8bff9b6a1c017f" + --hash "7d14c2e8d6f83eff87b6cbdcfb3fedf66bde3e880a555a836b0feaaecee3bc41" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-yan-luk.csv \ - --hash "6bdaea4c974026fa7bfab4e874b1c3f0368d6a2f35bbf94ad626ab573bf8282d" + --hash "49cfda9501ba6076e7285a131d9efb1f2d0964fabb71b2e176d94a151e6695c9" test_dhatus: cargo build --release --bin test_results ../target/release/test_results \ --data-type dhatu \ --test-cases test-files/dhatus.csv \ - --hash "813ceb212c3d500ed4e4a2b892c8c72504be8c0f3602831135698bcd54e62b5f" + --hash "bc7d210cc44e1231e0f89d3f6e39de4288b0c75fa108a1168003fc7c33a16965" test_subantas: diff --git a/vidyut-prakriya/README.md b/vidyut-prakriya/README.md index 0f84b33..5030f02 100644 --- a/vidyut-prakriya/README.md +++ b/vidyut-prakriya/README.md @@ -90,7 +90,7 @@ use vidyut_prakriya::args::*; let v = Vyakarana::new(); -let dhatu = Dhatu::mula("BU", Gana::Bhvadi); +let dhatu = Dhatu::mula(Slp1String::from("BU").expect("ok"), Gana::Bhvadi); let args = Tinanta::builder() .dhatu(dhatu) .lakara(Lakara::Lat) diff --git a/vidyut-prakriya/data/dhatupatha.tsv b/vidyut-prakriya/data/dhatupatha.tsv index 9ec0913..816d09c 100644 --- a/vidyut-prakriya/data/dhatupatha.tsv +++ b/vidyut-prakriya/data/dhatupatha.tsv @@ -781,7 +781,7 @@ code dhatu artha 01.0780 Iza~ uYCe 01.0781 kaza~ hiMsAyAm 01.0782 Kaza~ hiMsAyAm -01.0783 Si\\za~ hiMsAyAm +01.0783 Si\za~ hiMsAyAm 01.0784 jaza~ hiMsAyAm 01.0785 Jaza~ hiMsAyAm 01.0786 Saza~ hiMsAyAm diff --git a/vidyut-prakriya/examples/create_all_krdantas.rs b/vidyut-prakriya/examples/create_all_krdantas.rs index 8ef4cb1..42bc4f9 100644 --- a/vidyut-prakriya/examples/create_all_krdantas.rs +++ b/vidyut-prakriya/examples/create_all_krdantas.rs @@ -14,7 +14,7 @@ use serde::Serialize; use std::error::Error; use std::io; use vidyut_lipi::{Lipika, Scheme}; -use vidyut_prakriya::args::{BaseKrt, Krdanta, Sanadi}; +use vidyut_prakriya::args::{BaseKrt, Krdanta, Lakara, Prayoga, Sanadi}; use vidyut_prakriya::{Dhatupatha, Vyakarana}; /// Command line arguments. @@ -38,7 +38,9 @@ struct Row<'a> { gana: &'static str, number: u16, sanadi: String, - krt: &'static str, + prayoga: Option, + lakara: Option, + krt: BaseKrt, } fn create_output_string( @@ -73,33 +75,53 @@ fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { None => Scheme::Slp1, }; + let sat_prayoga_lakara = &[ + (Some(Prayoga::Kartari), Some(Lakara::Lat)), + (Some(Prayoga::Kartari), Some(Lakara::Lrt)), + (Some(Prayoga::Karmani), Some(Lakara::Lat)), + (Some(Prayoga::Karmani), Some(Lakara::Lrt)), + ]; + for sanadis in &sanadi_choices { for entry in &dhatupatha { let dhatu = entry.dhatu().clone().with_sanadi(&sanadis); for krt in BaseKrt::iter() { - let krdanta = Krdanta::builder().dhatu(dhatu.clone()).krt(krt).build()?; + let prayoga_lakara: &[(Option, Option)] = match krt { + BaseKrt::Satf | BaseKrt::SAnac => sat_prayoga_lakara, + _ => &[(None, None)], + }; - let prakriyas = v.derive_krdantas(&krdanta); - if prakriyas.is_empty() { - continue; - } + for (prayoga, lakara) in prayoga_lakara.iter().copied() { + let mut builder = Krdanta::builder().dhatu(dhatu.clone()).krt(krt); + if let (Some(prayoga), Some(lakara)) = (prayoga, lakara) { + builder = builder.prayoga(prayoga).lakara(lakara); + } + let krdanta = builder.build()?; - let dhatu_text = &dhatu.aupadeshika().expect("ok"); - let krdantas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - let krdantas = create_output_string(&mut lipika, krdantas, output_scheme); - let sanadi_text: Vec<_> = sanadis.iter().map(|x| x.as_str()).collect(); - let sanadi_text = sanadi_text.join("-"); - - let row = Row { - krdantas, - dhatu: dhatu_text, - gana: dhatu.gana().expect("ok").as_str(), - number: entry.number(), - sanadi: sanadi_text, - krt: krt.as_str(), - }; + let prakriyas = v.derive_krdantas(&krdanta); + if prakriyas.is_empty() { + continue; + } + + let dhatu_text = &dhatu.aupadeshika().expect("ok"); + let krdantas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); + let krdantas = create_output_string(&mut lipika, krdantas, output_scheme); + let sanadi_text: Vec<_> = sanadis.iter().map(|x| x.as_str()).collect(); + let sanadi_text = sanadi_text.join("-"); - wtr.serialize(row)?; + let row = Row { + krdantas, + dhatu: dhatu_text, + gana: dhatu.gana().expect("ok").as_str(), + number: entry.number(), + sanadi: sanadi_text, + prayoga, + lakara, + krt, + }; + + wtr.serialize(row)?; + } } } } diff --git a/vidyut-prakriya/examples/create_all_tinantas.rs b/vidyut-prakriya/examples/create_all_tinantas.rs index 7153562..be34263 100644 --- a/vidyut-prakriya/examples/create_all_tinantas.rs +++ b/vidyut-prakriya/examples/create_all_tinantas.rs @@ -40,10 +40,10 @@ struct Row<'a> { gana: &'static str, number: u16, sanadi: String, - prayoga: &'static str, - lakara: &'static str, - purusha: &'static str, - vacana: &'static str, + prayoga: Prayoga, + lakara: Lakara, + purusha: Purusha, + vacana: Vacana, } fn create_output_string( @@ -111,10 +111,10 @@ fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { gana: dhatu.gana().expect("ok").as_str(), number: entry.number(), sanadi: sanadi_text.clone(), - lakara: lakara.as_str(), - purusha: purusha.as_str(), - vacana: vacana.as_str(), - prayoga: prayoga.as_str(), + lakara, + purusha, + vacana, + prayoga, }; wtr.serialize(row)?; diff --git a/vidyut-prakriya/src/ac_sandhi.rs b/vidyut-prakriya/src/ac_sandhi.rs index e292a89..edc02c4 100644 --- a/vidyut-prakriya/src/ac_sandhi.rs +++ b/vidyut-prakriya/src/ac_sandhi.rs @@ -321,7 +321,7 @@ fn apply_ac_sandhi_at_term_boundary(p: &mut Prakriya, i: usize) -> Option<()> { Some(()) } -fn try_sut_kat_purva(p: &mut Prakriya) -> Option<()> { +pub fn try_sut_kat_purva(p: &mut Prakriya) -> Option<()> { let i_dhatu = p.find_first_with_tag(T::Dhatu)?; let dhatu = p.get(i_dhatu)?; @@ -333,7 +333,7 @@ fn try_sut_kat_purva(p: &mut Prakriya) -> Option<()> { let prev = p.get(i_prev)?; let optional_add_sut_agama = |rule, p: &mut Prakriya, i_dhatu: usize| { - if p.optional_run(rule, |p| p.insert_before(i_dhatu, A::suw)) { + if p.optional_run(rule, |p| p.insert(i_dhatu, A::suw)) { it_samjna::run(p, i_dhatu).expect("ok"); } }; @@ -416,7 +416,5 @@ pub fn run_common(p: &mut Prakriya) -> Option<()> { apply_general_ac_sandhi(p, 0, p.len() - 1); 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 a131448..a5b0afd 100644 --- a/vidyut-prakriya/src/angasya.rs +++ b/vidyut-prakriya/src/angasya.rs @@ -90,7 +90,7 @@ pub fn maybe_do_jha_adesha(p: &mut Prakriya) -> Option<()> { let base = p.get(i_base)?; if base.is_dhatu() && p.has(i, |t| t.is_atmanepada()) { - let add_rut = |p: &mut Prakriya| p.insert_before(i, A::ruw); + let add_rut = |p: &mut Prakriya| p.insert(i, A::ruw); if base.is_u(Au::SIN) { // Serate p.run("7.1.6", add_rut); @@ -176,7 +176,6 @@ fn try_pratyaya_adesha_at_index(p: &mut Prakriya, i_anga: usize) -> Option<()> { /// Runs rules that change one or more letters in the anga to a 't'. fn try_anga_changes_before_t(p: &mut Prakriya, i_anga: usize) -> Option<()> { - p.debug("anga before t"); let anga = p.get(i_anga)?; if anga.is_dhatu() { @@ -1241,6 +1240,9 @@ pub fn run_before_dvitva(p: &mut Prakriya, is_lun: bool, skip_at_agama: bool) -> Some(()) }); + // Must run before guna for saYcaskaratuH, etc. + ac_sandhi::try_sut_kat_purva(p); + p.debug("==== Guna-vrddhi ===="); guna_vrddhi::run(p); diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index 41c14cb..614dd6f 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -412,7 +412,7 @@ fn try_rules_for_yan(p: &mut Prakriya, i_abhyasa: usize) -> Option<()> { } let optional_add_agama = |rule, p: &mut Prakriya, i_dhatu, agama: Agama| -> bool { - let added = p.optional_run(rule, |p| p.insert_before(i_dhatu, agama)); + let added = p.optional_run(rule, |p| p.insert(i_dhatu, agama)); if added { it_samjna::run(p, i_dhatu).ok(); } @@ -420,7 +420,7 @@ fn try_rules_for_yan(p: &mut Prakriya, i_abhyasa: usize) -> Option<()> { }; let add_agama = |rule, p: &mut Prakriya, i_dhatu, agama| -> bool { - p.run(rule, |p| p.insert_before(i_dhatu, agama)); + p.run(rule, |p| p.insert(i_dhatu, agama)); it_samjna::run(p, i_dhatu).ok(); true }; diff --git a/vidyut-prakriya/src/angasya/asiddhavat.rs b/vidyut-prakriya/src/angasya/asiddhavat.rs index e81b803..0ddc004 100644 --- a/vidyut-prakriya/src/angasya/asiddhavat.rs +++ b/vidyut-prakriya/src/angasya/asiddhavat.rs @@ -146,7 +146,7 @@ pub fn try_cinvat_for_bhave_and_karmani_prayoga(p: &mut Prakriya) -> Option<()> t.add_tag(T::Rit); t.add_tag(T::Cinvat); }); - p.insert_before(i_n, A::iw); + p.insert(i_n, A::iw); }); if ran { it_samjna::run(p, i_n).ok(); @@ -836,9 +836,11 @@ pub fn run_for_ni_at_index(p: &mut Prakriya, i_ni: usize) -> Option<()> { if n.last().is_ardhadhatuka() { let dhatu = p.get(i_dhatu)?; + let next = n.first(); - if n.first() - .has_text_in(&["Am", "anta", "Alu", "Ayya", "itnu", "iznu"]) + if next.has_text_in(&["Am"]) + || next.is_any_krt(&[K::Aluc, K::izRuc]) + || next.is_any_unadi(&[U::Jac, U::Ayya, U::itnuc, U::izRuc]) { // corayAm, spfhayAlu, etc. p.run_at("6.4.55", i_ni, op::antya("ay")); diff --git a/vidyut-prakriya/src/angasya/guna_vrddhi.rs b/vidyut-prakriya/src/angasya/guna_vrddhi.rs index 2d19d9b..49665fb 100644 --- a/vidyut-prakriya/src/angasya/guna_vrddhi.rs +++ b/vidyut-prakriya/src/angasya/guna_vrddhi.rs @@ -156,12 +156,15 @@ fn try_taddhita_vrddhi(p: &mut Prakriya, i_anga: usize, i_n: usize) -> Option<() return None; }; + if anga.is_any_phit(&["kekaya", "mitrayu", "pralaya"]) { + p.run_at("7.3.2", i_anga, |t| t.find_and_replace_text("y", "iy")); + } + + let anga = p.get(i_anga)?; if anga.is_any_phit(&["devikA", "SiMSapA", "dityavAh", "dIrGasatra", "Sreyas"]) { // dAvikA, ... let adi_ac = anga.text.find(al::is_ac)?; p.run_at("7.3.1", i_anga, |t| t.set_at(adi_ac, "A")); - } else if anga.is_any_phit(&["kekaya", "mitrayu", "pralaya"]) { - p.run_at("7.3.2", i_anga, |t| t.find_and_replace_text("y", "iy")); } else if anga.starts_with("vy") { // HACK: should properly be only with vi-upasarga. // TODO: also apply for sv-, .etc. @@ -446,7 +449,8 @@ fn try_r_guna_before_lit(p: &mut Prakriya, i: usize) -> Option<()> { }; let anga = p.get(i)?; - if anga.has_antya('f') && anga.is_samyogadi() { + let is_skr = || anga.has_u("qukf\\Y") && i > 0 && p.has(i - 1, |t| t.is(A::suw)); + if anga.has_antya('f') && (anga.is_samyogadi() || is_skr()) { p.run_at("7.4.10", i, do_ar_guna); } else if anga.has_antya('F') || (anga.has_u_in(&["fCa~", "f\\"]) && anga.has_adi('f')) { if anga.has_u("fCa~") { diff --git a/vidyut-prakriya/src/angasya/subanta.rs b/vidyut-prakriya/src/angasya/subanta.rs index 31b2efe..0fdaeb2 100644 --- a/vidyut-prakriya/src/angasya/subanta.rs +++ b/vidyut-prakriya/src/angasya/subanta.rs @@ -659,7 +659,7 @@ fn try_add_nit_agamas(p: &mut Prakriya, i_anga: usize) -> Option<()> { // tasyE p.run("7.3.114", |p| { p.set(i_anga, op::antya("a")); - p.insert_before(i_sup, A::syAw) + p.insert(i_sup, A::syAw) }); it_samjna::run(p, i_sup).ok()?; } else { diff --git a/vidyut-prakriya/src/args.rs b/vidyut-prakriya/src/args.rs index 36c887e..8ac6b20 100644 --- a/vidyut-prakriya/src/args.rs +++ b/vidyut-prakriya/src/args.rs @@ -21,6 +21,7 @@ mod krt; mod pada; mod pratipadika; mod samasa; +mod slp1_string; mod sup; mod taddhita; mod tin; @@ -32,6 +33,7 @@ pub use krt::*; pub use pada::*; pub use pratipadika::*; pub use samasa::*; +pub use slp1_string::Slp1String; pub use sup::*; pub use taddhita::*; pub use tin::*; diff --git a/vidyut-prakriya/src/args/dhatu.rs b/vidyut-prakriya/src/args/dhatu.rs index 1997135..0a07dce 100644 --- a/vidyut-prakriya/src/args/dhatu.rs +++ b/vidyut-prakriya/src/args/dhatu.rs @@ -1,5 +1,6 @@ use crate::args::Pratipadika; -use crate::core::errors::Error; +use crate::args::Slp1String; +use crate::core::errors::{Error, Result}; use crate::enum_boilerplate; use wasm_bindgen::prelude::wasm_bindgen; @@ -183,7 +184,7 @@ enum_boilerplate!(Sanadi, { #[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Muladhatu { - aupadeshika: String, + aupadeshika: Slp1String, gana: Gana, antargana: Option, sanadi: Vec, @@ -192,9 +193,9 @@ pub struct Muladhatu { impl Muladhatu { /// Creates a new *mūla-dhātu*. - pub fn new(upadesha: &str, gana: Gana) -> Self { + pub fn new(aupadeshika: Slp1String, gana: Gana) -> Self { Self { - aupadeshika: String::from(upadesha), + aupadeshika, gana, antargana: None, sanadi: Vec::new(), @@ -204,8 +205,8 @@ impl Muladhatu { /// The dhatu as stated in its *aupadeśika* form. `upadesha` should be an SLP1 string that /// includes any necessary svaras. For examples, see the `dhatu` column in the /// `data/dhatupatha.tsv` file included in this crate. - pub fn aupadeshika(&self) -> &String { - &self.aupadeshika + pub fn aupadeshika(&self) -> &str { + &self.aupadeshika.0 } /// The dhatu's *gaṇa*. @@ -306,74 +307,93 @@ impl Namadhatu { /// A *mūla-dhātu* in a specific gana: /// /// ``` +/// # use vidyut_prakriya::*; /// use vidyut_prakriya::args::*; /// -/// let bhu = Dhatu::mula("BU", Gana::Bhvadi); -/// let ad = Dhatu::mula("a\\da~", Gana::Adadi); -/// let hu = Dhatu::mula("hu\\", Gana::Juhotyadi); -/// let div = Dhatu::mula("divu~", Gana::Divadi); -/// let su = Dhatu::mula("zu\\Y", Gana::Svadi); -/// let tud = Dhatu::mula("tu\\da~^", Gana::Tudadi); -/// let rudh = Dhatu::mula("ru\\Di~^r", Gana::Rudhadi); -/// let tan = Dhatu::mula("tanu~^", Gana::Tanadi); -/// let kri = Dhatu::mula("qukrI\\Y", Gana::Kryadi); -/// let cur = Dhatu::mula("cura~", Gana::Curadi); +/// let slp = Slp1String::from; +/// +/// let bhu = Dhatu::mula(slp("BU")?, Gana::Bhvadi); +/// let ad = Dhatu::mula(slp("a\\da~")?, Gana::Adadi); +/// let hu = Dhatu::mula(slp("hu\\")?, Gana::Juhotyadi); +/// let div = Dhatu::mula(slp("divu~")?, Gana::Divadi); +/// let su = Dhatu::mula(slp("zu\\Y")?, Gana::Svadi); +/// let tud = Dhatu::mula(slp("tu\\da~^")?, Gana::Tudadi); +/// let rudh = Dhatu::mula(slp("ru\\Di~^r")?, Gana::Rudhadi); +/// let tan = Dhatu::mula(slp("tanu~^")?, Gana::Tanadi); +/// let kri = Dhatu::mula(slp("qukrI\\Y")?, Gana::Kryadi); +/// let cur = Dhatu::mula(slp("cura~")?, Gana::Curadi); +/// # Ok::<(), Error>(()) /// ``` /// /// A *mūla-dhātu* in a specific *gaṇa* and *antargaṇa*: /// /// ``` -/// use vidyut_prakriya::args::*; +/// # use vidyut_prakriya::*; +/// # use vidyut_prakriya::args::*; +/// # let slp = Slp1String::from; /// -/// let kut = Dhatu::mula_with_antargana("kuwa~", Gana::Tudadi, Antargana::Kutadi); +/// let kut = Dhatu::mula_with_antargana(slp("kuwa~")?, Gana::Tudadi, Antargana::Kutadi); +/// # Ok::<(), Error>(()) /// ```` /// /// A *mūla-dhātu* with *sanādi pratyaya*s: /// /// ``` +/// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; -/// let bhu = Dhatu::mula("BU", Gana::Bhvadi); +/// let bhu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi); /// let bhavi = bhu.clone().with_sanadi(&[Sanadi::Ric]); /// let bubhusha = bhu.clone().with_sanadi(&[Sanadi::san]); /// let bobhuya = bhu.clone().with_sanadi(&[Sanadi::yaN]); /// let bobhu = bhu.clone().with_sanadi(&[Sanadi::yaNluk]); /// let bibhavayiza = bhu.clone().with_sanadi(&[Sanadi::Ric, Sanadi::san]); +/// # Ok::<(), Error>(()) /// ``` /// /// A *mūla-dhātu* with prefixes: /// /// ``` +/// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; -/// let bhu = Dhatu::mula("BU", Gana::Bhvadi); +/// let bhu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi); /// let prabhu = bhu.clone().with_prefixes(&["pra"]); /// let pratisambhu = bhu.clone().with_prefixes(&["prati", "sam"]); +/// # Ok::<(), Error>(()) /// ``` /// /// A *mūla-dhātu* with both prefixes and *sanādi pratyaya*s: /// /// ``` +/// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; -/// let bhu = Dhatu::mula("BU", Gana::Bhvadi); +/// # let slp = Slp1String::from; +/// let bhu = Dhatu::mula(slp("BU")?, Gana::Bhvadi); +/// let bhu = Dhatu::mula(slp("BU")?, Gana::Bhvadi); /// let pratisambibhavayiza = bhu.clone() /// .with_prefixes(&["prati", "sam"]) /// .with_sanadi(&[Sanadi::Ric, Sanadi::san]); +/// # Ok::<(), Error>(()) /// ``` /// /// A *nāma-dhātu* with an optional *sanādi pratyaya*: /// /// ``` +/// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; -/// let putra = Pratipadika::basic("putra"); +/// let putra = Pratipadika::basic(Slp1String::from("putra")?); /// let putriya = Dhatu::nama(putra, Some(Sanadi::kyac)); +/// # Ok::<(), Error>(()) /// ``` /// /// A *nāma-dhātu* with a mandatory *sanādi pratyaya* from some other sutra: /// /// ``` +/// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; -/// let lohita = Pratipadika::basic("lohita"); +/// let lohita = Pratipadika::basic(Slp1String::from("lohita")?); /// // "kyaN" will be added by sutra 3.1.13. /// let lohitaya = Dhatu::nama(lohita, None); +/// # Ok::<(), Error>(()) /// ```` /// /// let bhu = Dhatu::mula("BU", Gana::Bhvadi); @@ -401,13 +421,15 @@ impl Dhatu { /// ### Example /// /// ``` + /// # use vidyut_prakriya::*; /// use vidyut_prakriya::args::*; /// - /// let bhu = Dhatu::mula("BU", Gana::Bhvadi); - /// let kr = Dhatu::mula("qukf\\Y", Gana::Tanadi); + /// let bhu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi); + /// let kr = Dhatu::mula(Slp1String::from("qukf\\Y")?, Gana::Tanadi); + /// # Ok::<(), Error>(()) /// ``` - pub fn mula(upadesha: &str, gana: Gana) -> Self { - Self::Mula(Muladhatu::new(upadesha, gana)) + pub fn mula(aupadeshika: Slp1String, gana: Gana) -> Self { + Self::Mula(Muladhatu::new(aupadeshika, gana)) } /// Creates a new dhatu with its gana and antargana. @@ -421,12 +443,14 @@ impl Dhatu { /// ### Example /// /// ``` + /// # use vidyut_prakriya::*; /// use vidyut_prakriya::args::*; /// - /// let kut = Dhatu::mula_with_antargana("kuwa~", Gana::Tudadi, Antargana::Kutadi); + /// let kut = Dhatu::mula_with_antargana(Slp1String::from("kuwa~")?, Gana::Tudadi, Antargana::Kutadi); + /// # Ok::<(), Error>(()) /// ``` - pub fn mula_with_antargana(upadesha: &str, gana: Gana, antargana: Antargana) -> Self { - Self::Mula(Muladhatu::new(upadesha, gana).with_antargana(antargana)) + pub fn mula_with_antargana(aupadeshika: Slp1String, gana: Gana, antargana: Antargana) -> Self { + Self::Mula(Muladhatu::new(aupadeshika, gana).with_antargana(antargana)) } /// Creates a new *nāmadhātu* with its *sanādi pratyaya*. @@ -439,16 +463,25 @@ impl Dhatu { /// With an explicit `Sanadi` pratyaya: /// /// ``` - /// # use vidyut_prakriya::args::*; - /// let putriya = Dhatu::nama(Pratipadika::basic("putra"), Some(Sanadi::kyac)); - /// let putrakamya = Dhatu::nama(Pratipadika::basic("putra"), Some(Sanadi::kAmyac)); + /// # use vidyut_prakriya::*; + /// use vidyut_prakriya::args::*; + /// + /// let putriya = Dhatu::nama( + /// Pratipadika::basic(Slp1String::from("putra")?), + /// Some(Sanadi::kyac)); + /// let putrakamya = Dhatu::nama( + /// Pratipadika::basic(Slp1String::from("putra")?), + /// Some(Sanadi::kAmyac)); + /// # Ok::<(), Error>(()) /// ```` /// /// With an implicit `Sanadi` pratyaya: /// /// ``` + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; - /// let lohitaya = Dhatu::nama(Pratipadika::basic("lohita"), None); + /// let lohitaya = Dhatu::nama(Pratipadika::basic(Slp1String::from("lohita")?), None); + /// # Ok::<(), Error>(()) /// ```` pub fn nama(subanta: Pratipadika, nama_sanadi: Option) -> Self { Self::Nama(Namadhatu { @@ -481,7 +514,7 @@ impl Dhatu { } /// The aupadeshika text for this dhatu, if defined. - pub fn aupadeshika(&self) -> Option<&String> { + pub fn aupadeshika(&self) -> Option<&str> { match self { Self::Mula(m) => Some(m.aupadeshika()), _ => None, @@ -586,10 +619,10 @@ impl DhatuBuilder { } /// Converts the arguments in this builder into a `Dhatu` struct. - pub fn build(self) -> Result { + pub fn build(self) -> Result { Ok(Dhatu::Mula(Muladhatu { aupadeshika: match self.aupadeshika { - Some(x) => x, + Some(x) => Slp1String::from(x)?, _ => return Err(Error::missing_required_field("aupadeshika")), }, gana: match self.gana { diff --git a/vidyut-prakriya/src/args/pratipadika.rs b/vidyut-prakriya/src/args/pratipadika.rs index 44ec5ef..e5c5326 100644 --- a/vidyut-prakriya/src/args/pratipadika.rs +++ b/vidyut-prakriya/src/args/pratipadika.rs @@ -1,4 +1,5 @@ -use crate::args::{Krdanta, Samasa, Taddhitanta}; +use crate::args::{Krdanta, Samasa, Slp1String, Taddhitanta}; +use crate::core::errors::{Error, Result}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -7,7 +8,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BasicPratipadika { - pub(crate) text: String, + pub(crate) text: Slp1String, pub(crate) is_avyaya: bool, pub(crate) is_nyap: bool, } @@ -15,7 +16,7 @@ pub struct BasicPratipadika { impl BasicPratipadika { /// Returns the text that constitutes this pratipadika. pub fn text(&self) -> &str { - &self.text + &self.text.0 } } @@ -43,9 +44,9 @@ pub enum Pratipadika { impl Pratipadika { /// (unstable) A simple constructor for `Pratipadika::Basic`. - pub fn basic(text: impl AsRef) -> Self { + pub fn basic(text: Slp1String) -> Self { Self::Basic(BasicPratipadika { - text: text.as_ref().to_string(), + text, is_nyap: false, is_avyaya: false, }) @@ -53,9 +54,9 @@ impl Pratipadika { /// (unstable) A simple constructor for `Pratipadika::Basic` that marks the pratipadika as an /// avyaya. - pub fn avyaya(text: impl AsRef) -> Self { + pub fn avyaya(text: Slp1String) -> Self { Self::Basic(BasicPratipadika { - text: text.as_ref().to_string(), + text, is_nyap: false, is_avyaya: true, }) @@ -63,18 +64,19 @@ impl Pratipadika { /// (unstable) A simple constructor for `Pratipadika::Basic` that indicates that the /// pratipadika already ends in a nyAp-pratyaya. - pub fn nyap(text: impl AsRef) -> Self { + pub fn nyap(text: Slp1String) -> Self { Self::Basic(BasicPratipadika { - text: text.as_ref().to_string(), + text, is_nyap: true, is_avyaya: false, }) } } -impl From<&str> for Pratipadika { - fn from(s: &str) -> Self { - Self::basic(s) +impl TryFrom<&str> for Pratipadika { + type Error = Error; + fn try_from(s: &str) -> Result { + Ok(Self::basic(Slp1String::from(s)?)) } } diff --git a/vidyut-prakriya/src/args/slp1_string.rs b/vidyut-prakriya/src/args/slp1_string.rs new file mode 100644 index 0000000..491bbf1 --- /dev/null +++ b/vidyut-prakriya/src/args/slp1_string.rs @@ -0,0 +1,214 @@ +use crate::core::errors::{Error, Result}; +use crate::sounds::{AC, AL}; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +/// `SanskritString` is a validated `String` that contains only ASCII characters that conform to +/// the SLP1 encoding for Sanskrit text. Specifically, it makes the following guarantees: +/// +/// - All characters in the string are ASCII. +/// - Specifically, all characters are part of the SLP1 encoding scheme. All characters not in the +/// list provided below, including whitespace, will cause an error. +/// - `~` must follow a vowel. +/// - `\\` and `^` must follow either a vowel or `~`. +/// +/// List of accepted SLP1 characters: +/// +/// - `a` -- *a* +/// - `A` -- *ā* +/// - `i` -- *i* +/// - `I` -- *ī* +/// - `u` -- *u* +/// - `U` -- *ū* +/// - `f` -- *r̥* +/// - `F` -- *r̥̄* +/// - `x` -- *l̥* +/// - `X` -- *l̥̄* +/// - `e` -- *ē* +/// - `E` -- *ai* +/// - `o` -- *ō* +/// - `O` -- *au* +/// - `M` -- *ṁ* (*anusvāra*) +/// - `H` -- *ḥ* (*visarga*) +/// - `k` -- *k* +/// - `K` -- *kh* +/// - `g` -- *g* +/// - `G` -- *gh* +/// - `N` -- *ṅ* +/// - `c` -- *c* +/// - `C` -- *ch* +/// - `j` -- *j* +/// - `J` -- *jh* +/// - `Y` -- *ñ* +/// - `w` -- *ṭ* +/// - `W` -- *ṭh* +/// - `q` -- *ḍ* +/// - `Q` -- *ḍh* +/// - `R` -- *ṇ* +/// - `t` -- *t* +/// - `T` -- *th* +/// - `d` -- *d* +/// - `D` -- *dh* +/// - `n` -- *n* +/// - `p` -- *p* +/// - `P` -- *ph* +/// - `b` -- *b* +/// - `B` -- *bh* +/// - `m` -- *m* +/// - `y` -- *y* +/// - `r` -- *r* +/// - `l` -- *l* +/// - `v` -- *v* +/// - `S` -- *ś* +/// - `z` -- *ṣ* +/// - `s` -- *s* +/// - `h` -- *h* +/// - `\\` -- *anudātta* on the preceding vowel +/// - `^` -- *svarita* on the preceding vowel +/// - `~` -- *anunāsikatva* on the preceding vowel. +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Slp1String(pub(crate) String); + +impl Slp1String { + /// Tries to initialize a new `Slp1String`. + /// + /// ### Usage + /// + /// ``` + /// # use vidyut_prakriya::*; + /// use vidyut_prakriya::args::*; + /// + /// let bhu = Slp1String::from("BU")?; + /// # Ok::<(), Error>(()) + /// ``` + pub fn from(text: impl AsRef) -> Result { + Self::from_inner(text.as_ref()) + } + + fn from_inner(text: &str) -> Result { + let bytes = text.as_bytes(); + for (i, c) in text.char_indices() { + if !c.is_ascii() { + return Err(Error::ParseError(format!("Char `{c}` is not ASCII"))); + } + + if !AL.contains(c) && !matches!(c, '\\' | '^' | '~' | 'M' | 'H') { + return Err(Error::ParseError(format!( + "Char `{c}` is ASCII but not valid SLP1." + ))); + } + + if matches!(c, '\\' | '^' | '~') { + if i == 0 { + return Err(Error::ParseError(format!( + "Char `{c}` must follow a vowel but is the first char in the string." + ))); + } + + let prev = bytes[i - 1] as char; + let prev_is_vowel = AC.contains(prev); + if c == '~' && !prev_is_vowel { + return Err(Error::ParseError(format!( + "Char `~` must follow a vowel but follows `{prev}`." + ))); + } else if !prev_is_vowel && prev != '~' { + return Err(Error::ParseError(format!( + "Char `{c}` must follow a vowel or `~` but follows `{prev}`." + ))); + } + } + } + + Ok(Self(String::from(text))) + } + + // Accessors (experimental) + + #[allow(unused)] + pub(crate) fn get(&self, i: usize) -> Option { + self.0.as_bytes().get(i).map(|x| *x as char) + } + + #[allow(unused)] + pub(crate) fn get_rev(&self, i: usize) -> Option { + self.0.bytes().rev().nth(i).map(|x| x as char) + } + + #[allow(unused)] + pub(crate) fn adi(&self) -> Option { + self.0.bytes().next().map(|x| x as char) + } + + #[allow(unused)] + pub(crate) fn antya(&self) -> Option { + self.0.bytes().last().map(|x| x as char) + } + + #[allow(unused)] + pub(crate) fn upadha(&self) -> Option { + self.get_rev(1) + } + + #[allow(unused)] + pub(crate) fn has_antya(&self, c: char) -> bool { + assert!(c.is_ascii()); + self.0.bytes().last() == Some(c as u8) + } +} + +impl TryFrom for Slp1String { + type Error = Error; + fn try_from(val: String) -> Result { + Slp1String::from(&val) + } +} + +impl TryFrom<&str> for Slp1String { + type Error = Error; + fn try_from(val: &str) -> Result { + Slp1String::from(val) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_validation_cases() { + let success_cases = &[ + "nArAyaRAya", // Sample text. + "", // Empty strings OK. + "aH", // Visarga + "aM", // Anusvara + "ka~", // Anunasika + "ka\\", // Anudatta + "ka^", // Svarita + "ka~\\", // Anunasika + anudatta + "ka~^", // Anunasika + svarita + ]; + for case in success_cases { + assert!(Slp1String::from(case).is_ok(), "Should be Ok: {case}") + } + + let failure_cases = &[ + "अ", // Not ASCII + "!", // Not SLP1 + " ", // Not SLP1 + "5", // Not SLP1 + "\\", // Must follow vowel. + "^", // Must follow vowel. + "~", // Must follow vowel. + "b\\", // Must follow vowel or `~`. + "b^", // Must follow vowel or `~`. + "b~", // Must follow vowel. + "ba\\~", // Must follow vowel. + "ba^~", // Must follow vowel. + ]; + for case in failure_cases { + assert!(Slp1String::from(case).is_err(), "Should be Err: {case}") + } + } +} diff --git a/vidyut-prakriya/src/args/tin.rs b/vidyut-prakriya/src/args/tin.rs index a053616..7fc411c 100644 --- a/vidyut-prakriya/src/args/tin.rs +++ b/vidyut-prakriya/src/args/tin.rs @@ -324,10 +324,10 @@ impl Tinanta { /// ### Example /// /// ```` -/// # use vidyut_prakriya::args::*; -/// # use vidyut_prakriya::Error; +/// # use vidyut_prakriya::*; +/// use vidyut_prakriya::args::*; /// -/// let dhatu = Dhatu::mula("BU", Gana::Bhvadi); +/// let dhatu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi); /// let args = Tinanta::builder() /// .dhatu(dhatu) /// .lakara(Lakara::Lat) diff --git a/vidyut-prakriya/src/core.rs b/vidyut-prakriya/src/core.rs index ecb12d7..3830a64 100644 --- a/vidyut-prakriya/src/core.rs +++ b/vidyut-prakriya/src/core.rs @@ -10,7 +10,6 @@ pub mod errors; pub mod iterators; pub mod operators; pub mod prakriya_stack; -pub mod sanskrit_string; pub(crate) mod prakriya; pub(crate) mod tag; diff --git a/vidyut-prakriya/src/core/operators.rs b/vidyut-prakriya/src/core/operators.rs index 45add86..fd4eb60 100644 --- a/vidyut-prakriya/src/core/operators.rs +++ b/vidyut-prakriya/src/core/operators.rs @@ -119,7 +119,7 @@ pub fn text(sub: &'static str) -> impl Fn(&mut Term) { /// Inserts `agama` at index `i` of the prakriya then runs the it-samjna-prakarana. pub fn insert_before(rule: impl Into, p: &mut Prakriya, index: usize, agama: Agama) { - p.insert_before(index, agama); + p.insert(index, agama); p.step(rule.into()); it_samjna::run(p, index).expect("ok"); } diff --git a/vidyut-prakriya/src/core/prakriya.rs b/vidyut-prakriya/src/core/prakriya.rs index 26906f1..5e01c5c 100644 --- a/vidyut-prakriya/src/core/prakriya.rs +++ b/vidyut-prakriya/src/core/prakriya.rs @@ -626,7 +626,7 @@ impl Prakriya { } } - pub(crate) fn insert_before(&mut self, i: usize, t: impl Into) { + pub(crate) fn insert(&mut self, i: usize, t: impl Into) { self.terms.insert(i, t.into()); } diff --git a/vidyut-prakriya/src/core/sanskrit_string.rs b/vidyut-prakriya/src/core/sanskrit_string.rs deleted file mode 100644 index 0cd699b..0000000 --- a/vidyut-prakriya/src/core/sanskrit_string.rs +++ /dev/null @@ -1,62 +0,0 @@ -use crate::core::errors::{Error, Result}; -use crate::sounds::AL; - -#[allow(unused)] -struct SanskritString(String); - -#[allow(unused)] -impl SanskritString { - pub(crate) fn new() -> Self { - Self(String::new()) - } - - pub(crate) fn from(text: impl AsRef) -> Result { - Self::from_inner(text.as_ref()) - } - - fn from_inner(text: &str) -> Result { - // All chars must be ASCII and valid SLP1. - // - // (The `is_ascii` check is just to be explicit.) - let is_valid = text.is_ascii() - && text - .chars() - .all(|c| AL.contains(c) || matches!(c, '\\' | '^' | '~')); - - if is_valid { - Ok(Self(String::from(text))) - } else { - Err(Error::ParseError( - "Input text must be an ASCII string in SLP1 encoding with no whitespace." - .to_string(), - )) - } - } - - // Accessors - - pub fn get(&self, i: usize) -> Option { - self.0.as_bytes().get(i).map(|x| *x as char) - } - - pub fn get_rev(&self, i: usize) -> Option { - self.0.bytes().rev().nth(i).map(|x| x as char) - } - - pub fn adi(&self) -> Option { - self.0.bytes().next().map(|x| x as char) - } - - pub fn antya(&self) -> Option { - self.0.bytes().last().map(|x| x as char) - } - - pub fn upadha(&self) -> Option { - self.get_rev(1) - } - - pub fn has_antya(&self, c: char) -> bool { - assert!(c.is_ascii()); - self.0.bytes().last() == Some(c as u8) - } -} diff --git a/vidyut-prakriya/src/dhatu_karya.rs b/vidyut-prakriya/src/dhatu_karya.rs index 016c379..babce15 100644 --- a/vidyut-prakriya/src/dhatu_karya.rs +++ b/vidyut-prakriya/src/dhatu_karya.rs @@ -265,13 +265,13 @@ pub fn try_add_prefixes(p: &mut Prakriya, prefixes: &[String]) -> Option<()> { Ok(u) => u.into(), _ => Term::make_upadesha(prefix), }; - p.insert_before(i_offset, t); + p.insert(i_offset, t); samjna::try_nipata_rules(p, i_offset); let mut su = Term::from(Sup::su); su.add_tags(&[T::Pada, T::V1, T::Ekavacana, T::Luk]); su.set_text(""); - p.insert_before(i_offset + 1, su); + p.insert(i_offset + 1, su); // Don't run it-samjna-prakarana for other upasargas (e.g. sam, ud) // TODO: why run only for AN? @@ -329,11 +329,15 @@ pub fn run(p: &mut Prakriya, dhatu: &Muladhatu) -> Result<()> { #[cfg(test)] mod tests { use super::*; + use crate::args::Slp1String; fn check(text: &str, code: &str) -> Term { let (gana, _number) = code.split_once('.').expect("valid"); let gana: u8 = gana.parse().expect("ok"); - let dhatu = Muladhatu::new(text, gana.to_string().parse().unwrap()); + let dhatu = Muladhatu::new( + Slp1String::try_from(text).expect("ok"), + gana.to_string().parse().unwrap(), + ); let mut p = Prakriya::new(); run(&mut p, &dhatu).expect("ok"); p.get(0).expect("ok").clone() diff --git a/vidyut-prakriya/src/dhatupatha.rs b/vidyut-prakriya/src/dhatupatha.rs index ec86674..2e42332 100644 --- a/vidyut-prakriya/src/dhatupatha.rs +++ b/vidyut-prakriya/src/dhatupatha.rs @@ -33,7 +33,7 @@ impl Entry { } /// The numeric code for this entry. - pub fn code(&self) -> &String { + pub fn code(&self) -> &str { &self.code } @@ -43,7 +43,7 @@ impl Entry { } /// The meaning of this dhatu as provided in the Dhatupatha. - pub fn artha(&self) -> &String { + pub fn artha(&self) -> &str { &self.artha } diff --git a/vidyut-prakriya/src/dvitva.rs b/vidyut-prakriya/src/dvitva.rs index fdb1ac6..99a31ec 100644 --- a/vidyut-prakriya/src/dvitva.rs +++ b/vidyut-prakriya/src/dvitva.rs @@ -152,8 +152,8 @@ fn try_dvitva(rule: Code, p: &mut Prakriya, i_dhatu: usize) -> Option<()> { // Case 1b1: abhyasa within dhatu ([und] i sa --> un di [d] i sa) let i_dhatu_old = i_dhatu; let before_abhyasa = Term::make_text(&p_text[..start]); - p.insert_before(i_dhatu, before_abhyasa); - p.insert_before(i_dhatu + 1, abhyasa); + p.insert(i_dhatu, before_abhyasa); + p.insert(i_dhatu + 1, abhyasa); p.set(i_dhatu + 2, |t| t.set_text(&p_text[start..dhatu_len])); let i_abhyasa = i_dhatu_old + 1; @@ -190,10 +190,16 @@ fn try_dvitva(rule: Code, p: &mut Prakriya, i_dhatu: usize) -> Option<()> { if dhatu.starts_with("tC") { abhyasa.set_adi(""); } - p.insert_before(i_dhatu, abhyasa); + + // Insert abhyasa before suw-Agama, if present. + let i_abhyasa = if i_dhatu > 0 && p.has(i_dhatu - 1, |t| t.is(A::suw)) { + i_dhatu - 1 + } else { + i_dhatu + }; + p.insert(i_abhyasa, abhyasa); p.step(rule); - let i_abhyasa = i_dhatu; let i_dhatu = i_dhatu + 1; p.add_tag_at("6.1.4", i_abhyasa, T::Abhyasa); diff --git a/vidyut-prakriya/src/it_agama.rs b/vidyut-prakriya/src/it_agama.rs index c030056..72e3640 100644 --- a/vidyut-prakriya/src/it_agama.rs +++ b/vidyut-prakriya/src/it_agama.rs @@ -130,7 +130,7 @@ impl<'a> ItPrakriya<'a> { /// Inserts it-Agama and prevents further rules. fn try_add_with(&mut self, rule: impl Into, func: impl Fn(&mut Prakriya)) { if !self.done { - self.p.insert_before(self.i_next, A::iw); + self.p.insert(self.i_next, A::iw); func(self.p); self.p.step(rule); @@ -628,9 +628,9 @@ fn run_sarvadhatuke_for_term(ip: &mut ItPrakriya) -> Option<()> { // - possible aprkta --> It agama in the rule below. let is_pit = n.has_tag(T::pit) && !n.has_tag(T::Nit); if n.has_adi(HAL) && n.has_tag(T::Sarvadhatuka) && is_pit && is_aprkta { - let use_at = ip.p.optional_run("7.3.99", |p| p.insert_before(i_n, A::aw)); + let use_at = ip.p.optional_run("7.3.99", |p| p.insert(i_n, A::aw)); if !use_at { - ip.p.run("7.3.98", |p| p.insert_before(i_n, A::Iw)); + ip.p.run("7.3.98", |p| p.insert(i_n, A::Iw)); } it_samjna::run(ip.p, i_n).ok()?; } else { diff --git a/vidyut-prakriya/src/krt/basic.rs b/vidyut-prakriya/src/krt/basic.rs index 42715a7..dfe8035 100644 --- a/vidyut-prakriya/src/krt/basic.rs +++ b/vidyut-prakriya/src/krt/basic.rs @@ -127,7 +127,17 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { || dhatu.has_text_in(&["vft", "vfD", "sah", "car"]) { kp.try_add("3.2.136", izRuc); + } else if kp.dhatu_end().is_nic() && kp.p.is_chandasi() { + // DArayizRu, pArayizRu, ... + kp.try_add("3.2.137", izRuc); + } else if dhatu.has_u_in(&["BU", "BrAjf~\\"]) && kp.p.is_chandasi() { + if !dhatu.has_u("BU") { + kp.p.step(Rule::Kashika("3.2.138")); + } + // BavizRu + kp.try_add("3.2.138", izRuc); } else if dhatu.has_text_in(&["glE", "ji", "sTA", "BU"]) { + // glAsnu, jizRu, sTAsnu, BUzRu kp.try_add("3.2.139", ksnu); } else if dhatu.has_text_in(&["tras", "gfD", "Dfz", "kzip"]) { kp.try_add("3.2.140", knu); @@ -1047,8 +1057,14 @@ fn try_add_krt(kp: &mut KrtPrakriya) -> Option { p.set(i_dhatu, |t| t.set_antya("t")); }); } else if dhatu.has_u_in(&["i\\R", "zwu\\Y", "SAsu~", "vfY", "df", "juzI~\\"]) { - kp.try_add("3.1.109", K::kyap); - avashyaka_blocked = true; + if dhatu.has_u("i\\R") { + // Optional so we can apply 3.3.99 later. + let ok = kp.optional_try_add("3.1.109", K::kyap); + avashyaka_blocked = ok; + } else { + kp.try_add("3.1.109", K::kyap); + avashyaka_blocked = true; + } } else if dhatu.has_upadha('f') && !dhatu.has_text_in(&["kfp", "cft"]) && !skip_3_1_110 { kp.try_add("3.1.110", K::kyap); diff --git a/vidyut-prakriya/src/pratipadika_karya.rs b/vidyut-prakriya/src/pratipadika_karya.rs index 0f901e6..5fa2b54 100644 --- a/vidyut-prakriya/src/pratipadika_karya.rs +++ b/vidyut-prakriya/src/pratipadika_karya.rs @@ -6,9 +6,9 @@ use crate::sounds as al; /// FOO pub fn add_basic(p: &mut Prakriya, basic: &BasicPratipadika) { - let mut base = match basic.text.parse::() { + let mut base = match basic.text.0.parse::() { Ok(u) => u.into(), - _ => Term::make_pratipadika(&basic.text), + _ => Term::make_pratipadika(&basic.text.0), }; // HACK: old implemenation of `Pratipadika` has these tags, so keep them here for consistency diff --git a/vidyut-prakriya/src/samjna.rs b/vidyut-prakriya/src/samjna.rs index 2908fe7..9417c96 100644 --- a/vidyut-prakriya/src/samjna.rs +++ b/vidyut-prakriya/src/samjna.rs @@ -409,6 +409,12 @@ fn try_run_for_dhatu_pratyaya(p: &mut Prakriya, i: usize) -> Option<()> { p.add_tag_at("3.4.115", i, T::Ardhadhatuka); } else if pratyaya.has_lakara(AshirLin) { p.add_tag_at("3.4.116", i, T::Ardhadhatuka); + } else if pratyaya.has_lakara(Let) { + let i_dhatu = p.find_last_where(|t| t.is_dhatu())?; + let dhatu = p.get(i_dhatu)?; + if dhatu.has_u("qukf\\Y") { + p.add_tag_at("3.4.117", i, T::Sarvadhatuka); + } } else if pratyaya.has_tag_in(&[T::Tin, T::Sit]) { if !pratyaya.is_sarvadhatuka() { p.add_tag_at("3.4.113", i, T::Sarvadhatuka); diff --git a/vidyut-prakriya/src/taddhita/nan_snan_adhikara_prakarana.rs b/vidyut-prakriya/src/taddhita/nan_snan_adhikara_prakarana.rs index 826f95a..be2e2e5 100644 --- a/vidyut-prakriya/src/taddhita/nan_snan_adhikara_prakarana.rs +++ b/vidyut-prakriya/src/taddhita/nan_snan_adhikara_prakarana.rs @@ -8,6 +8,8 @@ pub fn run(tp: &mut TaddhitaPrakriya) { let prati = tp.prati(); if prati.has_text_in(gana::PRTHU_ADI) { tp.try_add("5.1.122", imanic); + } else if prati.has_text_in(&["mitrayu"]) { + tp.try_add("5.1.134", vuY); } let code = "5.1.119"; diff --git a/vidyut-prakriya/src/tin_pratyaya.rs b/vidyut-prakriya/src/tin_pratyaya.rs index 070354f..fdd8852 100644 --- a/vidyut-prakriya/src/tin_pratyaya.rs +++ b/vidyut-prakriya/src/tin_pratyaya.rs @@ -129,7 +129,7 @@ fn siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { p.run("3.4.94", |p| { // Add pit to the pratyaya, not the Agama. p.set(i, |t| t.add_tag(T::pit)); - p.insert_before(i, agama); + p.insert(i, agama); }); it_samjna::run(p, i).ok()?; @@ -138,9 +138,12 @@ fn siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { if tin.has_adi('A') { // mantrayEte, mantrayETe ,... p.run_at("3.4.95", i, op::adi("E")); - } else if tin.is_parasmaipada() && tin.has_antya('i') { - // jozizat, patAti, ... - p.optional_run_at("3.4.97", i, op::antya_lopa); + } else if p.has(i_dhatu, |t| t.has_u_in(&["juzI~", "tF", "madi~"])) + && tin.is_parasmaipada() + && tin.has_antya('i') + { + // jozizat, tArizat; patAti, ... + p.run_at("3.4.97", i, op::antya_lopa); } else if p.has_tag(PT::Uttama) && tin.has_antya('s') { // karavAva, karavAma; karavAvaH, karavAmaH p.optional_run_at("3.4.98", i, op::antya_lopa); @@ -189,7 +192,7 @@ fn siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { p.run("3.4.92", |p| { // Add pit to the pratyaya, not the Agama. p.set(i, |t| t.add_tag(T::pit)); - p.insert_before(i, A::Aw); + p.insert(i, A::Aw); }); it_samjna::run(p, i).ok()?; } @@ -249,7 +252,7 @@ fn siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { // liN-only siddhi if p.has(i, |t| t.is_lin_lakara()) { if p.has(i, |t| t.is_parasmaipada()) { - p.insert_before(i, A::yAsuw); + p.insert(i, A::yAsuw); if la == Lakara::AshirLin { // ucyAt // Add kit to the pratyaya, not the Agama. @@ -262,7 +265,7 @@ fn siddhi(p: &mut Prakriya, la: Lakara) -> Option<()> { it_samjna::run(p, i).expect("agama"); } else { // paceta; pakzIzwa - p.insert_before(i, A::sIyuw); + p.insert(i, A::sIyuw); p.step("3.4.102"); it_samjna::run(p, i).expect("agama"); diff --git a/vidyut-prakriya/src/tripadi/pada_8_3.rs b/vidyut-prakriya/src/tripadi/pada_8_3.rs index d7d1040..9b1bd58 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_3.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_3.rs @@ -144,7 +144,7 @@ fn try_add_dhut_agama(p: &mut Prakriya) -> Option<()> { let y = p.get(j)?; if p.is_pada(i) && x.has_antya('q') && y.has_adi('s') { p.optionally("8.3.29", |rule, p| { - p.insert_before(j, A::Duw); + p.insert(j, A::Duw); p.step(rule); it_samjna::run(p, j).ok(); }); diff --git a/vidyut-prakriya/src/vikarana.rs b/vidyut-prakriya/src/vikarana.rs index c525cb7..3a72f0c 100644 --- a/vidyut-prakriya/src/vikarana.rs +++ b/vidyut-prakriya/src/vikarana.rs @@ -299,7 +299,7 @@ fn add_kr_bhu_or_as_after_am_pratyaya(p: &mut Prakriya) { dhatu.set_text("BU"); dhatu.add_tag(T::Dhatu); dhatu.maybe_save_sthanivat(); - p.insert_before(i_tin, dhatu); + p.insert(i_tin, dhatu); if !p.is_bhave_or_karmani() { if p.has_tag(PT::Atmanepada) { @@ -317,7 +317,7 @@ fn add_kr_bhu_or_as_after_am_pratyaya(p: &mut Prakriya) { dhatu.set_text("as"); dhatu.add_tag(T::Dhatu); dhatu.maybe_save_sthanivat(); - p.insert_before(i_tin, dhatu); + p.insert(i_tin, dhatu); if !p.is_bhave_or_karmani() { if p.has_tag(PT::Atmanepada) { @@ -335,7 +335,7 @@ fn add_kr_bhu_or_as_after_am_pratyaya(p: &mut Prakriya) { dhatu.set_text("kf"); dhatu.add_tag(T::Dhatu); dhatu.maybe_save_sthanivat(); - p.insert_before(i_tin, dhatu); + p.insert(i_tin, dhatu); }); } } @@ -420,7 +420,7 @@ fn maybe_add_am_pratyaya_for_lot(p: &mut Prakriya) { kf.add_tag(T::Dhatu); let i_tin = p.terms().len() - 1; - p.insert_before(i_tin, kf); + p.insert(i_tin, kf); p.step("3.1.40") } } @@ -603,19 +603,22 @@ pub fn run(p: &mut Prakriya) -> Option<()> { return None; } - let i_tin = p.find_last_where(|t| t.is_sarvadhatuka())?; - let tin = p.get(i_tin)?; - let i_dhatu = p.find_prev_where(i_tin, |t| t.is_dhatu())?; + let i_last = p.find_last_where(|t| t.is_tin() || t.is_sarvadhatuka())?; + let last = p.get(i_last)?; + let i_dhatu = p.find_prev_where(i_last, |t| t.is_dhatu())?; - if tin.lakara.map_or(false, |la| matches!(la, Lrt | Lrn | Lut)) { - if tin.has_lakara(Lut) { + if last.has_lakara(Lit) { + // See `try_add_am_pratyaya_for_lit`. + } else if last.has_lakara_in(&[Lrt, Lrn, Lut]) { + let code = "3.1.33"; + if last.has_lakara(Lut) { // BavitA - p.run("3.1.33", add_vikarana(tAsi)); + p.run(code, add_vikarana(tAsi)); } else { // Bavizyati - p.run("3.1.33", add_vikarana(sya)); + p.run(code, add_vikarana(sya)); } - } else if tin.has_lakara(Let) { + } else if last.has_lakara(Let) { if uses_sip_vikarana(p, i_dhatu) { // jozizat, mandizat, tArizat p.run("3.1.34", add_vikarana(sip)); @@ -627,15 +630,16 @@ pub fn run(p: &mut Prakriya) -> Option<()> { p.run_at(Varttika("3.1.34.1"), i_dhatu + 1, |t| t.add_tag(T::Rit)); } } - } else if tin.has_lakara(Lun) { + } else if last.has_lakara(Lot) { + // Just for vidāṅkurvantu, etc. + maybe_add_am_pratyaya_for_lot(p); + } else if last.has_lakara(Lun) { add_lun_vikarana(p); - } else if tin.has_lakara(Lit) { - // See `try_add_am_pratyaya_for_lit`. - } else if tin.has_tag(T::Sarvadhatuka) { - if tin.has_lakara(Lot) { - // Just for vidāṅkurvantu, etc. - maybe_add_am_pratyaya_for_lot(p); - } + } + + let i_last = p.find_last_where(|t| t.is_tin() || t.is_sarvadhatuka())?; + let last = p.get(i_last)?; + if !last.has_lakara_in(&[Lit, Lut, Lrt, Lrn, Lun, AshirLin]) { add_sarvadhatuka_vikarana(p); } diff --git a/vidyut-prakriya/src/vyakarana.rs b/vidyut-prakriya/src/vyakarana.rs index 153fef8..4e5d1ae 100644 --- a/vidyut-prakriya/src/vyakarana.rs +++ b/vidyut-prakriya/src/vyakarana.rs @@ -31,7 +31,11 @@ use crate::core::PrakriyaTag as PT; /// ```no_run /// use vidyut_prakriya::Vyakarana; /// -/// let v = Vyakarana::builder().log_steps(false).is_chandasi(true).use_svaras(true).build(); +/// let v = Vyakarana::builder() +/// .log_steps(false) +/// .is_chandasi(true) +/// .use_svaras(true) +/// .build(); /// ``` #[derive(Debug, Default)] pub struct Vyakarana { @@ -81,33 +85,36 @@ impl Vyakarana { /// A *mūla-dhātu* from the Dhatupatha: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let vand = Dhatu::mula("vadi~\\", Gana::Bhvadi); + /// let vand = Dhatu::mula(Slp1String::from("vadi~\\")?, Gana::Bhvadi); /// let prakriyas = v.derive_dhatus(&vand); /// assert_eq!(prakriyas[0].text(), "vand"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *mūla-dhātu* with one or more *upasarga*s: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let gam = Dhatu::mula("ga\\mx~", Gana::Bhvadi); + /// let gam = Dhatu::mula(Slp1String::from("ga\\mx~")?, Gana::Bhvadi); /// let upasangam = gam.with_prefixes(&["upa", "sam"]); /// let prakriyas = v.derive_dhatus(&upasangam); - /// assert_eq!(prakriyas[0].text(), "upasaNgam"); + /// assert_eq!(prakriyas[0].text(), "upasaMgam"); + /// assert_eq!(prakriyas[1].text(), "upasaNgam"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *mūla-dhātu* with one or more *sanādi pratyaya*s: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let vand = Dhatu::mula("vadi~\\", Gana::Bhvadi); + /// let vand = Dhatu::mula(Slp1String::from("vadi~\\")?, Gana::Bhvadi); /// /// let vivandisha = vand.clone().with_sanadi(&[Sanadi::san]); /// let prakriyas = v.derive_dhatus(&vivandisha); @@ -128,31 +135,34 @@ impl Vyakarana { /// let vivandishi = vand.clone().with_sanadi(&[Sanadi::san, Sanadi::Ric]); /// let prakriyas = v.derive_dhatus(&vivandishi); /// assert_eq!(prakriyas[0].text(), "vivandizi"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *nāma-dhātu* with an optional *sanādi pratyaya*: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let putra = Pratipadika::basic("putra"); + /// let putra = Pratipadika::basic(Slp1String::from("putra")?); /// let putriya = Dhatu::nama(putra, Some(Sanadi::kyac)); /// let prakriyas = v.derive_dhatus(&putriya); /// assert_eq!(prakriyas[0].text(), "putrIya"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *nāma-dhātu* with a mandatory *sanādi pratyaya* from some other sutra: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let lohita = Pratipadika::basic("lohita"); + /// let lohita = Pratipadika::basic(Slp1String::from("lohita")?); /// let lohitaya = Dhatu::nama(lohita, None); /// let prakriyas = v.derive_dhatus(&lohitaya); /// // From sutra 3.1.13. /// assert_eq!(prakriyas[0].text(), "lohitAya"); + /// # Ok::<(), Error>(()) /// ```` pub fn derive_dhatus(&self, args: &Dhatu) -> Vec { let mut stack = self.create_prakriya_stack(); @@ -174,7 +184,7 @@ impl Vyakarana { /// /// let v = Vyakarana::new(); /// - /// let bhu = Dhatu::mula("BU", Gana::Bhvadi); + /// let bhu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi); /// let args = Tinanta::builder() /// .dhatu(bhu) /// .lakara(Lakara::Lat) @@ -185,15 +195,16 @@ impl Vyakarana { /// .unwrap(); /// let prakriyas = v.derive_tinantas(&args); /// assert_eq!(prakriyas[0].text(), "Bavati"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *tiṅanta* with one or more *upasarga*s: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// # let v = Vyakarana::new(); - /// let abhibhu = Dhatu::mula("BU", Gana::Bhvadi).with_prefixes(&["aBi"]); + /// let abhibhu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi).with_prefixes(&["aBi"]); /// let args = Tinanta::builder() /// .dhatu(abhibhu) /// .lakara(Lakara::Lat) @@ -204,15 +215,16 @@ impl Vyakarana { /// .unwrap(); /// let prakriyas = v.derive_tinantas(&args); /// assert_eq!(prakriyas[0].text(), "aBiBavati"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *tiṅanta* whose *dhātu* has one or more *sanādi-pratyaya*s: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// # let v = Vyakarana::new(); - /// let bobhuya = Dhatu::mula("BU", Gana::Bhvadi).with_sanadi(&[Sanadi::yaN]); + /// let bobhuya = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi).with_sanadi(&[Sanadi::yaN]); /// let args = Tinanta::builder() /// .dhatu(bobhuya) /// .lakara(Lakara::Lat) @@ -223,16 +235,17 @@ impl Vyakarana { /// .unwrap(); /// let prakriyas = v.derive_tinantas(&args); /// assert_eq!(prakriyas[0].text(), "boBUyate"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *tiṅanta* that must use *ātmanepada*. If the *dhātu* cannot support the requested *pada*, /// this method returns no results: /// /// ``` - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// # let v = Vyakarana::new(); - /// let kr = Dhatu::mula("qukf\\Y", Gana::Tanadi); + /// let kr = Dhatu::mula(Slp1String::from("qukf\\Y")?, Gana::Tanadi); /// let args = Tinanta::builder() /// .dhatu(kr) /// .lakara(Lakara::Lat) @@ -244,16 +257,16 @@ impl Vyakarana { /// .unwrap(); /// let prakriyas = v.derive_tinantas(&args); /// assert_eq!(prakriyas[0].text(), "kurute"); + /// # Ok::<(), Error>(()) /// ``` /// /// A *tiṅanta* with one or more *upasarga*s: /// /// ``` - /// # use vidyut_prakriya::Error; - /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// # let v = Vyakarana::new(); - /// let abhibhu = Dhatu::mula("BU", Gana::Bhvadi).with_prefixes(&["aBi"]); + /// let abhibhu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi).with_prefixes(&["aBi"]); /// let args = Tinanta::builder() /// .dhatu(abhibhu) /// .lakara(Lakara::Lat) @@ -272,7 +285,7 @@ impl Vyakarana { /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// # let v = Vyakarana::new(); - /// let bobhuya = Dhatu::mula("BU", Gana::Bhvadi).with_sanadi(&[Sanadi::yaN]); + /// let bobhuya = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi).with_sanadi(&[Sanadi::yaN]); /// let args = Tinanta::builder() /// .dhatu(bobhuya) /// .lakara(Lakara::Lat) @@ -292,7 +305,7 @@ impl Vyakarana { /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// # let v = Vyakarana::new(); - /// let kr = Dhatu::mula("qukf\\Y", Gana::Tanadi); + /// let kr = Dhatu::mula(Slp1String::from("qukf\\Y")?, Gana::Tanadi); /// let args = Tinanta::builder() /// .dhatu(kr) /// .lakara(Lakara::Lat) @@ -339,7 +352,7 @@ impl Vyakarana { /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); /// let args = Subanta::builder() - /// .pratipadika(Pratipadika::basic("nara")) + /// .pratipadika(Pratipadika::basic(Slp1String::from("nara")?)) /// .linga(Linga::Pum) /// .vibhakti(Vibhakti::Trtiya) /// .vacana(Vacana::Eka) @@ -365,7 +378,7 @@ impl Vyakarana { /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let dhatu = Dhatu::mula("BU", Gana::Bhvadi); + /// let dhatu = Dhatu::mula(Slp1String::from("BU")?, Gana::Bhvadi); /// let args = Krdanta::new(dhatu, BaseKrt::ktvA); /// let prakriyas = v.derive_krdantas(&args); /// assert_eq!(prakriyas[0].text(), "BUtvA"); @@ -378,7 +391,7 @@ impl Vyakarana { /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let dhatu = Dhatu::mula("dF", Gana::Kryadi); + /// let dhatu = Dhatu::mula(Slp1String::from("dF")?, Gana::Kryadi); /// let args = Krdanta::new(dhatu, Unadi::YuR); /// let prakriyas = v.derive_krdantas(&args); /// assert_eq!(prakriyas[0].text(), "dAru"); @@ -401,7 +414,7 @@ impl Vyakarana { /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); /// let args = Taddhitanta::builder() - /// .pratipadika(Pratipadika::basic("nara")) + /// .pratipadika(Pratipadika::basic(Slp1String::from("nara")?)) /// .taddhita(Taddhita::matup) /// .build()?; /// let prakriyas = v.derive_taddhitantas(&args); @@ -421,12 +434,12 @@ impl Vyakarana { /// ### Example /// /// ``` - /// # use vidyut_prakriya::Vyakarana; - /// # use vidyut_prakriya::Error; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); - /// let pratipadika = Pratipadika::basic("nara"); + /// let pratipadika = Pratipadika::basic(Slp1String::from("nara")?); /// let prakriyas = v.derive_stryantas(&pratipadika); + /// # Ok::<(), Error>(()) /// ``` pub fn derive_stryantas(&self, pratipadika: &Pratipadika) -> Vec { let mut stack = self.create_prakriya_stack(); @@ -444,8 +457,8 @@ impl Vyakarana { /// # use vidyut_prakriya::args::*; /// let v = Vyakarana::new(); /// - /// let rajan = Pratipadika::basic("rAjan"); - /// let purusha = Pratipadika::basic("puruza"); + /// let rajan = Pratipadika::basic(Slp1String::from("rAjan")?); + /// let purusha = Pratipadika::basic(Slp1String::from("puruza")?); /// let args = Samasa::builder() /// .padas(vec![ /// Subanta::new(rajan, Linga::Pum, Vibhakti::Sasthi, Vacana::Eka), @@ -472,8 +485,7 @@ impl Vyakarana { /// ### Example /// /// ``` - /// # use vidyut_prakriya::Vyakarana; - /// # use vidyut_prakriya::Error; + /// # use vidyut_prakriya::*; /// # use vidyut_prakriya::args::*; /// /// let v = Vyakarana::new(); diff --git a/vidyut-prakriya/src/wasm.rs b/vidyut-prakriya/src/wasm.rs index db2d058..bd27fd4 100644 --- a/vidyut-prakriya/src/wasm.rs +++ b/vidyut-prakriya/src/wasm.rs @@ -192,7 +192,9 @@ impl KrdantaArgs { impl SubantaArgs { fn into_rust(self) -> Subanta { Subanta::builder() - .pratipadika(Pratipadika::basic(self.pratipadika)) + .pratipadika(Pratipadika::basic( + Slp1String::from(self.pratipadika).expect("ok"), + )) .linga(self.linga) .vacana(self.vacana) .vibhakti(self.vibhakti) diff --git a/vidyut-prakriya/test_utils/src/lib.rs b/vidyut-prakriya/test_utils/src/lib.rs index 2f61e3e..cf5d79c 100644 --- a/vidyut-prakriya/test_utils/src/lib.rs +++ b/vidyut-prakriya/test_utils/src/lib.rs @@ -6,6 +6,7 @@ manage the boilerplate required for these assertions. */ extern crate vidyut_prakriya; +use std::convert::TryInto; use vidyut_prakriya::args::Antargana; use vidyut_prakriya::args::DhatuPada::*; use vidyut_prakriya::args::Prayoga::*; @@ -22,6 +23,64 @@ fn pum_s(pratipadika: Pratipadika, vibhakti: Vibhakti) -> Subanta { Subanta::new(pratipadika, Linga::Pum, vibhakti, Vacana::Eka) } +/// A wrapper for `Pratipadika` that supports From<&str> (as opposed to TryFrom<&str>). +#[derive(Clone)] +pub struct SafePratipadika(pub Pratipadika); + +impl From<&str> for SafePratipadika { + fn from(val: &str) -> Self { + Self(Pratipadika::basic(Slp1String::from(val).expect("ok"))) + } +} + +impl From<&Krdanta> for SafePratipadika { + fn from(val: &Krdanta) -> Self { + Self(val.into()) + } +} + +impl From for SafePratipadika { + fn from(val: Krdanta) -> Self { + Self(val.into()) + } +} + +impl From<&Pratipadika> for SafePratipadika { + fn from(val: &Pratipadika) -> Self { + Self(val.into()) + } +} + +impl From for SafePratipadika { + fn from(val: Pratipadika) -> Self { + Self(val) + } +} + +impl From for SafePratipadika { + fn from(val: Samasa) -> Self { + Self(val.into()) + } +} + +impl From<&Samasa> for SafePratipadika { + fn from(val: &Samasa) -> Self { + Self(val.into()) + } +} + +impl From<&Taddhitanta> for SafePratipadika { + fn from(val: &Taddhitanta) -> Self { + Self(val.into()) + } +} + +impl From for SafePratipadika { + fn from(val: Taddhitanta) -> Self { + Self(val.into()) + } +} + /// A handy way to manage various assertions. /// /// `Vyakarana` with its default settings will ignore certain rules. Some of these rules are @@ -79,13 +138,13 @@ impl Tester { /// Derives taddhitantas in a specific meaning context from the given conditions. fn derive_artha_taddhitantas( &self, - p: impl Into, + p: impl Into, t: Taddhita, a: Option, ) -> Vec { let args = if let Some(a) = a { Taddhitanta::builder() - .pratipadika(p.into()) + .pratipadika(p.into().0) .taddhita(t) .artha(a) .build() @@ -130,7 +189,7 @@ impl Tester { assert_has_results(actual, expected); } - pub fn assert_has_krt( + pub fn assert_has_krdanta( &self, prefixes: &[&str], dhatu: &Dhatu, @@ -150,7 +209,7 @@ impl Tester { pub fn assert_has_upapada_krdanta( &self, - upapada: impl Into, + upapada: impl Into, prefixes: &[&str], dhatu: &Dhatu, krt: impl Into, @@ -164,7 +223,7 @@ impl Tester { pub fn assert_has_taddhita( &self, - prati: impl Into, + prati: impl Into, t: Taddhita, expected: &[&str], ) { @@ -176,7 +235,7 @@ impl Tester { pub fn assert_has_artha_taddhita( &self, - prati: impl Into, + prati: impl Into, requested_artha: TaddhitaArtha, t: Taddhita, expected: &[&str], @@ -211,26 +270,26 @@ impl Default for Tester { // --------- pub fn d(u: &str, g: Gana) -> Dhatu { - Dhatu::mula(u, g) + Dhatu::mula(u.try_into().expect("ok"), g) } pub fn d_kutadi(u: &str, g: Gana) -> Dhatu { - let mula = Muladhatu::new(u, g).with_antargana(Antargana::Kutadi); + let mula = Muladhatu::new(u.try_into().expect("ok"), g).with_antargana(Antargana::Kutadi); Dhatu::Mula(mula) } pub fn d_akusmiya(u: &str, g: Gana) -> Dhatu { - let mula = Muladhatu::new(u, g).with_antargana(Antargana::Akusmiya); + let mula = Muladhatu::new(u.try_into().expect("ok"), g).with_antargana(Antargana::Akusmiya); Dhatu::Mula(mula) } pub fn d_adhrshiya(u: &str, g: Gana) -> Dhatu { - let mula = Muladhatu::new(u, g).with_antargana(Antargana::Adhrshiya); + let mula = Muladhatu::new(u.try_into().expect("ok"), g).with_antargana(Antargana::Adhrshiya); Dhatu::Mula(mula) } pub fn d_ghatadi(u: &str, g: Gana) -> Dhatu { - let mula = Muladhatu::new(u, g).with_antargana(Antargana::Ghatadi); + let mula = Muladhatu::new(u.try_into().expect("ok"), g).with_antargana(Antargana::Ghatadi); Dhatu::Mula(mula) } @@ -263,6 +322,10 @@ pub fn yan_luk(dhatu: &Dhatu) -> Dhatu { dhatu.clone().with_sanadi(&[Sanadi::yaNluk]) } +pub fn phit(s: &str) -> Pratipadika { + Pratipadika::basic(Slp1String::from(s).expect("ok")) +} + pub fn krdanta(prefixes: &[&str], d: &Dhatu, krt: impl Into) -> Krdanta { Krdanta::builder() .dhatu(d.clone().with_prefixes(prefixes)) @@ -272,12 +335,17 @@ pub fn krdanta(prefixes: &[&str], d: &Dhatu, krt: impl Into) -> Krdanta { } pub fn upapada_krdanta( - upapada: impl Into, + upapada: impl Into, prefixes: &[&str], d: &Dhatu, krt: impl Into, ) -> Krdanta { - let upapada = Subanta::new(upapada.into(), Linga::Pum, Vibhakti::Prathama, Vacana::Eka); + let upapada = Subanta::new( + upapada.into().0, + Linga::Pum, + Vibhakti::Prathama, + Vacana::Eka, + ); Krdanta::builder() .dhatu(d.clone().with_prefixes(prefixes)) .krt(krt) @@ -286,21 +354,21 @@ pub fn upapada_krdanta( .unwrap() } -pub fn taddhitanta(prati: impl Into, taddhita: Taddhita) -> Taddhitanta { +pub fn taddhitanta(prati: impl Into, taddhita: Taddhita) -> Taddhitanta { Taddhitanta::builder() - .pratipadika(prati.into()) + .pratipadika(prati.into().0) .taddhita(taddhita) .build() .unwrap() } pub fn artha_taddhitanta( - prati: impl Into, + prati: impl Into, artha: TaddhitaArtha, taddhita: Taddhita, ) -> Taddhitanta { Taddhitanta::builder() - .pratipadika(prati.into()) + .pratipadika(prati.into().0) .artha(artha) .taddhita(taddhita) .build() @@ -309,35 +377,41 @@ pub fn artha_taddhitanta( /// Shorthand for building a pratipadika that ends with NI/Ap. pub fn nyap(text: &str) -> Pratipadika { - Pratipadika::nyap(text) + Pratipadika::nyap(text.try_into().expect("ok")) } -pub fn karmadharaya(x: impl Into, y: impl Into) -> Samasa { +pub fn karmadharaya(x: impl Into, y: impl Into) -> Samasa { use Vibhakti::*; Samasa::builder() - .padas(vec![pum_s(x.into(), Prathama), pum_s(y.into(), Prathama)]) + .padas(vec![ + pum_s(x.into().0, Prathama), + pum_s(y.into().0, Prathama), + ]) .samasa_type(SamasaType::Karmadharaya) .build() .unwrap() } pub fn tatpurusha( - x: impl Into, - y: impl Into, + x: impl Into, + y: impl Into, vibhakti: Vibhakti, ) -> Samasa { use Vibhakti::*; Samasa::builder() - .padas(vec![pum_s(x.into(), vibhakti), pum_s(y.into(), Prathama)]) + .padas(vec![ + pum_s(x.into().0, vibhakti), + pum_s(y.into().0, Prathama), + ]) .samasa_type(SamasaType::Tatpurusha) .build() .unwrap() } -pub fn avyaya_tatpurusha(x: impl Into, y: impl Into) -> Samasa { +pub fn avyaya_tatpurusha(x: impl Into, y: impl Into) -> Samasa { let padas = vec![ - Subanta::avyaya(x.into()), - Subanta::new(y.into(), Linga::Pum, Vibhakti::Prathama, Vacana::Eka), + Subanta::avyaya(x.into().0), + Subanta::new(y.into().0, Linga::Pum, Vibhakti::Prathama, Vacana::Eka), ]; Samasa::builder() .padas(padas) @@ -346,10 +420,13 @@ pub fn avyaya_tatpurusha(x: impl Into, y: impl Into) - .unwrap() } -pub fn bahuvrihi(x: impl Into, y: impl Into) -> Samasa { +pub fn bahuvrihi(x: impl Into, y: impl Into) -> Samasa { use Vibhakti::*; Samasa::builder() - .padas(vec![pum_s(x.into(), Prathama), pum_s(y.into(), Prathama)]) + .padas(vec![ + pum_s(x.into().0, Prathama), + pum_s(y.into().0, Prathama), + ]) .samasa_type(SamasaType::Bahuvrihi) .build() .unwrap() @@ -478,14 +555,19 @@ test_la!(assert_has_lrn, Lakara::Lrn); macro_rules! assert_sup { ($fn_name:ident, $vibhakti:expr, $vacana:expr) => { impl Tester { - pub fn $fn_name(&self, prati: impl Into, linga: Linga, expected: &[&str]) { - self.assert_has_subantas(&prati.into(), linga, $vibhakti, $vacana, &expected); + pub fn $fn_name( + &self, + prati: impl Into, + linga: Linga, + expected: &[&str], + ) { + self.assert_has_subantas(&prati.into().0, linga, $vibhakti, $vacana, &expected); } } - pub fn $fn_name(prati: impl Into, linga: Linga, expected: &[&str]) { + pub fn $fn_name(prati: impl Into, linga: Linga, expected: &[&str]) { let t = Tester::default(); - t.assert_has_subantas(&prati.into(), linga, $vibhakti, $vacana, &expected); + t.assert_has_subantas(&prati.into().0, linga, $vibhakti, $vacana, &expected); } }; } @@ -517,9 +599,9 @@ assert_sup!(assert_has_sup_sp, Sambodhana, Bahu); macro_rules! create_sup { ($fn_name:ident, $vibhakti:expr, $vacana:expr) => { - pub fn $fn_name(_expected: &str, prati: impl Into, linga: Linga) -> Pada { + pub fn $fn_name(_expected: &str, prati: impl Into, linga: Linga) -> Pada { Subanta::builder() - .pratipadika(prati.into()) + .pratipadika(prati.into().0) .linga(linga) .vibhakti($vibhakti) .vacana($vacana) @@ -564,7 +646,7 @@ pub fn assert_has_subantas_raw( vacana: Vacana, expected: &[&str], ) { - let pratipadika = Pratipadika::basic(pratipadika_text); + let pratipadika = Pratipadika::basic(pratipadika_text.try_into().expect("ok")); let v = Vyakarana::new(); let args = Subanta::builder() .pratipadika(pratipadika) @@ -592,7 +674,7 @@ pub fn assert_has_krdanta( expected: &[&str], ) { let t = Tester::default(); - t.assert_has_krt(prefixes, dhatu, krt, expected); + t.assert_has_krdanta(prefixes, dhatu, krt, expected); } pub fn assert_has_artha_krdanta( @@ -623,7 +705,7 @@ pub fn assert_has_artha_krdanta( } pub fn assert_has_upapada_krdanta( - upapada: impl Into, + upapada: impl Into, prefixes: &[&str], dhatu: &Dhatu, krt: impl Into, @@ -667,7 +749,7 @@ pub fn create_upapada_krdanta( /// This function is a shorthand that lets us test certain subanta forms more easily. pub fn create_taddhitanta( text: &str, - base: impl Into, + base: impl Into, taddhita: Taddhita, ) -> Taddhitanta { taddhitanta(base, taddhita).with_require(text) @@ -678,25 +760,29 @@ pub fn create_taddhitanta( /// This function is a shorthand that lets us test certain subanta forms more easily. pub fn create_artha_taddhita( _text: &str, - base: impl Into, + base: impl Into, artha: TaddhitaArtha, taddhita: Taddhita, ) -> Taddhitanta { Taddhitanta::builder() - .pratipadika(base.into()) + .pratipadika(base.into().0) .taddhita(taddhita) .artha(artha) .build() .unwrap() } -pub fn assert_has_taddhita(prati: impl Into, taddhita: Taddhita, expected: &[&str]) { +pub fn assert_has_taddhita( + prati: impl Into, + taddhita: Taddhita, + expected: &[&str], +) { let t = Tester::default(); t.assert_has_taddhita(prati.into(), taddhita, expected); } pub fn assert_has_artha_taddhita( - prati: impl Into, + prati: impl Into, requested_artha: TaddhitaArtha, taddhita: Taddhita, expected: &[&str], @@ -730,8 +816,8 @@ impl Tester { pub fn assert_has_bahuvrihi( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&bahuvrihi(a, b), expected); @@ -739,13 +825,13 @@ impl Tester { fn assert_has_avyayibhava( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { let padas = vec![ - Subanta::avyaya(a.into()), - Subanta::new(b.into(), Linga::Pum, Vibhakti::Prathama, Vacana::Eka), + Subanta::avyaya(a.into().0), + Subanta::new(b.into().0, Linga::Pum, Vibhakti::Prathama, Vacana::Eka), ]; let args = Samasa::builder() .padas(padas) @@ -768,8 +854,8 @@ impl Tester { pub fn assert_has_karmadharaya( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&karmadharaya(a, b), expected); @@ -777,8 +863,8 @@ impl Tester { pub fn assert_has_dvitiya_tatpurusha( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Dvitiya), expected); @@ -786,8 +872,8 @@ impl Tester { pub fn assert_has_trtiya_tatpurusha( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Trtiya), expected); @@ -795,8 +881,8 @@ impl Tester { fn assert_has_caturthi_tatpurusha( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Caturthi), expected); @@ -804,8 +890,8 @@ impl Tester { fn assert_has_panchami_tatpurusha( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Panchami), expected); @@ -813,8 +899,8 @@ impl Tester { fn assert_has_sasthi_tatpurusha( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Sasthi), expected); @@ -822,8 +908,8 @@ impl Tester { fn assert_has_saptami_tatpurusha( &self, - a: impl Into, - b: impl Into, + a: impl Into, + b: impl Into, expected: &[&str], ) { self.assert_has_samasas(&tatpurusha(a, b, Vibhakti::Saptami), expected); @@ -833,8 +919,8 @@ impl Tester { macro_rules! assert_samasa { ($fn_name:ident) => { pub fn $fn_name( - purva: impl Into, - uttara: impl Into, + purva: impl Into, + uttara: impl Into, expected: &[&str], ) { let t = Tester::default(); @@ -854,15 +940,15 @@ assert_samasa!(assert_has_sasthi_tatpurusha); assert_samasa!(assert_has_saptami_tatpurusha); pub fn assert_has_avyaya_tatpurusha( - first: impl Into, - second: impl Into, + first: impl Into, + second: impl Into, expected: &[&str], ) { let t = Tester::default(); t.assert_samasa_of_type( &[ - Subanta::avyaya(first.into()), - pum_s(second.into(), Prathama), + Subanta::avyaya(first.into().0), + pum_s(second.into().0, Prathama), ], Tatpurusha, expected, @@ -870,8 +956,8 @@ pub fn assert_has_avyaya_tatpurusha( } pub fn assert_has_misc_tatpurusha( - first: impl Into, - second: impl Into, + first: impl Into, + second: impl Into, expected: &[&str], ) { assert_has_sasthi_tatpurusha(first, second, expected); @@ -882,7 +968,12 @@ pub fn assert_has_dvandva(items: &[&str], expected: &[&str]) { .padas( items .iter() - .map(|s| pum_s(Pratipadika::basic(s), Vibhakti::Prathama)) + .map(|s| { + pum_s( + Pratipadika::basic((*s).try_into().expect("ok")), + Vibhakti::Prathama, + ) + }) .collect(), ) .samasa_type(Dvandva) @@ -897,7 +988,12 @@ pub fn assert_has_samahara_dvandva(items: &[&str], expected: &[&str]) { .padas( items .iter() - .map(|s| pum_s(Pratipadika::basic(s), Vibhakti::Prathama)) + .map(|s| { + pum_s( + Pratipadika::basic((*s).try_into().expect("ok")), + Vibhakti::Prathama, + ) + }) .collect(), ) .samasa_type(SamaharaDvandva) @@ -912,8 +1008,8 @@ pub fn assert_has_samahara_dvandva(items: &[&str], expected: &[&str]) { /// This function is a shorthand that lets us test certain subanta forms more easily. pub fn create_avyaya_tatpurusha( _text: &str, - first: impl Into, - second: impl Into, + first: impl Into, + second: impl Into, ) -> Samasa { avyaya_tatpurusha(first, second) } diff --git a/vidyut-prakriya/tests/integration/api.rs b/vidyut-prakriya/tests/integration/api.rs index 7a4eae5..ac1f798 100644 --- a/vidyut-prakriya/tests/integration/api.rs +++ b/vidyut-prakriya/tests/integration/api.rs @@ -5,33 +5,87 @@ Basic tests against our high-level API. These tests verify two important things: 2. That the function can handle pathological input without panicking. */ extern crate test_utils; + +use std::convert::TryInto; use test_utils::assert_has_results; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::*; use vidyut_prakriya::Vyakarana; +/// Checks that Enum string representations exist and are 1:1. +#[test] +fn enum_as_str_and_from_string() { + for val in Gana::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Krt::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Lakara::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Linga::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Prayoga::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Purusha::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Sanadi::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Taddhita::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Unadi::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Vacana::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } + + for val in Vibhakti::iter() { + assert_eq!(val, val.as_str().parse().expect("ok")); + } +} + fn assert_derive_dhatu(dhatu: Dhatu, expected: &[&str]) { let v = Vyakarana::new(); let prakriyas = v.derive_dhatus(&dhatu); assert_has_results(prakriyas, expected); } +fn mula(u: &str, gana: Gana) -> Dhatu { + Dhatu::mula(u.try_into().expect("ok"), gana) +} + #[test] fn derive_dhatus_for_mula_dhatus() { // Basic dhatus - assert_derive_dhatu(Dhatu::mula("BU", Bhvadi), &["BU"]); - assert_derive_dhatu(Dhatu::mula("eDa~\\", Bhvadi), &["eD"]); - assert_derive_dhatu(Dhatu::mula("qukf\\Y", Tanadi), &["kf"]); - assert_derive_dhatu(Dhatu::mula("gADf~\\", Bhvadi), &["gAD"]); + assert_derive_dhatu(mula("BU", Bhvadi), &["BU"]); + assert_derive_dhatu(mula("eDa~\\", Bhvadi), &["eD"]); + assert_derive_dhatu(mula("qukf\\Y", Tanadi), &["kf"]); + assert_derive_dhatu(mula("gADf~\\", Bhvadi), &["gAD"]); } #[test] fn derive_dhatus_for_mula_dhatus_and_upasargas() { - let pranici = Dhatu::mula("ci\\Y", Svadi).with_prefixes(&["pra", "ni"]); + let pranici = mula("ci\\Y", Svadi).with_prefixes(&["pra", "ni"]); assert_derive_dhatu(pranici, &["praRici"]); - let sanskr = Dhatu::mula("qukf\\Y", Tanadi).with_prefixes(&["sam"]); + let sanskr = mula("qukf\\Y", Tanadi).with_prefixes(&["sam"]); assert_derive_dhatu(sanskr, &["saNkf", "saMskf", "saMkf"]); } @@ -39,22 +93,25 @@ fn derive_dhatus_for_mula_dhatus_and_upasargas() { fn derive_dhatus_for_nama_dhatus() { // with explicit sanAdi assert_derive_dhatu( - Dhatu::nama("putra".into(), Some(Sanadi::kyac)), + Dhatu::nama("putra".try_into().expect("ok"), Some(Sanadi::kyac)), &["putrIya"], ); assert_derive_dhatu( - Dhatu::nama("putra".into(), Some(Sanadi::kAmyac)), + Dhatu::nama("putra".try_into().expect("ok"), Some(Sanadi::kAmyac)), &["putrakAmya"], ); // with inferred sanAdi - assert_derive_dhatu(Dhatu::nama("lohita".into(), None), &["lohitAya"]); + assert_derive_dhatu( + Dhatu::nama("lohita".try_into().expect("ok"), None), + &["lohitAya"], + ); } #[test] fn derive_tinantas() { let v = Vyakarana::new(); - let kr = Dhatu::mula("qukf\\Y", Gana::Tanadi); + let kr = mula("qukf\\Y", Gana::Tanadi); // Should get 2 results. let args_ubhaya = Tinanta::builder() diff --git a/vidyut-prakriya/tests/integration/basic_krdantas.rs b/vidyut-prakriya/tests/integration/basic_krdantas.rs deleted file mode 100644 index be707e1..0000000 --- a/vidyut-prakriya/tests/integration/basic_krdantas.rs +++ /dev/null @@ -1,476 +0,0 @@ -/*! -Various test cases for krdantas. - -Each of the test functions below tests a single krt-pratyaya. These tests are arranged in -the standard Sanskrit alphabetical order by the aupadeshika form of the krt pratyaya being tested. - -Test cases marked with *Kale* are from M. R. Kale's *A Higher Sanskrit Grammar*. -*/ -use vidyut_prakriya::args::BaseKrt as Krt; -use vidyut_prakriya::args::*; -use vidyut_prakriya::Vyakarana; - -/// Creates a krdanta with the given args. -fn create_krdanta(dhatu: &str, gana: &str, krt: BaseKrt) -> Vec { - let v = Vyakarana::new(); - let dhatu = Dhatu::mula(dhatu, gana.parse().expect("ok")); - let args = Krdanta::builder().dhatu(dhatu).krt(krt).build().unwrap(); - - let prakriyas = v.derive_krdantas(&args); - prakriyas.iter().map(|p| p.text()).collect() -} - -/// Tests all of the given test cases against the given krt-pratyaya. -fn test_krdanta(cases: &Vec<(&'static str, u8, &'static str)>, krt: BaseKrt) { - let mut num_errors = 0; - for (dhatu, gana, expected) in cases { - let mut expected: Vec<_> = expected.split('|').collect(); - expected.sort(); - expected.dedup(); - - let mut actual = create_krdanta(dhatu, &gana.to_string(), krt); - actual.sort(); - actual.dedup(); - - if actual != expected { - println!("Expected : {expected:?}"); - println!("Actual : {actual:?}"); - println!(); - num_errors += 1; - } - } - if num_errors > 0 { - let n = cases.len(); - let num_ok = n - num_errors; - println!("{num_ok} / {n} tests passed."); - } - assert_eq!(num_errors, 0); -} - -#[test] -fn aniya() { - let cases = vec![ - // Kale 712 - ("qudA\\Y", 3, "dAnIya"), - ("ci\\Y", 5, "cayanIya"), - ("RI\\Y", 1, "nayanIya"), - ("Sru\\", 1, "SravaRIya"), - ("BU", 1, "BavanIya"), - ("qukf\\Y", 8, "karaRIya"), - ("mu\\cx~^", 6, "mocanIya"), - ("mfjU~", 2, "mArjanIya"), - ("sf\\ja~\\", 6, "sarjanIya"), - ("Bra\\sja~^", 6, "BarjanIya|BrajjanIya"), - ("Bi\\di~^r", 7, "BedanIya"), - ("Ridi~", 1, "nindanIya"), - ("guhU~^", 1, "gUhanIya"), - // Kale 713 - ("kaTa", 10, "kaTanIya"), - ("cura~", 10, "coraRIya"), - ]; - - test_krdanta(&cases, Krt::anIyar); -} - -#[test] -fn kanac() { - let cases = vec![ - // Kale 675 (a) - ("RI\\Y", 1, "ninyAna"), - ("qudA\\Y", 3, "dadAna"), - ("qupa\\ca~^z", 1, "pecAna"), - ("ya\\ja~^", 1, "IjAna"), - ("qukf\\Y", 8, "cakrARa"), - ("va\\ca~", 2, "UcAna"), - ("zwu\\Y", 2, "tuzwuvAna"), - ("Sru\\", 1, "SuSruvARa"), - ]; - - test_krdanta(&cases, Krt::kAnac); -} - -#[ignore] -#[test] -fn kta() { - // TODO: expand "yasyeti ca" - let cases = vec![ - // Kale 679 -- basic examples - ("zRA\\", 2, "snAta"), - ("ji\\", 1, "jita"), - ("RI\\Y", 1, "nIta"), - ("Sru\\", 1, "Sruta"), - ("BU", 1, "BUta"), - ("hf\\", 3, "hfta"), - ("tya\\ja~", 1, "tyakta"), - // Kale 681 (a) -- guna - ("SIN", 2, "Sayita"), - // The four below are allowed by 7.2.17. - // ("YizvidA~\\", 1, "svedita"), - // ("YimidA~", 1, "medita"), - // ("YikzvidA~", 1, "kzvedita"), - // ("YiDfzA~~", 5, "Darzita"), - // Kale 681 (b). - ("muda~\\", 1, "mudita"), - // Kale 684 -- general rules - ("pA\\", 2, "pAta"), - ("SriY", 1, "Srita"), - // nIta, Sruta, and BUta are above. - ("qukf\\Y", 8, "kfta"), - ("UrRuY", 1, "UrRuta"), - ("ve\\Y", 1, "uta"), - ("vye\\Y", 1, "vIta"), - ("hve\\Y", 1, "hUta"), - // "tyakta" is above. - ("Bra\\sja~^", 1, "Bfzwa"), - ("ya\\ja~^", 1, "izwa"), - ("bu\\Da~\\", 1, "budDa"), - ("vya\\Da~", 1, "vidDa"), - ("Yizva\\pa~", 1, "supta"), - ("qula\\Ba~\\z", 1, "labDa"), - ("ba\\nDa~", 9, "badDa"), - ("df\\Si~r", 1, "dfzwa"), - ("kru\\Sa~", 1, "kruzwa"), - ("va\\ca~", 2, "ukta"), - ("guhU~^", 1, "gUQa"), - ("mfjU~", 2, "mfzwa"), - ("zi\\Du~", 4, "sidDa"), - // ("tf\\pa~", 4, "tfpta"), - // ("Ra\\Sa~", 1, "nazwa"), - ("vfDu~\\", 1, "vfdDa"), - ("vftu~\\", 1, "vftta"), - ("Sa\\kx~", 5, "Sakta"), - ("zi\\ca~", 6, "sikta"), - ("pra\\Ca~", 6, "pfzwa"), - ("da\\nSa~", 1, "dazwa"), - // Kale erroneously has "dizwa." - ("dvi\\za~^", 2, "dvizwa"), - ("SAsu~", 2, "Sizwa"), - ("da\\ha~", 1, "dagDa"), - ("va\\ha~^", 1, "UQa"), - ("zaha~\\", 1, "soQa"), - ("Dvansu~\\", 6, "Dvasta"), - ("li\\ha~^", 2, "lIQa"), - ("mu\\ha~", 6, "mugDa|mUQa"), - ("Ra\\ha~^", 6, "nadDa"), - ("sransu~\\", 6, "srasta"), - // Kale 685 -- seT - ("Saki~\\", 1, "SaNkita"), - ("vada~", 1, "udita"), - ("kaTa", 10, "kaTita"), - ("praTa~\\", 1, "praTita"), - ("eDa~\\", 1, "eDita"), - ("kapi~\\", 1, "kampita"), - ("muza~", 1, "muzita"), - ("graha~^", 9, "gfhIta"), - // Kale 685 -- seT exceptions - ("YiinDI~\\", 7, "idDa"), - ("fzI~", 6, "fzwa"), - ("citI~", 1, "citta"), - ("juzI~\\", 6, "juzwa"), - ("trasI~", 4, "trasta"), - ("dIpI~\\", 4, "dIpta"), - ("madI~", 4, "matta"), - ("yatI~\\", 1, "yatta"), - // Kale 686 (a) -- veT - ("damu~", 4, "dAnta|damita"), - ("Samu~", 4, "SAnta|Samita"), - ("pura~", 1, "pUrRa|pUrita"), - ("dasu~", 4, "dasta|dAsita"), - ("spaSa~^", 1, "spazwa|spaSita"), - ("Cada", 10, "Canna|CAdita"), - ("jYapa~", 10, "jYapta|jYapita"), - ("ruza~", 1, "ruzwa|ruzita"), - ("ama~", 1, "Anta|amita"), - // TODO: saMGuz, Asvan, hfz - // Kale 686 (b) -- more veT - ("kliSU~", 9, "klizwa|kliSita"), - ("pUN", 1, "pUta|pavita"), - // Kale 701 - ("a\\da~", 1, "jagDa|anna"), - ("UyI~\\", 1, "Uta"), - ("kaza~", 1, "kazwa"), - ("kfSa~", 4, "kfSa"), - ("kzIbf~\\", 4, "kzIba"), - ("knUyI~\\", 1, "knUta"), - ("kzmAyI~\\", 1, "kzmAta"), - ("kzE\\", 1, "kzAma"), - ("gE\\", 1, "gIta"), - ("Co\\", 4, "CAta|Cita"), - // Other - ("Su\\za~", 4, "Suzka"), - ]; - - test_krdanta(&cases, Krt::kta); -} - -#[ignore] -#[test] -fn ktva() { - let cases = vec![ - // Kale 745 - ("jYA\\", 9, "jYAtvA"), - ("qudA\\Y", 3, "dattvA"), - ("zWA\\", 1, "sTitvA"), - ("o~hA\\N", 3, "hAtvA"), - ("o~hA\\k", 3, "hItvA"), - ("quDA\\Y", 3, "hitvA"), - ("ji\\", 1, "jitvA"), - ("pUN", 1, "pUtvA|pavitvA"), - ("BU", 1, "BUtvA"), - ("qukf\\Y", 8, "kftvA"), - ("tF", 1, "tIrtvA"), - ("pF", 9, "pUrtvA"), - ("trE\\N", 1, "trAtvA"), - ("mu\\cx~^", 6, "muktvA"), - ("a\\da~", 2, "jagDvA"), - ("Co\\", 1, "CAtvA|CitvA"), - ("df\\Si~r", 1, "dfzwvA"), - ("kzu\\Da~", 4, "kzuDitvA|kzoDitvA"), - ("va\\sa~", 1, "uzitvA"), - ("va\\ca~", 2, "uktvA"), - ("va\\ha~^", 1, "UQvA"), - ("ya\\ja~^", 1, "izwvA"), - ("quva\\pa~^", 1, "uptvA"), - ("ba\\nDa~", 9, "badDvA"), - ("bu\\Da~\\", 1, "budDvA"), - ("SAsu~", 2, "SizwvA"), - // Kale 746 - ("SIN", 2, "SayitvA"), - ("jAgf", 2, "jAgaritvA"), - // Kale 746 (a) - ("YitfzA~", 4, "tfzitvA|tarzitvA"), - ("mfzu~", 1, "mfzitvA|marzitvA"), - // Kale erroneously has "kfz" here. - ("kfSa~", 4, "kfSitvA|karSitvA"), - // TODO: ft? - // Kale 746 (b) - ("mfqa~", 9, "mfqitvA"), - ("mfda~", 9, "mfditvA"), - ("guDa~", 9, "guDitvA"), - ("kuza~", 9, "kuzitvA"), - ("kliSU~", 9, "kliSitvA|klizwvA"), - ("vada~", 1, "uditvA"), - // Kale 747 - ("mfjU~", 2, "mArjitvA|mfzwvA"), - ("gAhU~\\", 1, "gAhitvA|gAQvA"), - ("guhU~^", 1, "guhitvA|gUhitvA|gUQvA"), - ("gupU~", 1, "gopAyitvA|gopitvA|guptvA|gupitvA"), - ("izu~", 1, "ezitvA|izwvA"), - ("zaha~\\", 1, "sahitvA|soQvA"), - ("luBa~", 4, "loBitvA|lubDvA"), - ("ancu~", 1, "aktvA|aYcitvA"), - // TODO: more - ("Kanu~^", 1, "KanitvA|KAtvA"), - ("tanu~^", 8, "tanitvA|tatvA"), - ("damu~", 4, "damitvA|dAntvA"), - ("Samu~", 4, "SamitvA|SAntvA"), - ("kramu~", 1, "kramitvA|krantvA|krAntvA"), - ("kramu~", 1, "kramitvA|krantvA|krAntvA"), - // Kale 750 - ("liKa~", 1, "liKitvA|leKitvA"), - ("klidU~", 4, "kliditvA|kleditvA|klittvA"), - ("luBa~", 6, "luBitvA|loBitvA"), - ("dyuta~\\", 1, "dyutitvA|dyotitvA"), - ("riza~", 1, "rizitvA|rezitvA"), - ("ruza~", 1, "ruzitvA|rozitvA"), - ("divu~", 4, "devitvA|dyutvA"), - ]; - - test_krdanta(&cases, Krt::ktvA); -} - -#[ignore] -#[test] -fn kvasu() { - let cases = vec![ - // Kale 675 - ("i\\R", 2, "Iyivas"), - ("f\\", 3, "Arivas"), - ("RI\\Y", 1, "ninIvas"), - ("qupa\\ca~^z", 1, "pecivas"), - ("va\\ca~", 2, "Ucivas"), - ("ya\\ja~^", 1, "Ijivas"), - // Kale erroneously has "baBaYjvas." - ("Ba\\njo~", 7, "Bejivas"), - ("zwu\\Y", 2, "tuzwuvas"), - ("qukf\\Y", 8, "cakfvas"), - ("Bi\\di~^r", 2, "biBidvas"), - ("Gasx~", 1, "jakzivas"), - ("df\\Si~r", 1, "dadfSivas|dadfSvas"), - ("vida~", 2, "vividvas|vividivas"), - ("vi\\Sa~", 6, "viviSivas|viviSvas"), - ("janI~\\", 2, "jajanvas"), - ("Kanu~^", 1, "caKanvas"), - ("ga\\mx~", 1, "jagmivas|jaganvas"), - ("ha\\na~", 2, "jaGnivas|jaGanvas"), - // F, tF, jF - ("tF", 1, "titIrvas"), - ]; - - test_krdanta(&cases, Krt::kvasu); -} - -#[ignore] -#[test] -fn kvip() { - let cases = vec![ - ("zUN", 2, "sU"), - ("RI\\Y", 1, "nI"), - ("za\\dx~", 1, "sad"), - ("dvi\\za~^", 2, "dviz"), - ("yu\\ji~^r", 7, "yuj"), - ("rAjf~^", 1, "rAj"), - ("ci\\Y", 5, "cit"), - ]; - - test_krdanta(&cases, Krt::kvip); -} - -#[test] -fn nvul() { - let cases = vec![ - // Basic - ("qukf\\Y", 8, "kAraka"), - ("qupa\\ca~^z", 1, "pAcaka"), - ("ha\\na~", 2, "GAtaka"), - ("qudA\\Y", 3, "dAyaka"), - ("quDA\\Y", 3, "DAyaka"), - ("Samu~", 4, "Samaka"), - ("damu~", 4, "damaka"), - // Kale has "vaDaka" but I don't know what its dhatu is. - ("janI~\\", 4, "janaka"), - ]; - - test_krdanta(&cases, Krt::Rvul); -} - -#[test] -fn tavya() { - let cases = vec![ - // Kale 712 - ("qudA\\Y", 3, "dAtavya"), - ("ci\\Y", 5, "cetavya"), - ("RI\\Y", 1, "netavya"), - ("Sru\\", 1, "Srotavya"), - ("BU", 1, "Bavitavya"), - ("qukf\\Y", 8, "kartavya"), - ("mu\\cx~^", 6, "moktavya"), - // Kale is missing "mArjitavya". - ("mfjU~", 2, "mArzwavya|mArjitavya"), - ("sf\\ja~\\", 6, "srazwavya"), - ("Bra\\sja~^", 6, "Barzwavya|Brazwavya"), - ("Bi\\di~^r", 7, "Bettavya"), - ("Ridi~", 1, "ninditavya"), - ("guhU~^", 1, "goQavya|gUhitavya"), - ]; - - test_krdanta(&cases, Krt::tavya); -} - -#[test] -fn tumun() { - let cases = vec![ - // Kale 776 - ("i\\R", 2, "etum"), - ("eDa~\\", 1, "eDitum"), - ("qudA\\Y", 3, "dAtum"), - ("RI\\Y", 1, "netum"), - ("qukf\\Y", 8, "kartum"), - ("BU", 1, "Bavitum"), - ("DUY", 5, "Davitum|Dotum"), - ("vFY", 9, "varitum|varItum"), - ("gE\\", 1, "gAtum"), - ("ga\\mx~", 1, "gantum"), - ("granTa~", 1, "granTitum"), - ("qupa\\ca~^z", 1, "paktum"), - ("o~vrascU~", 6, "vraScitum|vrazwum"), - ("guhU~^", 1, "gUhitum|goQum"), - ("zaha~\\", 1, "sahitum|soQum"), - ("cura~", 10, "corayitum"), - ]; - - test_krdanta(&cases, Krt::tumun); -} - -#[ignore] -#[test] -fn yat() { - let cases = vec![ - ("BU", 1, "Bavya"), - // Kale 714 - ("qudA\\Y", 3, "deya"), - ("De\\w", 1, "Deya"), - ("gE\\", 1, "geya"), - ("Co\\", 1, "Ceya"), - ("ci\\Y", 5, "ceya"), - ("RI\\Y", 1, "neya"), - ("Sa\\kx~", 5, "Sakya"), - ("zaha~\\", 1, "sahya"), - ]; - - test_krdanta(&cases, Krt::yat); -} - -#[test] -fn lyuw() { - let cases = vec![ - // Basic - ("zaha~\\", 1, "sahana"), - ("hase~", 1, "hasana"), - ("SIN", 2, "Sayana"), - ("o~vrascU~", 6, "vraScana"), - ("du\\ha~^", 2, "dohana"), - ]; - - test_krdanta(&cases, Krt::lyuw); -} - -#[test] -fn shatr() { - let cases = vec![ - // Kale 667 - ("BU", 1, "Bavat"), - ("zWA\\", 1, "tizWat"), - ("dvi\\za~^", 2, "dvizat"), - ("a\\da~", 2, "adat"), - ("yA\\", 2, "yAt"), - ("hu\\", 3, "juhvat"), - ("divu~", 4, "dIvyat"), - ("zu\\Y", 5, "sunvat"), - ("tu\\da~^", 6, "tudat"), - ("ru\\Di~^r", 7, "runDat"), - ("qukf\\Y", 8, "kurvat"), - ("tanu~^", 8, "tanvat"), - ("qukrI\\Y", 9, "krIRat"), - ("muza~", 9, "muzRat"), - ("cura~", 10, "corayat"), - ]; - - test_krdanta(&cases, Krt::Satf); -} - -#[test] -fn shanac() { - // Kale 666 - let cases = vec![ - // Basic cases - ("eDa~\\", 1, "eDamAna"), - ("vadi~\\", 1, "vandamAna"), - ("SIN", 2, "SayAna"), - ("dvi\\za~^", 2, "dvizARa"), - ("quDA\\Y", 3, "daDAna"), - // ("hu\\", 3, "juhvAna"), - // ("divu~", 4, "dIvyamAna"), - ("zu\\Y", 5, "sunvAna"), - ("tu\\da~^", 6, "tudamAna"), - ("ru\\Di~^r", 7, "runDAna"), - ("qukf\\Y", 8, "kurvARa"), - ("tanu~^", 8, "tanvAna"), - ("qukrI\\Y", 9, "krIRAna"), - ("cura~", 10, "corayamARa"), - // Special cases - ("Asa~\\", 2, "AsIna"), - ]; - - test_krdanta(&cases, Krt::SAnac); -} diff --git a/vidyut-prakriya/tests/integration/basic_tinantas.rs b/vidyut-prakriya/tests/integration/basic_tinantas.rs deleted file mode 100644 index caff399..0000000 --- a/vidyut-prakriya/tests/integration/basic_tinantas.rs +++ /dev/null @@ -1,129 +0,0 @@ -use vidyut_prakriya::args::*; -use vidyut_prakriya::Vyakarana; - -fn derive(upadesha: &str, gana: &str, prayoga: Prayoga) -> Vec { - let v = Vyakarana::new(); - let dhatu = Dhatu::builder() - .aupadeshika(upadesha) - .gana(gana.parse().expect("ok")) - .build() - .unwrap(); - - let args = Tinanta::builder() - .dhatu(dhatu) - .prayoga(prayoga) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lat) - .build() - .unwrap(); - - let prakriyas = v.derive_tinantas(&args); - prakriyas.iter().map(|p| p.text()).collect() -} - -fn run_test_cases(cases: &[(&str, u8, &str)], prayoga: Prayoga) { - let mut num_failed = 0; - for (dhatu, gana, expected) in cases { - let mut expected: Vec<_> = expected.split('|').collect(); - expected.sort(); - - let mut actual: Vec<_> = derive(dhatu, &gana.to_string(), prayoga); - actual.sort(); - actual.dedup(); - - if actual != expected { - println!("Dhatu : {dhatu} ({gana})"); - println!("Expected : {expected:?}"); - println!("Actual : {actual:?}"); - println!(); - num_failed += 1; - } - } - if num_failed > 0 { - let num_total = cases.len(); - let num_passed = num_total - num_failed; - println!("{num_passed} / {num_total} tests passed.") - } - assert_eq!(num_failed, 0); -} - -#[test] -fn karmani() { - let cases = &[ - // Kale 594 - ("GrA\\", 1, "GrAyate"), - ("jyA\\", 9, "jIyate"), - ("dA\\R", 1, "dIyate"), - ("qudA\\Y", 3, "dIyate"), - ("dA\\p", 2, "dAyate"), - ("quDA\\Y", 1, "DIyate"), - ("pA\\", 1, "pIyate"), - ("pA\\", 2, "pAyate"), - ("mA\\", 2, "mIyate"), - ("De\\w", 1, "DIyate"), - ("ve\\Y", 1, "Uyate"), - ("vye\\Y", 1, "vIyate"), - ("hve\\Y", 1, "hUyate"), - ("gE\\", 1, "gIyate"), - ("pE\\", 1, "pAyate"), - ("do\\", 4, "dIyate"), - ("zo\\", 4, "sIyate"), - ("o~hA\\k", 3, "hIyate"), - ("o~hA\\N", 3, "hAyate"), - ("ci\\Y", 5, "cIyate"), - ("wuo~Svi", 1, "SUyate"), - // TODO: debug this? - // ("qumi\\Y", 5, "mIyate"), - ("mI\\N", 4, "mIyate"), - ("SIN", 2, "Sayyate"), - ("UrRuY", 2, "UrRUyate"), - ("f\\", 3, "aryate"), - ("qukf\\Y", 8, "kriyate"), - ("jAgf", 2, "jAgaryate"), - ("smf", 1, "smaryate"), - ("vFY", 9, "vUryate"), - ("stf\\Y", 5, "staryate"), - ("kF", 6, "kIryate"), - ("stF\\Y", 9, "stIryate"), - ("de\\N", 1, "dIyate"), - ("tanu~^", 8, "tAyate|tanyate"), - ("pana~\\", 1, "panAyyate|panyate"), - // Kale has "gopyate" here, but I think it occurs only in curAdi. - ("gupU~", 1, "gupyate|gopAyyate"), - ("quva\\pa~^", 1, "upyate"), - ("Yizva\\pa~", 2, "supyate"), - ("kamu~\\", 1, "kamyate|kAmyate"), - ("cura~", 10, "coryate"), - ("divu~", 1, "dIvyate"), - ("vaSa~", 2, "uSyate"), - ("va\\ca~", 1, "ucyate"), - ("o~vrascU~", 6, "vfScyate"), - ("vyaca~", 6, "vicyate"), - ("pra\\Ca~", 6, "pfcCyate"), - ("viCa~", 6, "vicCyate|vicCAyyate"), - ("Bra\\sja~^", 6, "Bfjjyate"), - ("ya\\ja~^", 1, "ijyate"), - ("paRa~\\", 1, "paRAyyate|paRyate"), - // Kale has "ftIyate," likely a typo - ("fti", 1, "ftyate|ftIyyate"), - ("a\\da~", 2, "adyate"), - ("vada~", 1, "udyate"), - ("YiinDI~\\", 7, "iDyate"), - ("vya\\Da~", 4, "viDyate"), - ("ba\\nDa~", 9, "baDyate"), - ("zaRu~^", 8, "sAyate|sanyate"), - ("janI~\\", 4, "jAyate|janyate"), - ("va\\sa~", 1, "uzyate"), - ("vasa~\\", 2, "vasyate"), - ("asa~", 2, "BUyate"), - ("SAsu~", 2, "Sizyate"), - ("sransu~\\", 1, "srasyate"), - ("vadi~\\", 1, "vandyate"), - ("va\\ha~^", 1, "uhyate"), - ("graha~^", 1, "gfhyate"), - // TODO: samuhyate - ]; - - run_test_cases(cases, Prayoga::Karmani); -} diff --git a/vidyut-prakriya/tests/integration/kashika_1_1.rs b/vidyut-prakriya/tests/integration/kashika_1_1.rs index 8381cbd..4ccdc20 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_1.rs @@ -271,7 +271,7 @@ fn sutra_1_1_20() { #[test] fn sutra_1_1_21() { - S.assert_has_krt(&[], &d("qukf\\Y", Tanadi), Krt::tavya, &["karta/vya"]); + S.assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::tavya, &["karta/vya"]); S.assert_has_taddhita("upagu", T::aR, &["Opagava/"]); assert_has_sup_3d("vfkza", Pum, &["vfkzAByAm"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_1_3.rs b/vidyut-prakriya/tests/integration/kashika_1_3.rs index f57f1c7..9dc1027 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_3.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_3.rs @@ -748,7 +748,7 @@ fn sutra_1_3_89_v1() { #[test] fn sutra_1_3_90() { - let kyas = |prati| Dhatu::nama(Pratipadika::basic(prati), None); + let kyas = |prati| Dhatu::nama(phit(prati), None); assert_has_lat(&[], &kyas("lohita"), &["lohitAyati", "lohitAyate"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_1_4.rs b/vidyut-prakriya/tests/integration/kashika_1_4.rs index ad2a455..940217e 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_4.rs @@ -10,7 +10,7 @@ use vidyut_prakriya::args::Sanadi; use vidyut_prakriya::args::Taddhita as T; fn p(text: &str) -> Pratipadika { - Pratipadika::basic(text.to_string()) + phit(text) } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_3_1.rs b/vidyut-prakriya/tests/integration/kashika_3_1.rs index c1d0eff..8f6d21a 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_1.rs @@ -18,7 +18,7 @@ fn sanadi(p: Pratipadika, s: Sanadi) -> Dhatu { } fn p(text: &str) -> Pratipadika { - Pratipadika::basic(text.to_string()) + phit(text) } #[test] @@ -38,7 +38,7 @@ fn sutra_3_1_2() { #[test] fn sutra_3_1_3() { let kf = d("qukf\\Y", Tanadi); - S.assert_has_krt(&[], &kf, Krt::tavyat, &["kartavya^"]); + S.assert_has_krdanta(&[], &kf, Krt::tavyat, &["kartavya^"]); S.assert_has_artha_taddhita("tittiri", TA::TenaProktam, T::CaR, &["tEttirI/ya"]); } @@ -389,18 +389,13 @@ fn sutra_3_1_33() { fn sutra_3_1_34() { // No `\\` to force parasmaipada // -ti forms are not attested but optional by 3.4.97. - assert_has_tip(&[], &d("juzI~", Tudadi), Let, &["jozizat", "jozizati"]); - assert_has_tip(&[], &d("tF", Bhvadi), Let, &["tArizat", "tArizati"]); - assert_has_tip(&[], &d("madi~", Bhvadi), Let, &["mandizat", "mandizati"]); + assert_has_tip(&[], &d("juzI~", Tudadi), Let, &["jozizat"]); + assert_has_tip(&[], &d("tF", Bhvadi), Let, &["tArizat"]); + assert_has_tip(&[], &d("madi~", Bhvadi), Let, &["mandizat"]); // -t forms are not attested but optional by 3.4.97. - assert_has_tip(&[], &d("patx~", Bhvadi), Let, &["patAti", "patAt"]); - assert_has_tip( - &[], - &nic(&d("cyu\\N", Bhvadi)), - Let, - &["cyAvayAti", "cyAvayAt"], - ); + assert_has_tip(&[], &d("patx~", Bhvadi), Let, &["patAti"]); + assert_has_tip(&[], &nic(&d("cyu\\N", Bhvadi)), Let, &["cyAvayAti"]); } #[test] @@ -1096,7 +1091,8 @@ fn sutra_3_1_108() { #[test] fn sutra_3_1_109() { - assert_has_krdanta(&[], &d("i\\R", Adadi), Krt::kyap, &["itya"]); + // ityA is from 3.3.99. + assert_has_krdanta(&[], &d("i\\R", Adadi), Krt::kyap, &["itya", "ityA"]); assert_has_krdanta(&[], &d("zwu\\Y", Adadi), Krt::kyap, &["stutya"]); assert_has_krdanta(&[], &d("SAsu~", Adadi), Krt::kyap, &["Sizya"]); assert_has_krdanta(&[], &d("vfY", Svadi), Krt::kyap, &["vftya"]); @@ -1129,7 +1125,8 @@ fn sutra_3_1_111() { #[test] fn sutra_3_1_112() { let bhf = d("Bf\\Y", Bhvadi); - assert_has_krdanta(&[], &bhf, Krt::kyap, &["Bftya"]); + // BftyA is from 3.3.99. + assert_has_krdanta(&[], &bhf, Krt::kyap, &["Bftya", "BftyA"]); assert_has_krdanta(&[], &bhf, Krt::Ryat, &["BArya"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_3_2.rs b/vidyut-prakriya/tests/integration/kashika_3_2.rs index c4923ad..d709228 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_2.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_2.rs @@ -274,7 +274,7 @@ fn sutra_3_2_21() { assert_has_upapada_krdanta("viBA", &[], &kf, wa, &["viBAkara"]); assert_has_upapada_krdanta("niSA", &[], &kf, wa, &["niSAkara"]); assert_has_upapada_krdanta("praBA", &[], &kf, wa, &["praBAkara"]); - assert_has_upapada_krdanta(Pratipadika::basic("BAs"), &[], &kf, wa, &["BAskara"]); + assert_has_upapada_krdanta(phit("BAs"), &[], &kf, wa, &["BAskara"]); assert_has_upapada_krdanta("kAra", &[], &kf, wa, &["kArakara"]); assert_has_upapada_krdanta("anta", &[], &kf, wa, &["antakara"]); assert_has_upapada_krdanta("ananta", &[], &kf, wa, &["anantakara"]); diff --git a/vidyut-prakriya/tests/integration/kashika_3_3.rs b/vidyut-prakriya/tests/integration/kashika_3_3.rs index 0b40ff1..e85550b 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_3.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_3.rs @@ -711,7 +711,8 @@ fn sutra_3_3_99() { assert_has_krdanta(&[], &d("SIN", Adadi), K::kyap, &["SayyA"]); // Bftya is from 3.1.112. assert_has_krdanta(&[], &d("Bf\\Y", Bhvadi), K::kyap, &["Bftya", "BftyA"]); - assert_has_krdanta(&[], &d("i\\R", Adadi), K::kyap, &["ityA"]); + // itya is from 3.1.109. + assert_has_krdanta(&[], &d("i\\R", Adadi), K::kyap, &["itya", "ityA"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_3_4.rs b/vidyut-prakriya/tests/integration/kashika_3_4.rs index e771c60..c600dea 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_4.rs @@ -7,6 +7,10 @@ use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::*; +fn avyaya(text: &str) -> Pratipadika { + Pratipadika::avyaya(Slp1String::try_from(text).expect("ok")) +} + #[test] fn sutra_3_4_12() { assert_has_krdanta(&["vi"], &d("Ba\\ja~^", Tudadi), Krt::Ramul, &["viBAjam"]); @@ -60,7 +64,6 @@ fn sutra_3_4_69() { #[test] fn sutra_3_4_70() { - let avyaya = |text| Pratipadika::avyaya(text); let kf = &d("qukf\\Y", Tanadi); let bhuj = &d("Bu\\ja~", Rudhadi); let aas = &d("Asa~\\", Tanadi); @@ -252,7 +255,37 @@ fn sutra_3_4_93() { assert_has_mahin(&[], &kf, Lot, &["karavAmahE"]); } -#[ignore] +#[test] +fn sutra_3_4_94() { + // No `\\` to force parasmaipada + // -ti forms are not attested but optional by 3.4.97. + assert_has_tip(&[], &d("juzI~", Tudadi), Let, &["jozizat"]); + assert_has_tip(&[], &d("tF", Bhvadi), Let, &["tArizat"]); + assert_has_tip(&[], &d("madi~", Bhvadi), Let, &["mandizat"]); + + assert_has_tip(&[], &d("patx~", Bhvadi), Let, &["patAti"]); + assert_has_tip(&[], &nic(&d("cyu\\N", Bhvadi)), Let, &["cyAvayAti"]); +} + +#[test] +fn sutra_3_4_95() { + assert_has_aataam(&[], &d("matri~", Curadi), Let, &["mantrayEte"]); + assert_has_aathaam(&[], &d("matri~", Curadi), Let, &["mantrayETe"]); + assert_has_aataam(&[], &d("qukf\\Y", Tanadi), Let, &["karavEte"]); + assert_has_aathaam(&[], &d("qukf\\Y", Tanadi), Let, &["karavETe"]); +} + +#[test] +fn sutra_3_4_97() { + // No `\\` to force parasmaipada + assert_has_tip(&[], &d("juzI~", Tudadi), Let, &["jozizat"]); + assert_has_tip(&[], &d("tF", Bhvadi), Let, &["tArizat"]); + assert_has_tip(&[], &d("madi~", Bhvadi), Let, &["mandizat"]); + + assert_has_tip(&[], &d("patx~", Bhvadi), Let, &["patAti"]); + assert_has_tip(&[], &nic(&d("cyu\\N", Bhvadi)), Let, &["cyAvayAti"]); +} + #[test] fn sutra_3_4_98() { let kf = d("qukf\\Y", Tanadi); diff --git a/vidyut-prakriya/tests/integration/kashika_4_1.rs b/vidyut-prakriya/tests/integration/kashika_4_1.rs index 5dda3b4..51ca426 100644 --- a/vidyut-prakriya/tests/integration/kashika_4_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_4_1.rs @@ -3,7 +3,6 @@ use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::Pratipadika; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; @@ -13,8 +12,8 @@ fn assert_has_pum(prati: &str, expected: &[&str]) { assert_has_sup_1s(prati, Pum, expected); } -fn assert_has_stri(prati: impl Into, expected: &[&str]) { - assert_has_sup_1s(prati.into(), Stri, expected); +fn assert_has_stri(prati: impl Into, expected: &[&str]) { + assert_has_sup_1s(prati.into().0, Stri, expected); } fn assert_blocked(text: &str, artha: TaddhitaArtha, t: T) { @@ -170,7 +169,7 @@ fn sutra_4_1_2() { assert_has_sup_7d(&karishagandhya, Stri, &["kArIzaganDyayoH"]); assert_has_sup_7p(&karishagandhya, Stri, &["kArIzaganDyAsu"]); - let drshad = Pratipadika::basic("dfzad"); + let drshad = phit("dfzad"); assert_has_sup_1s(&drshad, Pum, &["dfzat"]); assert_has_sup_1d(&drshad, Pum, &["dfzadO"]); assert_has_sup_1p(&drshad, Pum, &["dfzadaH"]); diff --git a/vidyut-prakriya/tests/integration/kashika_5_1.rs b/vidyut-prakriya/tests/integration/kashika_5_1.rs index 230ee1e..60d8af9 100644 --- a/vidyut-prakriya/tests/integration/kashika_5_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_5_1.rs @@ -52,11 +52,12 @@ fn sutra_5_1_4() { #[ignore] #[test] fn sutra_5_1_5() { + let havis = krdanta(&[], &d("hu\\", Juhotyadi), Unadi::isi); assert_has_artha_taddhita("vatsa", TasmaiHitam, T::Ca, &["vatsIya"]); assert_has_artha_taddhita("avatsa", TasmaiHitam, T::Ca, &["avatsIya"]); assert_has_artha_taddhita("pawu", TasmaiHitam, T::yat, &["pawavya"]); assert_has_artha_taddhita("go", TasmaiHitam, T::yat, &["gavya"]); - assert_has_artha_taddhita("havis", TasmaiHitam, T::yat, &["havizya"]); + assert_has_artha_taddhita(&havis, TasmaiHitam, T::yat, &["havizya"]); assert_has_artha_taddhita("apUpa", TasmaiHitam, T::yat, &["apUpya"]); assert_has_artha_taddhita("apUpa", TasmaiHitam, T::Ca, &["apUpIya"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_6_1.rs b/vidyut-prakriya/tests/integration/kashika_6_1.rs index 2cedd61..c6b6c12 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_1.rs @@ -1067,7 +1067,6 @@ fn sutra_6_1_125() { // TODO: pluta and others } -#[ignore] #[test] fn sutra_6_1_135() { let kf = d("qukf\\Y", Tanadi); @@ -1135,7 +1134,7 @@ fn sutra_6_1_141() { #[test] fn sutra_6_1_159() { - S.assert_has_krt(&[], &d("kf\\za~", Bhvadi), Krt::GaY, &["karza/"]); + S.assert_has_krdanta(&[], &d("kf\\za~", Bhvadi), Krt::GaY, &["karza/"]); } #[ignore] @@ -1150,9 +1149,9 @@ fn sutra_6_1_162() { #[test] fn sutra_6_1_163() { - S.assert_has_krt(&[], &d("Ba\\njo~", Rudhadi), Krt::Gurac, &["BaNgura/"]); - S.assert_has_krt(&[], &d("BAsf~\\", Bhvadi), Krt::Gurac, &["BAsura/"]); - S.assert_has_krt(&[], &d("YimidA~", Divadi), Krt::Gurac, &["medura/"]); + S.assert_has_krdanta(&[], &d("Ba\\njo~", Rudhadi), Krt::Gurac, &["BaNgura/"]); + S.assert_has_krdanta(&[], &d("BAsf~\\", Bhvadi), Krt::Gurac, &["BAsura/"]); + S.assert_has_krdanta(&[], &d("YimidA~", Divadi), Krt::Gurac, &["medura/"]); // TODO: others } @@ -1228,10 +1227,10 @@ fn sutra_6_1_183() { fn sutra_6_1_185() { let kr = d("qukf\\Y", Tanadi); let hr = d("hf\\Y", Bhvadi); - S.assert_has_krt(&[], &san(&kr), Krt::yat, &["cikIrzya^"]); - S.assert_has_krt(&[], &san(&hr), Krt::yat, &["jihIrzya^"]); - S.assert_has_krt(&[], &kr, Krt::Ryat, &["kArya^"]); - S.assert_has_krt(&[], &hr, Krt::Ryat, &["hArya^"]); + S.assert_has_krdanta(&[], &san(&kr), Krt::yat, &["cikIrzya^"]); + S.assert_has_krdanta(&[], &san(&hr), Krt::yat, &["jihIrzya^"]); + S.assert_has_krdanta(&[], &kr, Krt::Ryat, &["kArya^"]); + S.assert_has_krdanta(&[], &hr, Krt::Ryat, &["hArya^"]); } #[test] @@ -1245,8 +1244,8 @@ fn sutra_6_1_191() { fn sutra_6_1_193() { let kr = d("qukf\\Y", Tanadi); let hr = d("hf\\Y", Bhvadi); - S.assert_has_krt(&[], &san(&kr), Krt::Rvul, &["cikI/rzaka"]); - S.assert_has_krt(&[], &san(&hr), Krt::Rvul, &["jihI/rzaka"]); + S.assert_has_krdanta(&[], &san(&kr), Krt::Rvul, &["cikI/rzaka"]); + S.assert_has_krdanta(&[], &san(&hr), Krt::Rvul, &["jihI/rzaka"]); S.assert_has_taddhita("BOriki", T::viDal, &["BOriki/viDa"]); S.assert_has_taddhita("BOliki", T::viDal, &["BOliki/viDa"]); @@ -1287,8 +1286,8 @@ fn sutra_6_1_212() { fn sutra_6_1_217() { let kr = d("qukf\\Y", Tanadi); let hr = d("hf\\Y", Bhvadi); - S.assert_has_krt(&[], &kr, Krt::anIyar, &["karaRI/ya"]); - S.assert_has_krt(&[], &hr, Krt::anIyar, &["haraRI/ya"]); + S.assert_has_krdanta(&[], &kr, Krt::anIyar, &["karaRI/ya"]); + S.assert_has_krdanta(&[], &hr, Krt::anIyar, &["haraRI/ya"]); S.assert_has_taddhita("pawu", T::jAtIyar, &["pawujAtI/ya"]); S.assert_has_taddhita("mfdu", T::jAtIyar, &["mfdujAtI/ya"]); diff --git a/vidyut-prakriya/tests/integration/kashika_6_4.rs b/vidyut-prakriya/tests/integration/kashika_6_4.rs index 51228cb..0c15aa5 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_4.rs @@ -675,7 +675,6 @@ fn sutra_6_4_49() { assert_has_krdanta(&[], &yan(&d("pUY", Kryadi)), Krt::tfc, &["popUyitf"]); } -#[ignore] #[test] fn sutra_6_4_51() { assert_has_tip(&[], &nic(&d("takza~", Bhvadi)), Lun, &["atatakzat"]); @@ -712,7 +711,6 @@ 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)); @@ -733,6 +731,7 @@ fn sutra_6_4_55() { ); let spfha = &d("spfha", Curadi); let gfha = &d("gfha", Curadi); + // anta assert_has_krdanta(&[], &nic(&d("gaqi~", Bhvadi)), Unadi::Jac, &["gaRqayanta"]); assert_has_krdanta( @@ -741,16 +740,22 @@ fn sutra_6_4_55() { Unadi::Jac, &["maRqayanta"], ); + // Alu assert_has_krdanta(&[], &spfha, Krt::Aluc, &["spfhayAlu"]); assert_has_krdanta(&[], &gfha, Krt::Aluc, &["gfhayAlu"]); + // Ayya assert_has_krdanta(&[], &spfha, Unadi::Ayya, &["spfhayAyya"]); assert_has_krdanta(&[], &gfha, Unadi::Ayya, &["gfhayAyya"]); + // itnu assert_has_krdanta(&[], &d("stana", Curadi), Unadi::itnuc, &["stanayitnu"]); - assert_has_krdanta(&[], &nic(&d("puza~", Kryadi)), Krt::izRuc, &["pozayizRu"]); - assert_has_krdanta(&[], &d("pAra", Curadi), Krt::izRuc, &["pArayizRu"]); + + // izRu + let t = Tester::with_chaandasa(); + t.assert_has_krdanta(&[], &nic(&d("puza~", Kryadi)), Krt::izRuc, &["pozayizRu"]); + t.assert_has_krdanta(&[], &d("pAra", Curadi), Krt::izRuc, &["pArayizRu"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_7_1.rs b/vidyut-prakriya/tests/integration/kashika_7_1.rs index 7f7bb9b..c396737 100644 --- a/vidyut-prakriya/tests/integration/kashika_7_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_7_1.rs @@ -7,6 +7,10 @@ use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::*; +fn avyaya(text: &str) -> Pratipadika { + Pratipadika::avyaya(Slp1String::try_from(text).expect("ok")) +} + #[test] fn sutra_7_1_1() { let nand = d("wunadi~", Bhvadi); @@ -372,13 +376,7 @@ fn sutra_7_1_37() { let hf = d("hf\\Y", Bhvadi); assert_has_krdanta(&["pra"], &kf, ktvA, &["prakftya"]); assert_has_krdanta(&["pra"], &hf, ktvA, &["prahftya"]); - assert_has_upapada_krdanta( - Pratipadika::avyaya("pArSvataH"), - &[], - &kf, - ktvA, - &["pArSvataHkftya"], - ); + assert_has_upapada_krdanta(avyaya("pArSvataH"), &[], &kf, ktvA, &["pArSvataHkftya"]); assert_has_krdanta(&["nAnA"], &kf, ktvA, &["nAnAkftya"]); assert_has_krdanta(&["dviDA"], &kf, ktvA, &["dviDAkftya"]); @@ -596,14 +594,16 @@ fn sutra_7_1_66() { #[test] fn sutra_7_1_67() { - let avyaya = Pratipadika::avyaya; let labh = d("qula\\Ba~\\z", Bhvadi); + // Kal assert_has_upapada_krdanta(avyaya("Izat"), &["pra"], &labh, Krt::Kal, &["IzatpralamBa"]); assert_has_upapada_krdanta(avyaya("su"), &["pra"], &labh, Krt::Kal, &["supralamBa"]); + // GaY assert_has_krdanta(&["pra"], &labh, Krt::GaY, &["pralamBa"]); assert_has_krdanta(&["vi", "pra"], &labh, Krt::GaY, &["vipralamBa"]); + // otherwise, ... assert_has_upapada_krdanta(avyaya("Izat"), &[], &labh, Krt::Kal, &["IzallaBa"]); assert_has_krdanta(&[], &labh, Krt::GaY, &["lABa"]); diff --git a/vidyut-prakriya/tests/integration/kashika_7_4.rs b/vidyut-prakriya/tests/integration/kashika_7_4.rs index 18fb241..48ce6dd 100644 --- a/vidyut-prakriya/tests/integration/kashika_7_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_7_4.rs @@ -150,19 +150,23 @@ fn sutra_7_4_10() { let kzi = d("kzi\\", Tudadi); assert_has_tas(&[], &kzi, Lit, &["cikziyatuH"]); assert_has_jhi(&[], &kzi, Lit, &["cikziyuH"]); + // saMyogAdeH let kf = d("qukf\\Y", Tanadi); assert_has_tas(&[], &kf, Lit, &["cakratuH"]); assert_has_jhi(&[], &kf, Lit, &["cakruH"]); + // vrddhi otherwise assert_has_tip(&[], &svf, Lit, &["sasvAra"]); assert_has_tip(&[], &smf, Lit, &["sasmAra"]); + // liwi assert_has_krdanta(&[], &smf, Krt::kta, &["smfta"]); assert_has_krdanta(&[], &smf, Krt::ktavatu, &["smftavat"]); + // saMskf - assert_has_tas(&["sam"], &kf, Lit, &["saYcaskratuH", "saYcakratuH"]); - assert_has_jhi(&["sam"], &kf, Lit, &["saYcaskruH", "saYcakruH"]); + assert_has_tas(&["sam"], &kf, Lit, &["saYcaskaratuH", "saYcakratuH"]); + assert_has_jhi(&["sam"], &kf, Lit, &["saYcaskaruH", "saYcakruH"]); } #[test] @@ -407,12 +411,11 @@ fn sutra_7_4_31() { #[test] fn sutra_7_4_33() { - let kyac = |prati| sanadi(prati, Sanadi::kyac); - let p = |text: &str| Pratipadika::basic(text.to_string()); - assert_has_tip(&[], &kyac(p("putra")), Lat, &["putrIyati"]); - assert_has_tip(&[], &kyac(p("Gawa")), Lat, &["GawIyati"]); - assert_has_tip(&[], &kyac(p("KawvA")), Lat, &["KawvIyati"]); - assert_has_tip(&[], &kyac(p("mAlA")), Lat, &["mAlIyati"]); + let kyac = |prati| sanadi(phit(prati), Sanadi::kyac); + assert_has_tip(&[], &kyac("putra"), Lat, &["putrIyati"]); + assert_has_tip(&[], &kyac("Gawa"), Lat, &["GawIyati"]); + assert_has_tip(&[], &kyac("KawvA"), Lat, &["KawvIyati"]); + assert_has_tip(&[], &kyac("mAlA"), Lat, &["mAlIyati"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_8_2.rs b/vidyut-prakriya/tests/integration/kashika_8_2.rs index 14a206d..8eaee89 100644 --- a/vidyut-prakriya/tests/integration/kashika_8_2.rs +++ b/vidyut-prakriya/tests/integration/kashika_8_2.rs @@ -5,7 +5,6 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pada; -use vidyut_prakriya::args::Pratipadika; use vidyut_prakriya::args::Subanta; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha; @@ -794,7 +793,7 @@ fn sutra_8_2_66() { // TODO: sandhi applied at pada before moving to vakya, which prevents match. let jush = krdanta(&[], &d("juzI~\\", Tudadi), Krt::kvip); // HACK: technically "saha", but use "sa" for convenience. - let sajush = bahuvrihi(Pratipadika::basic("sa"), jush); + let sajush = bahuvrihi("sa", jush); let sajuh = Subanta::new(&sajush, Stri, Vibhakti::Prathama, Vacana::Eka).into(); assert_has_vakya(&sajuh, &pada("ftuBis"), &["sajUr ftuBiH"]); assert_has_vakya(&sajuh, &pada("deveBiH"), &["sajUr deeBiH"]); diff --git a/vidyut-prakriya/tests/integration/kashika_8_3.rs b/vidyut-prakriya/tests/integration/kashika_8_3.rs index 7ac1873..6720373 100644 --- a/vidyut-prakriya/tests/integration/kashika_8_3.rs +++ b/vidyut-prakriya/tests/integration/kashika_8_3.rs @@ -11,6 +11,13 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; +fn kamyac(prati: &str) -> Dhatu { + Dhatu::nama( + Pratipadika::basic(prati.try_into().expect("ok")), + Some(Sanadi::kAmyac), + ) +} + #[test] fn sutra_8_3_13() { assert_has_krdanta(&[], &d("li\\ha~^", Adadi), Krt::kta, &["lIQa"]); @@ -173,7 +180,6 @@ fn sutra_8_3_38() { assert_has_taddhita("payas", T::ka, &["payaska"]); assert_has_taddhita("yaSas", T::ka, &["yaSaska"]); - let kamyac = |prati| Dhatu::nama(Pratipadika::basic(prati), Some(Sanadi::kAmyac)); assert_has_tip(&[], &kamyac("payas"), Lat, &["payaskAmyati"]); assert_has_tip(&[], &kamyac("yaSas"), Lat, &["yaSaskAmyati"]); @@ -189,7 +195,6 @@ fn sutra_8_3_39() { assert_has_taddhita("sarpis", T::ka, &["sarpizka"]); assert_has_taddhita("yajus", T::ka, &["yajuzka"]); - let kamyac = |prati| Dhatu::nama(Pratipadika::basic(prati), Some(Sanadi::kAmyac)); assert_has_tip(&[], &kamyac("sarpis"), Lat, &["sarpizkAmyati"]); assert_has_tip(&[], &kamyac("yajus"), Lat, &["yajuzkAmyati"]); diff --git a/vidyut-prakriya/tests/integration/kaumudi_08.rs b/vidyut-prakriya/tests/integration/kaumudi_08.rs index 3652a85..03593ce 100644 --- a/vidyut-prakriya/tests/integration/kaumudi_08.rs +++ b/vidyut-prakriya/tests/integration/kaumudi_08.rs @@ -5,11 +5,16 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pratipadika; +use vidyut_prakriya::args::Slp1String; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::Unadi; use vidyut_prakriya::args::Vibhakti; use vidyut_prakriya::args::{Dhatu, Sanadi}; +fn phit(s: &str) -> Pratipadika { + Pratipadika::basic(Slp1String::from(s).expect("ok")) +} + #[test] fn skip_sk_178_to_sk_186() {} @@ -118,7 +123,7 @@ fn sk_212() { assert_has_sup_6s("rAma", Pum, &["rAmasya"]); let pis = create_krdanta("pis", &[], &d("pisf~", Bhvadi), Krt::kvip); - let supis = bahuvrihi(Pratipadika::basic("su"), pis); + let supis = bahuvrihi("su", pis); assert_has_sup_1s(&supis, Pum, &["supIH"]); assert_has_sup_1d(&supis, Pum, &["supisO"]); assert_has_sup_1p(&supis, Pum, &["supisaH"]); @@ -499,7 +504,7 @@ fn skip_sk_271() {} #[ignore] #[test] fn sk_273() { - let sakhiy = Dhatu::nama("saKi".into(), Some(Sanadi::kyac)); + let sakhiy = Dhatu::nama(phit("saKi"), Some(Sanadi::kyac)); let sakhi = krdanta(&[], &sakhiy, Krt::kvip); assert_has_sup_1s(&sakhi, Pum, &["saKA"]); assert_has_sup_1d(&sakhi, Pum, &["saKAyO"]); diff --git a/vidyut-prakriya/tests/integration/kaumudi_11.rs b/vidyut-prakriya/tests/integration/kaumudi_11.rs index b9b6b39..b203271 100644 --- a/vidyut-prakriya/tests/integration/kaumudi_11.rs +++ b/vidyut-prakriya/tests/integration/kaumudi_11.rs @@ -3,7 +3,6 @@ use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::Pratipadika; use vidyut_prakriya::args::{BaseKrt as Krt, Gana}; #[test] @@ -323,7 +322,7 @@ fn sk_377() { #[test] fn sk_378() { let yuj = create_krdanta("yuj", &[], &d("yu\\ji~^r", Rudhadi), Krt::kvin); - let suyuj = bahuvrihi(Pratipadika::basic("su"), yuj); + let suyuj = bahuvrihi("su", yuj); assert_has_sup_1s(&suyuj, Pum, &["suyuk"]); assert_has_sup_1d(&suyuj, Pum, &["suyujO"]); assert_has_sup_1p(&suyuj, Pum, &["suyujaH"]); @@ -538,7 +537,7 @@ fn sk_434() { assert_has_sup_1p(&goraksh, Pum, &["gorakzaH"]); let pis = create_krdanta("pis", &[], &d("pisf~", Bhvadi), Krt::kvip); - let supis = bahuvrihi(Pratipadika::basic("su"), pis); + let supis = bahuvrihi("su", pis); assert_has_sup_1s(&supis, Pum, &["supIH"]); assert_has_sup_1d(&supis, Pum, &["supisO"]); assert_has_sup_1p(&supis, Pum, &["supisaH"]); diff --git a/vidyut-prakriya/tests/integration/kaumudi_12.rs b/vidyut-prakriya/tests/integration/kaumudi_12.rs index 50d841a..d98d965 100644 --- a/vidyut-prakriya/tests/integration/kaumudi_12.rs +++ b/vidyut-prakriya/tests/integration/kaumudi_12.rs @@ -3,7 +3,6 @@ use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::Pratipadika; #[test] fn sk_440() { @@ -120,7 +119,7 @@ fn sk_442() { let jush = create_krdanta("juz", &[], &d("juzI~\\", Tudadi), Krt::kvip); // HACK: technically "saha", but use "sa" for convenience. - let sajush = bahuvrihi(Pratipadika::basic("sa"), jush); + let sajush = bahuvrihi("sa", jush); assert_has_sup_1s(&sajush, Stri, &["sajUH"]); assert_has_sup_1d(&sajush, Stri, &["sajuzO"]); assert_has_sup_1p(&sajush, Stri, &["sajuzaH"]); diff --git a/vidyut-prakriya/tests/integration/kaumudi_52.rs b/vidyut-prakriya/tests/integration/kaumudi_52.rs index 5b6f050..a7b140e 100644 --- a/vidyut-prakriya/tests/integration/kaumudi_52.rs +++ b/vidyut-prakriya/tests/integration/kaumudi_52.rs @@ -666,7 +666,7 @@ fn sk_2573() { let karta = d("karta", Curadi); assert_has_tip(&[], &karta, Lat, &["kartayati", "kartati"]); - let pati = Dhatu::nama("pawu".into(), Some(Sanadi::Ric)); + let pati = Dhatu::nama(phit("pawu"), Some(Sanadi::Ric)); assert_has_tip(&[], &pati, Lat, &["pawayati"]); // TODO: apIpawat, apapawat, ... } diff --git a/vidyut-prakriya/tests/integration/kaumudi_57.rs b/vidyut-prakriya/tests/integration/kaumudi_57.rs index 46d9764..a7cd8ef 100644 --- a/vidyut-prakriya/tests/integration/kaumudi_57.rs +++ b/vidyut-prakriya/tests/integration/kaumudi_57.rs @@ -4,7 +4,7 @@ use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::{Dhatu, Pratipadika, Sanadi}; fn p(text: &str) -> Pratipadika { - Pratipadika::basic(text.to_string()) + phit(text) } fn kyac(pratipadika: Pratipadika) -> Dhatu { diff --git a/vidyut-prakriya/tests/integration/kaumudi_67.rs b/vidyut-prakriya/tests/integration/kaumudi_67.rs index ab54fc9..7542c10 100644 --- a/vidyut-prakriya/tests/integration/kaumudi_67.rs +++ b/vidyut-prakriya/tests/integration/kaumudi_67.rs @@ -22,7 +22,7 @@ fn unadi_1_1() { #[test] fn unadi_1_2() { let t = Tester::with_chaandasa(); - t.assert_has_krt(&[], &d("i\\R", Adadi), uR, &["Ayu"]); + t.assert_has_krdanta(&[], &d("i\\R", Adadi), uR, &["Ayu"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/main.rs b/vidyut-prakriya/tests/integration/main.rs index 065ca2d..2bfcb31 100644 --- a/vidyut-prakriya/tests/integration/main.rs +++ b/vidyut-prakriya/tests/integration/main.rs @@ -1,9 +1,6 @@ mod api; -mod basic_krdantas; -mod basic_tinantas; mod prakriyas; mod regressions; -mod sanadi_tinantas; mod kashika_1_1; mod kashika_1_2; diff --git a/vidyut-prakriya/tests/integration/sanadi_tinantas.rs b/vidyut-prakriya/tests/integration/sanadi_tinantas.rs deleted file mode 100644 index 34a38b5..0000000 --- a/vidyut-prakriya/tests/integration/sanadi_tinantas.rs +++ /dev/null @@ -1,138 +0,0 @@ -/*! -Various test cases for sanAdi-dhatus, particulary the dhatus ending in nic, san, or yan. - -Test cases marked with *Kale* are from M. R. Kale's *A Higher Sanskrit Grammar*. -*/ -use vidyut_prakriya::args::*; -use vidyut_prakriya::Vyakarana; - -fn create_sanadyanta(upadesha: &str, gana: &str, sanadi: Sanadi) -> Vec { - let v = Vyakarana::new(); - let gana = gana.parse().expect("ok"); - let dhatu = Dhatu::builder() - .aupadeshika(upadesha) - .gana(gana) - .sanadi(&[sanadi]) - .build() - .unwrap(); - - let args = Tinanta::builder() - .dhatu(dhatu) - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lat) - .build() - .unwrap(); - - let prakriyas = v.derive_tinantas(&args); - prakriyas.iter().map(|p| p.text()).collect() -} - -fn run_sanadi_test_cases(cases: &[(&str, u8, &str)], sanadi: Sanadi) { - let mut num_failed = 0; - for (dhatu, gana, expected) in cases { - let mut expected: Vec<_> = expected.split('|').collect(); - expected.sort(); - - let mut actual: Vec<_> = create_sanadyanta(dhatu, &gana.to_string(), sanadi); - if sanadi == Sanadi::Ric { - // All Nijantas are ubhayapadI, so to simplify the tests, focus on just parasmaipada. - actual.retain(|x| x.ends_with("ti")); - } - actual.sort(); - actual.dedup(); - - if actual != expected { - println!("Dhatu: {dhatu} ({gana})"); - println!("Expected: {expected:?}"); - println!("Actual : {actual:?}"); - println!(); - num_failed += 1; - } - } - if num_failed > 0 { - let num_total = cases.len(); - let num_passed = num_total - num_failed; - println!("{num_passed} / {num_total} tests passed.") - } - assert_eq!(num_failed, 0); -} - -#[ignore] -#[test] -fn san_tinantas() { - // Kale 613 - let cases = &[ - ("paWa~", 1, "pipaWizati"), - // Kala has only parasmaipada, but the dhatu is Yit so include both. - ("zi\\Y", 1, "sisIzati|sisIzate"), - ("zi\\ca~^", 1, "sisikzati|sisikzate"), - ("zmi\\N", 1, "sismayizate"), - ("zUN", 2, "susUzate"), - ("zWA\\", 1, "tizWAsati|tizWAsate"), - ("Ru", 2, "nunUzati"), - ("BU", 1, "buBUzati"), - // Irregular - ("a\\da~", 2, "jiGatsati"), - ("A\\px~", 5, "Ipsati"), - ("i\\R", 1, "jigamizati"), - // ("BU", 1, "aDijigAMsate"), - // ("BU", 1, "pratIzizati"), - ("izu~", 6, "ezizizati"), - ("Uza", 1, "Uzizati"), - ( - "UrRuY", - 1, - "UrRunUzati|UrRunUzate|UrRunuvizati|UrRunuvizate|UrRunavizati|UrRunavizate", - ), - ("f\\", 3, "aririzati"), - ("fDu~", 4, "Irtsati|ardiDizati"), - ("ga\\mx~", 1, "jigamizati"), - // ("BU", 1, "saMjigAmsate"), - ("gF", 6, "jigarizati|jigalizati"), - // Ubhayayadi per Yit - ("ci\\Y", 5, "cicIzati|cicIzate|cikIzati|cikIzate"), - ("ji\\", 1, "jigIzati"), - ("jYA\\", 9, "jYIpsati"), - // ("BU", 1, "jijJapayizati"), - ("tanu~^", 1, "titaMsati|titAMsati|titanizati"), - ("tfnhU~", 1, "titfkzati|titfMhizati"), - ("danBu~", 1, "Dipsati|DIpsati|didamBizati"), - ("BU", 1, "didaridrAsati|didaridrizati"), - ("qudA\\Y", 3, "ditsati"), - ("deN", 1, "ditsate"), - ("do", 4, "ditsati"), - ("divu~", 4, "dudyUzati|didevizati"), - ("quDA\\Y", 3, "Ditsati"), - ("De\\w", 1, "Ditsati"), - ("Ra\\Sa~", 1, "ninaNkzyati|ninaSizati"), - ("patx~", 1, "pitsati|pipatizati"), - ("pa\\da~\\", 4, "pitsate"), - ("pUN", 1, "pipavizate"), - ( - "Bra\\sja~^", - 6, - // Kale is missing atmanepada - "biBarkzati|biBarkzate|biBrakzati|biBrakzate|biBarjizati|biBarjizate|biBrajjizati|biBrajjizate", - ), - ("wuma\\sjo~", 6, "mimaNkzati|mimajjizati"), - ("mA\\", 2, "mitsati"), - ("qumi\\Y", 1, "mitsati"), - ("mI\\N", 4, "mitsate"), - ("me\\N", 1, "mitsate"), - // Also include mumuksate -- see Kashika on 7.4.57. - ("mu\\cx~^", 6, "mokzate|mumukzati|mumukzate"), - ("mfjU~", 2, "mimfkzati|mimArjizati"), - ("yu", 2, "yuyUzati|yiyavizati"), - ("ra\\Ba~\\", 1, "ripsate"), - ("rA\\Da~", 4, "ritsati|rirAtsati"), - ("qula\\Ba~\\z", 1, "lipsate"), - ("Sa\\kx~", 1, "Sikzati"), - ("vfDu~\\", 1, "vivftsati|vivarDizate"), - ("syandU~\\", 1, "sisyantsati|sisyandizate|sisyantsate"), - ("kfpU~\\", 1, "cikxpsati|cikalpizate|cikxpsate"), - ]; - - run_sanadi_test_cases(cases, Sanadi::san); -}