Если вы намерены завершить процесс входа в систему в самом мобильном приложении, а не в клиенте браузера, вам нужно будет использовать resource owner credentials
тип предоставления, и в этом случае не имеет значения, есть ли у вас один или несколько секретов в магазине, поскольку он аутентифицирует одного клиента в соответствии с вашим сценарием.
С другой стороны, если вы намереваетесь завершить поток входа в систему в клиенте браузера, то также не имеет значения, много ли у вас секретов или одного, потому что в этом случае я предполагаю, что выбор магазина будет сделан при входе в систему. экран, как вы упомянули, который будет частью сервера аутентификации.
В общем, нигде в вашем потоке местоположение магазина, кажется, не имеет значения, если нет какой-либо связи между учетными данными пользователя и идентификатором магазина. Если это так, то это по сути вопрос с несколькими арендаторами для Identity Server 4, для которого уже есть обсуждения с предложениями.
https://github.com/IdentityServer/IdentityServer4/issues/2673
Как защитить мультитенантный API с помощью Identity Server? [ 117]
Одна вещь, которую можно сделать, состоит в том, чтобы применяться setof/3
к предикату, который генерирует решения. Но отметьте это setof/3
реализован путем применения sort/2
к результату, обеспеченному bagof/3
(по крайней мере дело обстоит так в SWI-прологе). Так, если Ваш генератор решения продолжается навсегда, то setof/3
никогда не будет применяться...
Таким образом, я сказал бы, что попытка программировать так, чтобы дубликаты не были сгенерированы, т.е. при помощи сокращения (!), где это имеет смысл.
Если я помню правильно существует предикат решения (или подобный, это было некоторое время, так как я запрограммировал Пролог), который собирает уникальные решения в списке.
Править: setof/3
тот, о котором я думал. Спасибо, Kaarel.
Трудно сказать без большего количества Вашего кода, но Вы, вероятно, ищете оператор сокращения (!
). Если Вы хотите отправить определение foo
, Я (или кто-то еще, кто следует) могу давать подробный/конкретный ответ.
Другой подход к memoize решениям.
:- dynamic seen/1.
% Call this always before calling deadly_wrapper/1
clear_seen :-
retractall(seen(_)).
% This wrapper calls deadly/1 but remembers
% the solution using assert/1, and fails
% if the solution has been "seen" before.
deadly_wrapper(X) :-
deadly(X),
(
seen(X)
->
fail
;
assert(seen(X))
).
% This is for testing.
deadly(1).
deadly(1).
deadly(1).
deadly(5).
deadly(1).
deadly(1).
В случае, если Ваш Пролог поддерживает представление в виде таблицы, затем это становится еще более простым. Файл в качестве примера:
:- table deadly/1.
deadly(1).
deadly(1).
deadly(5).
deadly(1).
deadly(5).
Выполнение в качестве примера с XSB:
$ xsb
[xsb_configuration loaded]
[sysinitrc loaded]
XSB Version 3.2 (Kopi Lewak) of March 15, 2009
[x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam;
scheduling: local; word size: 64]
| ?- [deadly_tab].
[Compiling ./deadly_tab]
[deadly_tab compiled, cpu time used: 0.0100 seconds]
[deadly_tab loaded]
yes
| ?- deadly(X).
X = 5;
X = 1;
no
| ?-