% WAMVM VM-required term ops + control constructs smoke tests.
%
% Run with:
%   FLOWLOG_WAMVM_REQUIRE_VM=1 ./flowlog --engine wamvm -f tests/wamvm_term_ops_vm.pl -g ok.

p(1).
p(2).

q(1).
q(2).

add1(X, Y) :-
  Y is X + 1.

ok :-
  % once/1 commits to the first solution.
  findall(X, once(p(X)), XsOnce),
  XsOnce = [1],

  % if-then commits to the first success of If.
  ( q(X) -> true ),
  X = 1,

  % if-then-else: Else is not considered once If succeeds.
  ( q(Y) -> true ; Y = 99 ),
  Y = 1,

  % Else branch runs when If fails.
  ( fail -> Z = then ; Z = else ),
  Z = else,

  % If succeeds but Then fails: do NOT run Else.
  ( (true -> fail ; true) -> fail ; true ),

  % call/N (closure expansion).
  call(add1, 1, R),
  R = 2,

  % Module qualification is accepted (Flowlog ignores modules).
  :(m, true),

  % =../2 (univ) round-trips.
  foo(a, b) =.. L1,
  L1 = [foo, a, b],
  T2 =.. [foo, a, b],
  T2 = foo(a, b),

  % functor/3 deconstruct + construct.
  functor(foo(a, b), F, N),
  F = foo,
  N = 2,
  functor(T3, foo, 2),
  T3 = foo(_, _),

  % arg/3.
  arg(2, foo(a, b, c), A2),
  A2 = b,

  % compare/3.
  compare(C1, 1, 2),
  C1 = '<',
  compare('>', 2, 1),
  compare('=', 1, 1),

  % term_variables/2.
  term_variables(f(Xv, Yv, Xv, 1), Vars),
  Vars = [Xv, Yv],

  % copy_term/2 makes fresh variables.
  copy_term(f(Xc), f(Yc)),
  Xc = 1,
  var(Yc),
  Yc = 2,

  % unify_with_occurs_check/2.
  ( unify_with_occurs_check(U, f(U)) -> fail ; var(U) ),

  % acyclic_term/1 detects cycles (rational trees).
  V = f(V),
  \+ acyclic_term(V),

  % ground/1.
  ground(f(1, 2)),
  \+ ground(f(G)),
  var(G).
