Scryer Prolog 的全局键值元数据存储
Global key-value metadata storage for Scryer Prolog

原始链接: https://github.com/jjtolton/environment.pl

## Scryer Prolog 环境库摘要 此库为 Scryer Prolog 提供了一个健壮的、全局环境/上下文管理系统,基于关联树(AVL 树)和黑板构建。它允许存储和检索键值对,提供持久性(跨回溯)和可回溯(局部)存储。 主要特性包括:**全局和局部状态管理**、用于条件逻辑的**类型安全的重构谓词**(使用 `if_/3` 避免剪切)、以及**仅初始化一次**以防止意外覆盖。还提供了高效的**键存在性检查**。 该库提供用于设置/获取值的谓词(`env_set_global`, `env_key_val`)、检查标志(`env_check_flag_t`)以及管理环境本身的谓词。它专为声明式编程设计,利用 `library(reif)` 实现对回溯友好的条件语句,并提供 O(log n) 的键查找性能,即使对于大型数据集也是如此。 环境通过 `term_expansion/2` 初始化一次,将一个空的关联树存储在黑板上。它采用 BSD-2-Clause 许可,并与 Scryer Prolog 的标准库兼容。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Scryer Prolog 的全局键值元数据存储 (github.com/jjtolton) 13 分,triska 发表于 1 天前 | 隐藏 | 过去 | 收藏 | 1 条评论 shawa_a_a 1 天前 [–] 我很久没写 Prolog 了,所以不确定这些想法是否相关(全局状态可能就足够了!);但从 readme 的第一印象来看,这让我想起了 ETS https://www.erlang.org/doc/apps/stdlib/ets.html 本质上是在命名表下进行系统全局状态管理。 你有没有考虑过命名 `env` 实例?这将允许,例如,将功能标志保存在名为 `features` 的关系集合中。 你也可以借鉴 Erlang 的“匹配规范”并使用谓词查询键。 回复 考虑申请 YC 2026 冬季批次!申请截止日期为 11 月 10 日 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系方式 搜索:
相关文章

原文

A global environment/context management system for Scryer Prolog providing key-value metadata storage one level of abstraction above the blackboard.

This library provides a clean interface for managing global state in Prolog programs using association trees (AVL trees) backed by the blackboard. It offers:

  • Global persistent storage - Changes persist across backtracking
  • Backtrackable local storage - Changes roll back on backtracking
  • Type-safe reified predicates - Use if_/3 for conditional logic without cuts
  • Once-only initialization - Prevent accidental double initialization
  • Key existence checking - Efficiently check for key presence
bakage.pl install environment

Copy environment.pl to your project's library directory or ensure it's in your Scryer Prolog load path.

  • library(reif) - Reified predicates for conditional logic
  • library(assoc) - Association trees (AVL trees)
  • library(iso_ext) - ISO extensions including blackboard predicates
?- use_module(library(environment)).

% Set global values (persistent across backtracking)
?- env_set_global(username, 'Alice').
true.

?- env_set_global(counter, 42).
true.

% Retrieve values
?- env_key_val(username, User).
User = 'Alice'.

% Check if key exists (reified)
?- env_check_flag_t(username, T).
T = true.

% Set local value (backtrackable)
?- env_set_local(temp, 'temporary'), env_key_val(temp, V).
V = 'temporary'.

% Initialize once (prevents double initialization)
?- env_set_global_once(config_loaded, true).
true.

?- env_set_global_once(config_loaded, false).
ERROR: runtime_error(env_set_global_once)

environment(-Environment)

Retrieve the current global environment as an association tree.

Replace the entire global environment (persistent).

Replace the entire global environment (backtrackable).

env_set_global(+Key, +Value)

Set a key-value pair globally (persistent across backtracking).

env_set_global_flag(+Key)

Set a flag (key with value true) globally.

env_set_global_once(+Key, +Value)

Set a key-value pair only if it doesn't exist. If it exists with a different value, throws an error.

env_set_global_flag_once(+Key)

Set a flag only once. Throws error if already set with different value.

env_set_local(+Key, +Value)

Set a key-value pair locally (backtrackable).

Set a flag locally (backtrackable).

env_key_val(+Key, ?Value)

Retrieve value for a key. Throws key_error if key doesn't exist.

?- env_set_global(name, 'Bob'), env_key_val(name, N).
N = 'Bob'.

env_key_val_notfound(+Key, ?Value, +NotFound)

Retrieve value for a key, or unify with NotFound if key doesn't exist.

?- env_key_val_notfound(missing_key, V, default).
V = default.

Check if a flag exists (deterministic success/failure).

env_check_flag_t(+Key, ?Truth)

Reified version: unifies Truth with true or false.

?- env_set_global_flag(debug),
   env_check_flag_t(debug, T1),
   env_check_flag_t(missing, T2).
T1 = true,
T2 = false.

env_check_key_val(+Key, +Value)

Check if key exists with specific value (deterministic).

env_check_key_val_t(+Key, +Value, ?Truth)

Reified version of key-value check.

env_check_key_value_t(+Key, +Value, ?Truth)

Alias for env_check_key_val_t/3.

Assert that a flag exists (throws error if missing).

Remove a key from the environment (persistent).

Remove a key from the environment (backtrackable).

% Initialize configuration once
init_config :-
    env_set_global_once(db_host, 'localhost'),
    env_set_global_once(db_port, 5432),
    env_set_global_flag_once(config_loaded).

% Access configuration
get_db_connection(Host, Port) :-
    env_key_val(db_host, Host),
    env_key_val(db_port, Port).
% Enable/disable features
enable_feature(Feature) :-
    env_set_global_flag(Feature).

disable_feature(Feature) :-
    env_remove(Feature).

% Check if feature is enabled
feature_enabled(Feature) :-
    env_check_flag(Feature).

% Conditional execution
maybe_log(Message) :-
    env_check_flag_t(logging_enabled, T),
    if_(T=true,
        format('LOG: ~w~n', [Message]),
        true
       ).
% Use local state that backtracks
process_with_context(Data, Result) :-
    env_set_local(current_data, Data),
    process_step_1,
    process_step_2,
    env_key_val(result, Result).
% Increment counter
increment_counter(Name) :-
    env_key_val_notfound(Name, Current, 0),
    Next is Current + 1,
    env_set_global(Name, Next).

% Usage
?- increment_counter(requests), increment_counter(requests).
true.

?- env_key_val(requests, Count).
Count = 2.

The environment is initialized exactly once using term_expansion/2. The first time the module is loaded, it creates an empty association tree and stores it in the blackboard under global_context.

This library extensively uses reified predicates from library(reif) for conditional logic without cuts. This enables pure, declarative programming with backtracking-friendly conditionals.

  • All operations are O(log n) due to the underlying AVL tree implementation
  • Key lookups are efficient even with thousands of entries
  • Reified key existence checking avoids expensive exception handling

BSD-2-Clause (compatible with Scryer Prolog standard libraries)

Jay

0.1.0

联系我们 contact @ memedata.com