hacky as fuck truth table <-> sentence-fun logic works
This commit is contained in:
parent
c5f0e1a7dd
commit
7560ee9151
@ -114,3 +114,7 @@ mul([Arg | Rest]) ->
|
||||
end;
|
||||
mul([]) ->
|
||||
{ok, wfc_sentence:one()}.
|
||||
|
||||
|
||||
zero() -> wfc_sentence:zero().
|
||||
one() -> wfc_sentence:one().
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
blocks/1,
|
||||
%% fancier constructors
|
||||
from_list/1, bmt/1,
|
||||
row/1, col/1,
|
||||
%% useful operations
|
||||
transpose/1, from_bitfun/2,
|
||||
to_list/1
|
||||
@ -117,7 +118,7 @@ rth(RowIdx1, {bm, _Shape = {rc, NR, NC}, Bits})
|
||||
RowIdx0 = RowIdx1 - 1,
|
||||
RowLength = NC,
|
||||
SkipToGetToRow = RowIdx0 * RowLength,
|
||||
<<_:SkipToGetToRow, RowBits:RowLength, _/bits>> = Bits,
|
||||
<<_:SkipToGetToRow, RowBits:RowLength/bits, _/bits>> = Bits,
|
||||
{bm, NewShape, RowBits}.
|
||||
|
||||
|
||||
@ -213,7 +214,8 @@ mulfold({rc, R, C}, Shape, AccBits, M1, M2) ->
|
||||
dot({bm, {rc, 1, Same}, Bits1}, {bm, {rc, Same, 1}, Bits2}) ->
|
||||
<<Int1:Same>> = Bits1,
|
||||
<<Int2:Same>> = Bits2,
|
||||
SummandBits = Int1 band Int2,
|
||||
SummandInt = Int1 band Int2,
|
||||
SummandBits = <<SummandInt:Same>>,
|
||||
parity(SummandBits).
|
||||
|
||||
|
||||
@ -322,6 +324,18 @@ bitsy([Bit | Rest], Acc) -> bitsy(Rest, <<Acc/bits, Bit:1>>);
|
||||
bitsy([], Result) -> Result.
|
||||
|
||||
|
||||
-spec row([bit()]) -> bm().
|
||||
|
||||
row(Row) ->
|
||||
from_list([Row]).
|
||||
|
||||
|
||||
-spec col([bit()]) -> bm().
|
||||
|
||||
col(Col) ->
|
||||
transpose(row(Col)).
|
||||
|
||||
|
||||
-spec bmt(Arity :: pos_integer()) -> bm().
|
||||
% @doc Boole-Mobius transform
|
||||
%
|
||||
@ -329,8 +343,8 @@ bitsy([], Result) -> Result.
|
||||
|
||||
bmt(N) when N > 0 ->
|
||||
%% this might be backwards...
|
||||
blocks([[bmt(N-1), bmt(N-1)],
|
||||
[ztn(N-1), bmt(N-1)]]);
|
||||
blocks([[bmt(N-1), ztn(N-1)],
|
||||
[bmt(N-1), bmt(N-1)]]);
|
||||
bmt(0) ->
|
||||
from_list([[1]]).
|
||||
|
||||
|
||||
149
src/wfc_sftt.erl
Normal file
149
src/wfc_sftt.erl
Normal file
@ -0,0 +1,149 @@
|
||||
% @doc
|
||||
% sentence-fun <-> truth table logic
|
||||
-module(wfc_sftt).
|
||||
|
||||
-export_type([
|
||||
sf/0, tt/0
|
||||
]).
|
||||
|
||||
-export([
|
||||
arity/1,
|
||||
tt/1, sf/1,
|
||||
sf_to_tt/1, tt_to_sf/1,
|
||||
eval/2,
|
||||
bfls/1,
|
||||
bfl/2
|
||||
]).
|
||||
|
||||
-type bit() :: 0 | 1.
|
||||
-opaque sf() :: {sf, wfc_bm:bm()}.
|
||||
-opaque tt() :: {tt, wfc_bm:bm()}.
|
||||
|
||||
-spec arity(sf() | tt()) -> pos_integer().
|
||||
|
||||
arity({sf, BM}) -> matrix_arity(BM);
|
||||
arity({tt, BM}) -> matrix_arity(BM).
|
||||
|
||||
matrix_arity(Matrix) ->
|
||||
{rc, Height, _} = wfc_bm:shape(Matrix),
|
||||
log2(Height).
|
||||
|
||||
log2(N) when N > 1 ->
|
||||
1 + log2(N div 2);
|
||||
log2(1) ->
|
||||
0.
|
||||
|
||||
|
||||
-spec sf_to_tt(sf()) -> tt().
|
||||
sf_to_tt({sf, SFBM}) ->
|
||||
{tt, apply_bmt(SFBM)}.
|
||||
|
||||
|
||||
-spec tt_to_sf(tt()) -> sf().
|
||||
tt_to_sf({tt, SFBM}) ->
|
||||
{sf, apply_bmt(SFBM)}.
|
||||
|
||||
|
||||
apply_bmt(Matrix) ->
|
||||
BMT = wfc_bm:bmt(matrix_arity(Matrix)),
|
||||
wfc_bm:mul(BMT, Matrix).
|
||||
|
||||
|
||||
tt(List) ->
|
||||
{tt, wfc_bm:col(List)}.
|
||||
|
||||
sf(List) ->
|
||||
{sf, wfc_bm:col(List)}.
|
||||
|
||||
|
||||
-spec eval(sf() | tt(), [wfc:sentence()]) -> wfc:sentence().
|
||||
|
||||
eval(TT = {tt, _}, Sentences) ->
|
||||
eval(tt_to_sf(TT), Sentences);
|
||||
eval(SF = {sf, SFBM}, Sentences) ->
|
||||
Arity = arity(SF),
|
||||
Arity = length(Sentences),
|
||||
% [0, 0, 0], [1, 0, 0], ...
|
||||
BitFlagLists = bfls(Arity),
|
||||
io:format("bfls: ~p~n", [BitFlagLists]),
|
||||
% an SFBM is a Nx1 matrix where N = two_to_the(Arity)
|
||||
% hacky but works
|
||||
[Row] = wfc_bm:to_list(wfc_bm:transpose(SFBM)),
|
||||
io:format("row: ~p~n", [Row]),
|
||||
% filter by whether or not we're including
|
||||
Included = filter_included(BitFlagLists, Row),
|
||||
io:format("included: ~p~n", [Included]),
|
||||
AlmostSummands = inseminate(Included, Sentences),
|
||||
io:format("Almost: ~p~n", [AlmostSummands]),
|
||||
collapse(AlmostSummands).
|
||||
|
||||
|
||||
filter_included([_ | Rest], [0 | Rest2]) ->
|
||||
filter_included(Rest, Rest2);
|
||||
filter_included([Item | Rest], [1 | Rest2]) ->
|
||||
[Item | filter_included(Rest, Rest2)];
|
||||
filter_included([], []) ->
|
||||
[].
|
||||
|
||||
|
||||
-spec collapse([[wfc:sentence()]]) -> wfc:sentence().
|
||||
|
||||
collapse(AlmostSummands) ->
|
||||
Summands = lists:map(fun(Args) -> {ok,X} = wfc:mul(Args), X end, AlmostSummands),
|
||||
{ok, Y} = wfc:add(Summands),
|
||||
Y.
|
||||
|
||||
|
||||
-spec inseminate(BFLs :: [[bit()]], Sentences :: [wfc:sentence()]) -> [[wfc:sentence()]].
|
||||
|
||||
inseminate(BFLs, Sentences) ->
|
||||
lists:map(fun(BFL) -> inseminate2(BFL, Sentences) end, BFLs).
|
||||
|
||||
|
||||
-spec inseminate2(BFL :: [bit()], Sentences :: [wfc:sentence()]) -> [wfc:sentence()].
|
||||
inseminate2(BFL, Sentences) ->
|
||||
lists:zipwith(fun pair/2, BFL, Sentences).
|
||||
|
||||
pair(0, _) -> wfc_sentence:one();
|
||||
pair(1, S) -> S.
|
||||
|
||||
|
||||
-spec bfls(Arity :: non_neg_integer()) -> [[bit()]].
|
||||
% @doc get all bit-flag lists for 0..(2^Arity - 1)
|
||||
|
||||
bfls(Arity) when Arity >= 0 ->
|
||||
[bfl(Arity, N) || N <- lists:seq(0, two_to_the(Arity) - 1)].
|
||||
|
||||
two_to_the(N) ->
|
||||
1 bsl N.
|
||||
|
||||
|
||||
-spec bfl(Length :: pos_integer(), N :: non_neg_integer()) -> [bit()].
|
||||
% @doc
|
||||
% get the little-endian representation of N as binary, as a
|
||||
% list of bits.
|
||||
|
||||
bfl(Length, N) when Length > 0, N >= 0 ->
|
||||
%% hacky but logically straightforward
|
||||
bfl2(Length, lists:reverse(integer_to_list(N, 2))).
|
||||
|
||||
%% we're chopping digits off the end here
|
||||
bfl2(Length, Bits_Str) when Length =< length(Bits_Str) ->
|
||||
bfl3(take(Length, Bits_Str));
|
||||
bfl2(Length, Bits_Str) when Length > length(Bits_Str) ->
|
||||
% make more zeros than needed because about to circumcise
|
||||
% them.
|
||||
Zeros = [$0 || _ <- lists:seq(1, Length)],
|
||||
bfl2(Length, Bits_Str ++ Zeros).
|
||||
|
||||
|
||||
take(0, _) ->
|
||||
[];
|
||||
take(N, [Item | Rest]) when N >= 1 ->
|
||||
[Item | take(N-1, Rest)].
|
||||
|
||||
bfl3(BitsText) ->
|
||||
lists:map(fun unfuck_char/1, BitsText).
|
||||
|
||||
unfuck_char($0) -> 0;
|
||||
unfuck_char($1) -> 1.
|
||||
@ -24,8 +24,8 @@
|
||||
]).
|
||||
|
||||
-type bit() :: 0 | 1.
|
||||
-type tt1() :: fun(( bit() ) -> bit() ).
|
||||
-type tt2() :: fun(( bit() ) -> bit)( ).
|
||||
-type tt1() :: fun( (bit()) -> bit() ).
|
||||
-type tt2() :: fun( (bit(), bit()) -> bit() ).
|
||||
|
||||
%% convert truth tables to fixed-arity sentence-functions
|
||||
%% easiest approach is to use boole-mobius transform
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user