you can ‘invoke’ alternative bindings on Y
this way:
...registered(X, Y), (Y=ct101; Y=ct102; Y=ct103).
Note the parenthesis are required to keep the correct execution control flow. The ;
/2 it’s the general or
operator. For your restricted use you could as well choice the more idiomatic
...registered(X, Y), member(Y, [ct101,ct102,ct103]).
that on backtracking binds Y to each member of the list.
edit I understood with a delay your last requirement. If you want that Y match all 3 values the or is inappropriate, use instead
...registered(X, ct101), registered(X, ct102), registered(X, ct103).
or the more compact
...findall(Y, registered(X, Y), L), sort(L, [ct101,ct102,ct103]).
findall/3 build the list in the very same order that registered/2 succeeds. Then I use sort to ensure the matching.
...setof(Y, registered(X, Y), [ct101,ct102,ct103]).
setof/3 also sorts the result list