This commit is contained in:
Peter Harpending
2025-09-29 13:34:08 -07:00
parent 91f0064a5b
commit 5135a55081
6 changed files with 268 additions and 13 deletions
+75
View File
@@ -0,0 +1,75 @@
% @doc a sentence is an ordset of words
%
% in "A + B + AB", this is the full expression
%
% summation is implied in a sentence
%
% empty sentence is 0
-module(wfc_sentence).
-export_type([
sentence/0
]).
-export([
%% constructors
zero/0,
validate/1,
from_list/1, to_list/1,
%% ops
add/2, add/1
]).
-opaque sentence() :: {s, ordsets:ordset(wfc_word:word())}.
%%--------------------------
%% constructors
%%--------------------------
-spec zero() :: sentence().
zero() ->
{s, []}.
-spec from_list(Words) -> Result
when Words :: [wfc_word:word()],
Result :: {ok, sentence()}
| {error, string()}.
from_list(Words) ->
from_list(ordsets:from_list(Words), []).
%% validate each word
from_list([W | Rest], Acc) ->
case wfc_word:validate(W) of
ok -> from_list(Rest, [W | Acc]);
Error -> Error
end;
% done, all good
from_list([], Acc) ->
{ok, {s, lists:reverse(Acc)}}.
-spec to_list(sentence()) -> Result
when Result :: {ok, [wfc_word:word()]}
| {error, string()}.
to_list({s, Words}) -> {ok, Words};
to_list(Bad) -> {error, wfc_utils:str("wfc_sentence:to_list: bad sentence: ~tp", [Bad])}.
%%---------------------------
%% prim ops
%%---------------------------
add({s, X}, {s, Y}) -> {s, disjoint_union(X, Y)}.
disjoint_union(X, Y) ->
ordsets:subtract(ordsets:union(X, Y),
ordsets:intersection(X, Y)).
add([S | Rest]) -> add(S, add(Rest));
add([]) -> zero().