我有数据库,其中包含树木列表和有关这些树木的事实。例如:
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.
(抱歉我的英文:))
===== UPDATE =====
我最终得到了这个代码,感谢你:) 还会添加对用户输入的检查。
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 .
但这是另一个与当前问题无关的故事。
答案 0 :(得分:0)
Prolog是一种具有干净的关系数据模型的语言。我会选择一个不同的模式,将每个属性分开:比如
wood(oak, leafes(leafed)).
wood(oak, softness(hard)).
...
通过这种方式,您可以依赖通常的关系模式来应用于“应用程序”。具体来说,Prolog使用查询作为程序......
答案 1 :(得分:0)
假设木材属性的数量是固定的,在您的示例中为4,您可以使用以下事实定义谓词wood/5
:
% wood(Wood, Leaves, Softness, Color, OnTouch).
wood(oak, leafed, hard, gray_brown, smalltexture).
然后,您可以修改what_wood/1
谓词,以便当用户输入属性的原子any
时,它会在尝试匹配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_attribute/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_attribute/2
以避免在测试时创建选择点。您还可以重写此谓词,以利用已有的有效属性值的事实:
valid_attribute(Attribute, Value) :-
Test =.. [Attribute, Value],
once(Test).