Skip to main content

sim_lib_lang_prolog/
profile.rs

1use sim_kernel::{Cx, Result, Symbol};
2use sim_lib_standard_core::{
3    LanguageProfile, OrganUse, ProfileRegistry, fidelity_badge, install_language_profile,
4};
5
6use crate::{
7    install_prolog_lib, prolog_conformance_test_symbol, prolog_logic_organ_symbol,
8    prolog_lowering_symbol, prolog_profile_symbol, prolog_reader_symbol,
9    prolog_surface_fidelity_symbol,
10};
11
12/// Describes the Prolog surface profile as standard-distribution data.
13///
14/// The profile uses Lisp-expression input for asserted clauses and goals,
15/// installs the logic eval policy, draws on the logic, sequence, and control
16/// organs, and reports level 1 surface fidelity for the current organ-backed
17/// builtin coverage.
18pub fn prolog_profile() -> LanguageProfile {
19    let profile = prolog_profile_symbol();
20    let test = prolog_conformance_test_symbol();
21    LanguageProfile::new(profile.clone())
22        .with_reader(prolog_reader_symbol())
23        .with_lowering(prolog_lowering_symbol())
24        .with_eval_policy(Symbol::qualified("eval", "logic"))
25        .with_organ(OrganUse::new(prolog_logic_organ_symbol()))
26        .with_organ(OrganUse::new(sim_lib_sequence::sequence_organ_symbol()))
27        .with_organ(OrganUse::new(sim_lib_control::control_organ_symbol()))
28        .with_conformance_test(test.clone())
29        .with_fidelity_badge(fidelity_badge(
30            &profile,
31            prolog_surface_fidelity_symbol(),
32            1,
33            &test,
34        ))
35}
36
37/// Installs the Prolog profile into a [`ProfileRegistry`].
38///
39/// The Prolog lib is loaded first so the profile symbol and callable surface are
40/// available together in the same context.
41pub fn install_prolog_profile(
42    cx: &mut Cx,
43    registry: &mut ProfileRegistry,
44) -> Result<LanguageProfile> {
45    install_prolog_lib(cx)?;
46    install_language_profile(
47        cx,
48        registry,
49        prolog_profile(),
50        &[
51            sim_lib_sequence::publish_sequence_organ_claims_for_lib,
52            sim_lib_control::publish_control_organ_claims_for_lib,
53        ],
54    )
55}
56
57#[cfg(test)]
58mod tests {
59    use sim_kernel::{
60        ClaimPattern, Ref, Symbol, card::card_kind_predicate, standard::standard_profile_kind,
61        testing::bare_cx as cx,
62    };
63
64    use super::*;
65    use crate::prolog_surface_fidelity_symbol;
66
67    #[test]
68    fn prolog_profile_installs_with_level_one_fidelity_claim() {
69        let mut cx = cx();
70        let mut registry = ProfileRegistry::new();
71
72        let profile = install_prolog_profile(&mut cx, &mut registry).unwrap();
73
74        assert_eq!(profile.symbol, prolog_profile_symbol());
75        assert!(
76            profile
77                .organs
78                .iter()
79                .any(|organ| organ.organ == sim_lib_sequence::sequence_organ_symbol())
80        );
81        assert!(cx.registry().lib(&Symbol::new("prolog")).is_some());
82        assert!(registry.profile(&prolog_profile_symbol()).is_some());
83        let profile_kind = cx.query_facts(profile_kind_claim()).unwrap();
84        assert_eq!(profile_kind.len(), 1);
85        let fidelity = cx.query_facts(partial_fidelity_claim()).unwrap();
86        assert_eq!(fidelity.len(), 1);
87    }
88
89    fn profile_kind_claim() -> ClaimPattern {
90        ClaimPattern {
91            subject: Some(Ref::Symbol(prolog_profile_symbol())),
92            predicate: Some(card_kind_predicate()),
93            object: Some(Ref::Symbol(standard_profile_kind())),
94            include_revoked: false,
95        }
96    }
97
98    fn partial_fidelity_claim() -> ClaimPattern {
99        ClaimPattern {
100            subject: Some(Ref::Symbol(prolog_profile_symbol())),
101            predicate: Some(Symbol::qualified("standard", "fidelity-badge")),
102            object: Some(Ref::Symbol(prolog_surface_fidelity_symbol())),
103            include_revoked: false,
104        }
105    }
106}