Qu-Prolog编程与多用户会议调度系统设计
立即解锁
发布时间: 2025-08-30 02:00:12 阅读量: 6 订阅数: 20 AIGC 

# Qu-Prolog编程与多用户会议调度系统设计
## 1. Qu-Prolog编程基础
### 1.1 消息选择机制
在Qu - Prolog中,消息选择机制用于处理消息缓冲区中的消息。消息选择的形式如下:
```plaintext
message_choice (
MsgGuard1 -> CallConj1 ;
MsgGuard2 -> CallConj2 ;
...
MsgGuardn -> CallConjn
)
```
每个`MsgGuard`的形式为`MsgPtn << S reply_to R :: Test`,其中`reply_to R`和`:: Test`是可选的。该机制会依次扫描消息缓冲区中的每个消息,与备选的消息守卫序列进行匹配。当找到一个消息`M`,它与某个消息守卫的`MsgPtn << S reply_to R`匹配,并且关联的`Test`调用成功时,该消息将从缓冲区中移除,并执行相应的`CallConj`。`Test`调用可以是任意的Qu - Prolog调用,通常用于测试消息`M`与`MsgPtn << S reply_to R`统一后得到的变量值。
消息选择调用在到达消息缓冲区末尾时会暂停,当有新消息添加时会自动恢复。还可以通过添加`timeout(T) -> TimeOutCall`作为消息选择的最后一个备选方案,将线程搜索可接受消息的时间限制为`T`秒。当达到时间限制且当前消息缓冲区中没有可接受的消息时,线程将执行`TimeOutCall`。
### 1.2 响应式组件编程
代理或信息源的公共命名接口线程通常是其响应式组件。其作用是对外部消息做出反应,将任何扩展处理委托给分叉线程,以便能够快速对其他消息做出反应。这样的线程将执行一个目标,例如`reactions`,由以下形式的单个Qu - Prolog子句定义:
```plaintext
reactions:-
message_choice (
MsgPtn1 -> Action1 ;
...
MsgPtnk -> Actionk
),
reactions. % 尾递归调用
```
### 1.3 实现KQML风格的信息源
#### 1.3.1 KQML消息作为Prolog项
KQML消息的形式为`(performative :keyword1 value1 :keyword2 value2 ...)`,可以映射为Prolog项`performative([keyword1(value1), keyword2(value2), ...])`。例如,KQML消息`(ask-one :reply-with q123 :language prolog :content “price(ford,mondeo,X)”)`变为`ask_one([reply_with(q123),language(prolog),content(price(ford,mondeo,X))])`。
#### 1.3.2 信息服务器程序
假设在不同主机上启动一系列信息服务器应用程序,每个应用程序名为`kqml server`,其中有一个主线程名为`listener`。通过向`listener@kqml server:machine`发送KQML消息与服务器通信。`listener`线程的程序如下:
```plaintext
listener_loop :-
message_choice
(
ask_if(AttList) << _ reply_to R ::
(member(content(Q),AttList),
member(reply_with(Lab),AttList))
->
(Q -> tell([in_reply_to(Lab),content(yes)]) >> R
;
tell([in_reply_to(Lab),content(no)]) >> R
;
ask_all(AttList) << _ reply_to R ::
(member(content(Q),AttList),
member(reply_with(Lab),AttList))
->
findall(Q,Q,Ans),
% Ans成为Q的解实例列表
tell([in_reply_to(Lab),content(Ans)]) >> R
;
stand_by(stream_all(AttList)) << _ reply_to R ::
member(content(Q),AttList)
->
thread_fork(ans_gen(Q,R),I),
generator(I) >> R
;
tell(content(A)) -> assert(A)
;
untell(content(A)) -> retract(A)
),
listener_loop.
ans_gen(Q,R):-
call(Q), % 获取查询Q的下一个答案
message_choice ( % 等待来自R的next或discard消息
next << R -> reply(Q) >> R,
% 如果是next,发送已解决的Q作为回复
fail
% 现在失败以获取call(Q)的下一个解
;
discard << R -> thread_exit). % 收到discard消息时终止
ans_gen(Q,R) :- % 当Q没有更多解时使用此子句
message_choice (
next << R -> reply(fail) >> R, thread_exit
;
discard << R -> thread_exit).
```
### 1.4 远程调用信息服务器
如果客户端是Prolog线程,可以使用以下元调用谓词(声明为运算符)透明地向信息服务器发送远程查询:
- `Call..Q_S`:向查询服务器`Q_S`发送`ask if`消息。
```plaintext
Call..Q_S :-
gen_label(Lab),
ask_if([reply_with(Lab),content(Call)]) >> Q_S,
tell(L) <<= Q_S,
member(in_reply_to(Lab),L),
member(content(yes),L).
% 若答案为no,Call..Q_S失败
```
- `Call?Q_S`:向查询服务器`Q_S`发送`ask all`消息,等待服务器返回解列表,然后根据需要使用`member`在本地回溯解。
```plaintext
Call?Q_S:-
gen_label(Lab),
ask_all([reply_with(Lab),content(Call)]) >> Q_S,
tell(L) <<= Q_S,
member(in_reply_to(La
```
0
0
复制全文
相关推荐










