|
- :- use_module(library(apply)).
- :- use_module(library(lists)).
- % :- use_module(library(tabling)).
- % :- table valid_rules/2, op_rule/2.
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %% DCG parser for equations
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %% symbols to be mapped
- digit(1).
- digit(0).
-
- % digits
- digits([D]) --> [D], { digit(D) }. % empty list [] is not a digit
- digits([D | T]) --> [D], !, digits(T), { digit(D) }.
- digits(X):-
- phrase(digits(X), X).
- % More integrity constraints 1:
- % This two clauses forbid the first digit to be 0.
- % You may uncomment them to prune the search space
- % length(X, L),
- % (L > 1 -> X \= [0 | _]; true).
-
- % Equation definition
- eq_arg([D]) --> [D], { \+ D == '+', \+ D == '=' }.
- eq_arg([D | T]) --> [D], !, eq_arg(T), { \+ D == '+', \+ D == '=' }.
- equation(eq(X, Y, Z)) -->
- eq_arg(X), [+], eq_arg(Y), [=], eq_arg(Z).
- % More integrity constraints 2:
- % This clause restricts the length of arguments to be sane,
- % You may uncomment them to prune the search space
- % { length(X, LX), length(Y, LY), length(Z, LZ),
- % LZ =< max(LX, LY) + 1, LZ >= max(LX, LY) }.
- parse_eq(List_of_Terms, Eq) :-
- phrase(equation(Eq), List_of_Terms).
-
- %%%%%%%%%%%%%%%%%%%%%%
- %% Bit-wise operation
- %%%%%%%%%%%%%%%%%%%%%%
- % Abductive calculation with given pseudo-labels, abduces pseudo-labels as well as operation rules
- calc(Rules, Pseudo) :-
- calc([], Rules, Pseudo).
- calc(Rules0, Rules1, Pseudo) :-
- parse_eq(Pseudo, eq(X,Y,Z)),
- bitwise_calc(Rules0, Rules1, X, Y, Z).
-
- % Bit-wise calculation that handles carrying
- bitwise_calc(Rules, Rules1, X, Y, Z) :-
- reverse(X, X1), reverse(Y, Y1), reverse(Z, Z1),
- bitwise_calc_r(Rules, Rules1, X1, Y1, Z1),
- maplist(digits, [X,Y,Z]).
- bitwise_calc_r(Rs, Rs, [], Y, Y).
- bitwise_calc_r(Rs, Rs, X, [], X).
- bitwise_calc_r(Rules, Rules1, [D1 | X], [D2 | Y], [D3 | Z]) :-
- abduce_op_rule(my_op([D1],[D2],Sum), Rules, Rules2),
- ((Sum = [D3], Carry = []); (Sum = [C, D3], Carry = [C])),
- bitwise_calc_r(Rules2, Rules3, X, Carry, X_carried),
- bitwise_calc_r(Rules3, Rules1, X_carried, Y, Z).
-
- %%%%%%%%%%%%%%%%%%%%%%%%%
- % Abduce operation rules
- %%%%%%%%%%%%%%%%%%%%%%%%%
- % Get an existed rule
- abduce_op_rule(R, Rules, Rules) :-
- member(R, Rules).
- % Add a new rule
- abduce_op_rule(R, Rules, [R|Rules]) :-
- op_rule(R),
- valid_rules(Rules, R).
-
- % Integrity Constraints
- valid_rules([], _).
- valid_rules([my_op([X1],[Y1],_)|Rs], my_op([X],[Y],Z)) :-
- op_rule(my_op([X],[Y],Z)),
- [X,Y] \= [X1,Y1],
- [X,Y] \= [Y1,X1],
- valid_rules(Rs, my_op([X],[Y],Z)).
- valid_rules([my_op([Y],[X],Z)|Rs], my_op([X],[Y],Z)) :-
- X \= Y,
- valid_rules(Rs, my_op([X],[Y],Z)).
-
- op_rule(my_op([X],[Y],[Z])) :- digit(X), digit(Y), digit(Z).
- op_rule(my_op([X],[Y],[Z1,Z2])) :- digit(X), digit(Y), digits([Z1,Z2]).
|