:- use_module('event_types.pl').
:- use_module('so_automaton.pl').
:- use_module('skip_pattern_syntax.pl').
:- use_module('skip_pattern_compiler.pl').
:- use_module(library(clpfd)).

/*
     Example: Shop RFID system.
*/

:- encoding(utf8).

:- def_event_types([
       put(id, sid, time),
       get(id, sid, time),
       pay(id, cid, time),
       out(id, time),
       temp(id, ts, tm, time),
       agg(sum, count),
       agg2(sum)
    ]).

pattern(1, event(get, X) then unless(
    unless(
        filter(event(out, Y), ref(X, id) #= ref(Y, id)),
        event(put, Z), ref(X, id) #= ref(Z, id)
    ), event(pay, P), ref(P, id) #= ref(X, id)
)).

pattern(2, event(put, X) then (unless(
    filter(
        iter(
            filter(event(temp, Z), ref(X, id) #= ref(Z, id)),
            agg(sum(ref(Z, tm)-ref(Z, ts)), sum(1)), A
        ), 10 * ref(A, count) #< ref(A, sum)
    ), event(temp, Y), ref(X, id) #= ref(Y, id)    
) within 15)
).

pattern(3, filter(event(put, X) then event(get, Y), ref(X, id) #= ref(Y, id))).

pattern(4, (event(put, X) then event(put, Y)) within 15).

pattern(6, iter(event(put, X), agg2(sum(ref(X, id))), A) within 15).

pattern(7, iter(event(out, X), agg2(sum(ref(X, id))), A)).

pattern(8, filter(iter(event(out, X), agg2(sum(ref(X, id))), A), ref(A, sum) #> 10)).

pattern(11, filter(iter(event(out, X), agg2(sum(1)), A), ref(A, sum) #> 2)).

pattern(9, event(put, X) then unless(
    filter(event(get, Y), ref(X, id) #= ref(Y, id)),
    event(out, Z),
    ref(Z, id) #= ref(X, id) 
)).

pattern(10, event(get, X) then unless(
        filter(event(out, Y), ref(X, id) #= ref(Y, id)),
        event(pay, P), ref(P, id) #= ref(X, id)
)).

pattern(12, filter(event(get, X) then event(put, Y), ref(X, id) #= ref(Y, id))).

pattern(15, filter(event(get, X), ref(X, time) #> 10) then event(out, Y)).

pattern(18, event(get, X) or event(put, X)).
pattern(19, event(get, X) then filter(event(put, Y) or event(pay, Y), 
                                      ref(Y, id) #=ref(X, id))).

pattern(20, event(get, X) then filter(
    (event(put, Y) then event(temp, Z)) or event(pay, Y), 
ref(Y, id) #=ref(X, id))).

assert_pattern(N, P) :- pattern(N, P), assert_regular(N, P).

test_pattern(N, M, L, B) :- length(L, M), match_list(N, L, B).

