:- use_module(library(lists)).

atom_prefix(Atom, Prefix, N):-
  atom_codes(Atom, AtomL),
  length(PrefixL, N),
  append(PrefixL, _, AtomL),
  atom_codes(Prefix, PrefixL).

sum_nums(C, Sum):-
  sum_nums(C, 0, Sum).

sum_nums(C, Sum0, Sum):-
  ( number(C) -> Sum is Sum0 + C
  ; compound(C) ->
    C =.. [_|Args],
    sum_list(Args, Sum0, Sum)
  ; Sum = Sum0
  ).

sum_list([], Sum, Sum).
sum_list([H|Tl], Sum0, Sum):-
  sum_nums(H, Sum0, Sum1),
  sum_list(Tl, Sum1, Sum).

substitution(C, SL, V):-
  ( number(C) -> V = C
  ; atom(C) ->
    ( memberchk(C-V1, SL) -> V=V1
    ; V=0
    )
  ).

evaluation(Expr, SL, V):-
  ( atomic(Expr) -> substitution(Expr, SL, V)
  ; Expr =.. [Op,E1] ->
    evaluation(E1, SL, V1),
    OpE1 =.. [Op,V1],
    V is OpE1
  ; Expr =.. [Op,E1,E2] ->
    evaluation(E1, SL, V1),
    evaluation(E2, SL, V2),
    OpE1E2 =.. [Op,V1,V2],
    V is OpE1E2
  ).
