Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
99
Task/Truth-table/Prolog/truth-table.pro
Normal file
99
Task/Truth-table/Prolog/truth-table.pro
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
To evaluate the truth table a line of text is inputted and then there are three steps
|
||||
Let's say the expression is:
|
||||
'not a and (b or c)'
|
||||
|
||||
Step 1: tokenize into atoms and brackets
|
||||
eg: Tokenized = [ not, a, and, '(', b, or, c, ')' ].
|
||||
|
||||
Step 2: convert to a term that can be evaluated, and get out the variables
|
||||
eg: Expression = op(and, op(not, a), op(or, b, c)), Variables = [ a, b, c ]
|
||||
|
||||
Step 3: permeate over the variables, substituting the values for each var, and evaluate the expression for each permutation
|
||||
eg: [ 0, 0, 0]
|
||||
op(and, op(not, 0), op(or, 0, 0))
|
||||
op(and, 1, op(or, 0, 0))
|
||||
op(and, 1, 0)
|
||||
0
|
||||
|
||||
[ 0, 0, 1]
|
||||
op(and, op(not, 0), op(or, 0, 1))
|
||||
op(and, 1, op(or, 0, 0))
|
||||
op(and, 1, 1)
|
||||
1
|
||||
*/
|
||||
truth_table :-
|
||||
current_input(In),
|
||||
read_line_to_codes(In, Line),
|
||||
atom_codes(A, Line),
|
||||
atom_chars(A, Chars),
|
||||
|
||||
% parse everything into the form we want
|
||||
phrase(tok(Tok), Chars, _),
|
||||
phrase(expr(Expr,Vars), Tok, _),
|
||||
list_to_set(Vars,VarSet),
|
||||
|
||||
% evaluate
|
||||
print_expr(Expr, VarSet), !.
|
||||
|
||||
print_expr(Expr, Vars) :-
|
||||
% write the header (once)
|
||||
maplist(format('~p '), Vars),
|
||||
format('~n'),
|
||||
|
||||
% write the results for as many times as there are rows
|
||||
eval_expr(Expr, Vars, Tvals, R),
|
||||
maplist(format('~p '), Tvals),
|
||||
format('~p~n', R),
|
||||
fail.
|
||||
print_expr(_, _).
|
||||
|
||||
|
||||
% Step 1 - tokenize the input into spaces, brackets and atoms
|
||||
tok([A|As]) --> spaces(_), chars([X|Xs]), {atom_codes(A, [X|Xs])}, spaces(_), tok(As).
|
||||
tok([A|As]) --> spaces(_), bracket(A), spaces(_), tok(As).
|
||||
tok([]) --> [].
|
||||
chars([X|Xs]) --> char(X), { dif(X, ')'), dif(X, '(') }, !, chars(Xs).
|
||||
chars([]) --> [].
|
||||
spaces([X|Xs]) --> space(X), !, spaces(Xs).
|
||||
spaces([]) --> [].
|
||||
bracket('(') --> ['('].
|
||||
bracket(')') --> [')'].
|
||||
|
||||
|
||||
% Step 2 - Parse the expression into an evaluable term
|
||||
expr(op(I, E, E2), V) --> starter(E, V1), infix(I), expr(E2, V2), { append(V1, V2, V) }.
|
||||
expr(E, V) --> starter(E, V).
|
||||
|
||||
starter(op(not, E),V) --> [not], expr(E, V).
|
||||
starter(E,V) --> ['('], expr(E,V), [')'].
|
||||
starter(V,[V]) --> variable(V).
|
||||
|
||||
infix(or) --> [or].
|
||||
infix(and) --> [and].
|
||||
infix(xor) --> [xor].
|
||||
infix(nand) --> [nand].
|
||||
|
||||
variable(V) --> [V], \+ infix(V), \+ bracket(V).
|
||||
space(' ') --> [' '].
|
||||
char(X) --> [X], { dif(X, ' ') }.
|
||||
|
||||
|
||||
% Step 3 - evaluate the parsed expression
|
||||
eval_expr(Expr, Vars, Tvals, R) :-
|
||||
length(Vars,Len),
|
||||
length(Tvals, Len),
|
||||
maplist(truth_val, Tvals),
|
||||
eval(Expr, [Tvals,Vars],R).
|
||||
|
||||
eval(X, [Vals,Vars], R) :- nth1(N,Vars,X), nth1(N,Vals,R).
|
||||
eval(op(Op,A,B), V, R) :- eval(A,V,Ae), eval(B,V,Be), e(Op,Ae,Be,R).
|
||||
eval(op(not,A), V, R) :- eval(A,V,Ae), e(not,Ae,R).
|
||||
|
||||
truth_val(0). truth_val(1).
|
||||
|
||||
e(or,0,0,0). e(or,0,1,1). e(or,1,0,1). e(or,1,1,1).
|
||||
e(and,0,0,0). e(and,0,1,0). e(and,1,0,0). e(and,1,1,1).
|
||||
e(xor,0,0,0). e(xor,0,1,1). e(xor,1,0,1). e(xor,1,1,0).
|
||||
e(nand,0,0,1). e(nand,0,1,1). e(nand,1,0,1). e(nand,1,1,0).
|
||||
e(not, 1, 0). e(not, 0, 1).
|
||||
Loading…
Add table
Add a link
Reference in a new issue