Prolog:仅在用户不知道时才询问用户

时间:2016-11-18 22:35:07

标签: prolog

我想写一个KB,当试图证明一个目标时,如果它没有特定子目标的值,将要求用户输入。例如,请考虑以下事项:
可能的目标:

blue(X) :-
    color(X,blue).
white(X) :-
    color(X,white).
yellow(X) :-
    color(X,yellow).
orange(X) :-
    color(X,orange).
red(X) :-
    color(X,red).

要求输入:

askColor(X,Y) :- 
                write('color of  '),write(X),tab(2),
                read(Z),
                asserta(color(X,Z)),
                Y==Z. %only return "true" if the asserted color is the one we're looking for.
% trying to do "if we know the color is not Y, fail. otherwise (if we don't have a value for the color) ask the user". however, it always asks the user :(
color(X,Y) :- atom(Y), ((Z\=Y,atom(Z), color(X,Z)) -> fail ; askColor(X,Y)).

期望的结果是:

  • 用户输入blue(name).,因为" name"的颜色不明,我们问用户。如果用户输入" blue",color(name, blue)存储在KB中,我们得到" true"结果(我们在接下来的步骤中假设这一点)。如果输入任何其他内容,它将存储信息并返回" false"。这似乎工作正常。
  • blue(name)color(name,blue)的未来查询会立即返回" true",正如所料。
  • 现在出了问题:
    • 将来调用color(name,Y)作为解决方案返回Y=blue,但它也会要求用户输入。
    • red(name)color(name, red)的调用仍然要求用户输入。他们应该立即返回" false"因为color(name,blue)已知并且"蓝色"不等于"红色"。

我理解,对于这个特定的例子,要求用户在一组支持的值(我有代码)之间选择一个菜单可能更有意义。但是,我的程序的其他一些部分需要对整数执行相同的操作,这必须支持任何值。

1 个答案:

答案 0 :(得分:0)

这些事实可能有用:

:- dynamic db_color/2.

color(X,Y) :-
  db_color(X,Y).

color(X,_) :-
  db_color(X,_), !, fail.

color(X,Y) :-
  write('color of  '),write(X),tab(2),
  read(Z),
  asserta(db_color(X,Z)),
  Y=Z.

一些查询和结果:

?- color(apple,blue).
color of  apple  red.

false.

?- color(apple,blue).
false.

?- color(apple,red).
true ;
false.

?- color(apple,X).
X = red ;
false.

?- color(X,blue).
false.

?- color(X,red).
X = apple ;
false.

?- color(X,Y).
X = apple,
Y = red ;
false