Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2022
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 3.36 KB | None | 0 0
  1. digit(X) :-  member(X, "0123456789").
  2.  
  3. num(Num, [Digit|L], Res, M) :-
  4.     digit(Digit), !,
  5.     num(Num*10+Digit-48, L, Res, M).
  6. num(Num, L, Res, L) :- Res is Num.
  7.  
  8. tokenize(0'+,+). tokenize(0'-,-). tokenize(0'*,*). tokenize(0'/,/).
  9. tokenize(0'(,'('). tokenize(0'),')').
  10.  
  11. tokenize([],[]).
  12. tokenize([Ascii|L], [Symbol|M]) :-
  13.     tokenize(Ascii, Symbol),
  14.     tokenize(L, M).
  15. tokenize([Digit|L], [Num|M]) :-
  16.     digit(Digit),
  17.     num(Digit-48, L, Num, R),
  18.     tokenize(R, M).
  19.  
  20. %main :- tokenize("(1-2)*345+0",X), write(X),nl,fail.
  21.  
  22. % symbol kind
  23. operator(+). operator(-). operator(*). operator(/).
  24. bra('('). ket(')').
  25.  
  26. % cakculate a simple opeation
  27. calc(X,+,Y,Z) :- Z is X+Y.
  28. calc(X,-,Y,Z) :- Z is X-Y.
  29. calc(X,*,Y,Z) :- Z is X*Y.
  30. calc(_,/,0,_) :- !, fail. % can’t divide by 0
  31. calc(X,/,Y,Z) :- 0 is mod(X,Y), Z is div(X,Y). % exact division
  32.  
  33. % operator precedence
  34. precedence(+,1). precedence(-,1). precedence(*,2). precedence(/,2).
  35.  
  36. % Shunting-yard algorithm
  37. eval_op(X, L, [A,B|Nums], [Y|Ops], Res) :-
  38.     precedence(X, Px),
  39.     precedence(Y, Py),
  40.     Px =< Py, !,
  41.     calc(B, Y, A, C),
  42.     eval(L, [C|Nums], [X|Ops], Res).
  43. eval_op(X, L, Nums, Ops, Res) :-
  44.     eval(L, Nums, [X|Ops], Res).
  45.  
  46. eval_ket(L, Nums, [X|Ops], Res) :-
  47.     bra(X), !,
  48.     eval(L, Nums, Ops, Res).
  49. eval_ket(L, [X,Y|Nums], [Op|Ops], Res) :-
  50.     calc(Y, Op, X, Z),
  51.     eval_ket(L, [Z|Nums], Ops, Res).
  52.  
  53. eval([Tk|L], Nums, Ops, Res) :-
  54.     (   number(Tk) ->
  55.         eval(L, [Tk|Nums], Ops, Res)
  56.     ;   operator(Tk) ->
  57.         eval_op(Tk, L, Nums, Ops, Res)
  58.     ;   bra(Tk) ->
  59.         eval(L, Nums, [Tk|Ops], Res)
  60.     ;   ket(Tk) ->
  61.         eval_ket(L, Nums, Ops, Res)
  62.     ).
  63. eval([], [X,Y|Nums], [Op|Ops], Res) :-
  64.     calc(Y, Op, X, Z),
  65.     eval([], [Z|Nums], Ops, Res).
  66. eval([],[N],[],N).
  67.  
  68. % eval(-String, +Value)
  69. eval(Str, Val) :-
  70.     tokenize(Str, TokenList),
  71.     eval(TokenList, [], [], Val).
  72.  
  73. % print a string
  74. puts([X|L]) :- put_code(X),puts(L).
  75. puts([]).
  76.  
  77. %main :- member(L,["1+2*3","(1+2)","1","1+2","1+2-3","(1+2)*3","1+(2*3)"]),puts(L),nl,eval(L,R),write(=),write(R),nl,fail.
  78.  
  79. % possible next character
  80. after(X, Y) :-
  81.     (   member(X, "0123456789") ->
  82.         member(Y, "0123456789+-*/)")
  83.     ;   member(X, "+-*/(") ->
  84.         member(Y, "123456789(")
  85.     ;   member(X, ")") ->
  86.         member(Y, "+-*/)")
  87.     ).
  88.  
  89. choose([Constr], Prev, Avoid, [Ascii]) :-
  90.     member(Ascii, Constr),
  91.     member(Ascii, "0123456789)"),
  92.     \+(member(Ascii,Avoid)),
  93.     after(Prev, Ascii).
  94. choose([Constr|L], Prev, Avoid, [Ascii|M]) :-
  95.     member(Ascii, Constr),
  96.     after(Prev, Ascii),
  97.     \+(member(Ascii,Avoid)),
  98.     choose(L, Ascii, [Ascii|Avoid], M).
  99.  
  100. xchoose([Constr], Prev, Avoid, [Ascii]) :-
  101.     member(Ascii, Constr),
  102.     member(Ascii, "0123456789)"),
  103.     member(Ascii,Avoid),
  104.     after(Prev, Ascii).
  105. xchoose([Constr|L], Prev, Avoid, [Ascii|M]) :-
  106.     member(Ascii, Constr),
  107.     after(Prev, Ascii),
  108.     member(Ascii, Avoid),
  109.     choose(L, Ascii, Avoid, M).
  110.  
  111. choose(Constrs, String) :-
  112.     choose(Constrs, 40, [], String).
  113.  
  114. find(Constrs, Target, String) :- choose(Constrs, String), eval(String,Target).
  115.  
  116. %main :- T="0123456789+-*/()", find([T,T,T,T],12,Str), puts(Str), nl, fail.
  117.  
  118.  
  119. main :- find([
  120. "0124689+-*/()",
  121. "012689+-*/()",
  122. "0124689+-/()",
  123. "0124689+-*/()",
  124. "0124689+-*()",
  125. "0124689+-*/()",
  126. "+",
  127. "012489+-*/()"
  128. ],132,Str), puts(Str), nl, fail.
  129.  
  130.  
  131.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement