如何在Prolog中生成事实(any)?
我有一个数据库,它由树的列表和关于这些树的事实组成。例如:如何在Prolog中生成事实(any)?,prolog,Prolog,我有一个数据库,它由树的列表和关于这些树的事实组成。例如: softness(soft). softness(hard). softness(veryhard). color(gray_brown). color(soft_red). color(light). color(dark). wood(oak, leafes(leafed), softness(hard), color(gray_brown), on_touch(smalltexture)). 我试图制定一个规则,要求用户输入
softness(soft).
softness(hard).
softness(veryhard).
color(gray_brown).
color(soft_red).
color(light).
color(dark).
wood(oak, leafes(leafed), softness(hard), color(gray_brown), on_touch(smalltexture)).
我试图制定一个规则,要求用户输入树的特定参数,然后寻找合适的参数。像这样
what_wood(A, B):-
wood(A, B, _, _, _);
wood(A, _, B, _, _);
wood(A, _, _, B, _);
wood(A, _, _, _, B);
wood(A, B, _, _); %I have one tree with three parameters =/
wood(A, _, B, _);
wood(A, _, _, B).
what_wood(A) :-
write('Leafes: '), read(X), what_wood(A, leafes(X)),
write('Softness: '), read(Y), what_wood(A, softness(Y)),
write('Color: '), read(Z), what_wood(A, color(Z)),
write('On touch: '), read(Q), what_wood(A, on_touch(Q)).
所以我的问题是——如果用户想将参数指定为“any”,有没有这样的方法
leafes(leafed).
leafes(coniferous).
leafes(any):-
leafes(X). %this one doesn't work. Prints false
%leafes(leafed);leafes(coniferous). %Of course this doesn't work too.
(对不起我的英语:))
====更新=====
多亏了你,我最终得到了这段代码:)
还将为用户输入添加检查
wood(oak, leafed).
wood(oak, hard).
wood(oak, gray_brown).
wood(oak, smalltexture).
wood(beech, leafed).
wood(beech, hard).
wood(beech, soft_red).
wood(beech, largetexture).
wood(yew, leafed).
wood(yew, veryhard).
wood(yew, dark).
...
what_wood(A, B, C, D, E):-
wood(A, B), wood(A, C), wood(A, D), wood(A, E).
what_wood(A) :-
write('Leafes: '), read(X), convert(X, Leaves),
write('Softness: '), read(Y), convert(Y, Softness),
write('Color: '), read(Z), convert(Z, Color),
write('On touch: '), read(Q), convert(Q, OnTouch),
what_wood(A, Leaves, Softness, Color, OnTouch).
convert(any, _) :-
!.
convert(Attrib, Attrib).
此代码返回的答案与
A = oak ;
A = oak ;
...
A = beech ;
A = beech .
但这是另一个与当前问题无关的故事。Prolog是一种具有干净关系数据模型的语言。我会选择不同的模式,分离每个属性:比如
wood(oak, leafes(leafed)).
wood(oak, softness(hard)).
...
通过这种方式,您可以依赖于通常的关系模式来应用于您的“应用程序”。具体来说,Prolog使用查询作为过程…假设wood属性的数量是固定的,在您的示例中,您可以使用以下事实定义谓词
wood/5
:
% wood(Wood, Leaves, Softness, Color, OnTouch).
wood(oak, leafed, hard, gray_brown, smalltexture).
然后,您可以修改what_wood/1
谓词,这样当用户为属性输入atomany
时,它在尝试匹配wood/5
事实时使用匿名变量。比如:
what_wood(Wood) :-
write('Leafes: '), read(Leafes0), convert(Leafes0, Leafes),
write('Softness: '), read(Softness0), convert(Softness0, Softness),
write('Color: '), read(Color), convert(Color0, Color),
write('On touch: '), read(OnTouch), convert(OnTouch0, OnTouch),
wood(Wood, Leaves, Softness, Color, OnTouch).
convert(any, _) :-
!.
convert(Attribute, Attribute).
下一步是检查用户输入值的有效性,例如,如果无效,则重复该问题。例如,您可以定义一个read_属性/2
谓词,该谓词将执行读取操作,并在用户输入有效值之前重复该谓词:
read_attribute(Attribute, Value) :-
repeat,
write('Value for '), write(Attribute), write(': '),
read(Value),
valid_attribute(Attribute, Value),
!.
valid_attribute(leafes, leafed).
valid_attribute(leafes, coniferous).
valid_attribute(leafes, any).
...
这可以从几个方面加以改进。例如,通过在询问属性值时打印属性的可能值,以便用户知道哪些值被接受为有效值。谓词valid\u属性/2
也可以重写,以避免在测试时创建选择点。您还可以重写此谓词,以利用已存在的有效属性值的事实:
valid_attribute(Attribute, Value) :-
Test =.. [Attribute, Value],
once(Test).
您可以查询
?-leaves(X)。
查询中出现的变量是存在量化的,即“是否存在某种“leaves”?”如果您对特定的答案不感兴趣,您也可以使用\uu
i.o.X
。我已经知道这一点。问题是:当用户提示“leaves(any)”时,prolog会给出“leaves(leaved);leaves(conicored)”。这并不是prolog的正确用法。当您查询leaves(any)
时,您询问的是一个没有变量的事实leaves(Any)
确实是查询它的正确方法。您的示例也是一个无限循环。它不显示“假”,而是无限循环,连续显示“真”结果。好吧,这是一个很好的观点!您的模式看起来更好。我将尝试更改我的数据库,看看是否可以完成我的任务。谢谢!这种转换以我想要的方式工作。另外,感谢您提供用户输入检查。真的帮了我很多忙。