#include "core/control-context-v3.lp".
function(a1;b1;a2;b2;a3;b3; sink; fnOut).
scope(0..7).

    %CFA
cfa_parent(0, function(a1)).
cfa_parent(1, function(b1)).
cfa_parent(2, function(a2)).
cfa_parent(3, function(b2)).
cfa_parent(4, function(a3)).
cfa_parent(5, function(b3)).

cfa_parent(6, function(sink)).
cfa_parent(7, function(fnOut)).

cfa_function_specializations(fnOut, keys(keyA1A2A3)).
cfa_function_specializations(fnOut, keys(keyA1A2B3)).
cfa_function_specializations(fnOut, keys(keyA1B2A3)).
cfa_function_specializations(fnOut, keys(keyA1B2B3)).
cfa_function_specializations(fnOut, keys(keyB1A2A3)).
cfa_function_specializations(fnOut, keys(keyB1A2B3)).
cfa_function_specializations(fnOut, keys(keyB1B2A3)).
cfa_function_specializations(fnOut, keys(keyB1B2B3)).


cfa_call(0, a2).
cfa_call(0, b2).
cfa_call(1, a2).
cfa_call(1, b2).
cfa_call(2, a3).
cfa_call(2, b3).
cfa_call(3, a3).
cfa_call(3, b3).
cfa_call(4, sink).
cfa_call(5, sink).
cfa_call(6, fnOut).

    %context rules
    % r0: keyA->keyA0, keyB->keyB0
    % r1: keyA->keyA1, keyB->keyB1
bind_scope(2, keys(keyA1A2), Info) :- bind_scope(2, keys(keyA1), Info).
bind_scope(2, keys(keyB1A2), Info) :- bind_scope(2, keys(keyB1), Info).
bind_scope(3, keys(keyA1B2), Info) :- bind_scope(3, keys(keyA1), Info).
bind_scope(3, keys(keyB1B2), Info) :- bind_scope(3, keys(keyB1), Info).

bind_scope(4, keys(keyA1A2A3), Info):-bind_scope(4, keys(keyA1A2), Info).
bind_scope(4, keys(keyB1A2A3), Info):-bind_scope(4, keys(keyB1A2), Info).
bind_scope(4, keys(keyA1B2A3), Info):-bind_scope(4, keys(keyA1B2), Info).
bind_scope(4, keys(keyB1B2A3), Info):-bind_scope(4, keys(keyB1B2), Info).

bind_scope(5, keys(keyA1A2B3), Info):-bind_scope(5, keys(keyA1A2), Info).
bind_scope(5, keys(keyB1A2B3), Info):-bind_scope(5, keys(keyB1A2), Info).
bind_scope(5, keys(keyA1B2B3), Info):-bind_scope(5, keys(keyA1B2), Info).
bind_scope(5, keys(keyB1B2B3), Info):-bind_scope(5, keys(keyB1B2), Info).


    %initial context
keys(
    keyA1; keyB1; 
    keyA1A2;
    keyB1A2;
    keyA1B2;
    keyB1B2;
    keyA1A2A3;
    keyA1A2B3;
    keyA1B2A3;
    keyA1B2B3;
    keyB1A2A3;
    keyB1A2B3;
    keyB1B2A3;
    keyB1B2B3
).

bind_scope(0, keys(keyA1), strong).
bind_scope(1, keys(keyB1), strong).
