我有一些事实:
num(one)
num(two)
num(three)
然后我有一个谓词:
validValue(value(Num, Num1, Num2, Num2, Num4)) :-
num(Num), num(Num1), num(Num2), num(Num3), num(num4).
我现在想编写一个输出有效
的查询value(num,num1,num2,num3,num4)
但我希望它只显示带有num(两个)和num(三个)的有效输出。 例如,有效:
value(two,one,one,one,three)
无效
value(two,one,one,one,one)
我的思路是将X指定为两个,Y指定为三个,或者其他类似的指定并使用
validValue(value(X)).
但这显然只等于:
validValue(value(two)).
任何人都能告诉我我做错了什么? 非常感谢,谢谢。
答案 0 :(得分:3)
在“生成和测试”方法中,您需要测试某个术语的参数是否适用。
对于列表,这很容易。要说List
至少包含Element
中的一个,您可以使用memberchk/2
:
memberchk(Element, List)
您还可以使用univ运算符=../2
从术语的参数中创建列表:
Value =.. [value|Vs]
换句话说,你可以写:
is_valid(Value) :-
Value =.. [value|Vs],
memberchk(two, Vs), memberchk(three, Vs).
唯一的好处是,如果术语更改arity(突然间你有一个或多或少的值),则不必重新编写谓词。
要创建一个谓词,检查列表的每个成员是否至少出现一次作为术语中的参数,您可以写:
any_nums_value(Nums, Value) :-
Value =.. [value|Vs],
member(N, Nums),
memberchk(N, Vs).
然后:
% generate
?- valid(V).
V = value(one, one, one, one, one) ;
V = value(one, one, one, one, two) ;
V = value(one, one, one, one, three) ;
V = value(one, one, one, two, one) .
% generate and test
?- valid(V), any_nums_value([two, three], V).
V = value(one, one, one, one, two) ;
V = value(one, one, one, one, three) ;
V = value(one, one, one, two, one) ;
V = value(one, one, one, two, two) .
在上面的any_nums_value/2
中,联合member(N, Nums), memberchk(N, Vs)
表示:
Nums
中有Vs
成员至少出现一次Nums
如果你需要说:
中出现一次
Vs
的每位成员至少在all_nums_value(Nums, Value) :- Value =.. [value|Vs], maplist(list_check_member(Vs), Nums). list_check_member(List, Member) :- memberchk(Member, List).
然后你需要写:
list_check_member/2
maplist
是必要的,以便参数顺序适合?- valid(V), all_nums_value([two, three], V).
V = value(one, one, one, two, three) ;
V = value(one, one, one, three, two) ;
V = value(one, one, two, one, three) ;
V = value(one, one, two, two, three) .
% and so on
的工作方式。
然后:
valid/1
顺便说一下,我已将valid(value(A,B,C,D,E)) :-
maplist(num, [A,B,C,D,E]).
定义为:
valid_n(V, N) :-
length(Vs, N),
maplist(num, Vs),
V =.. [value|Vs].
?- valid_n(V, 3).
V = value(one, one, one) ;
V = value(one, one, two) ;
V = value(one, one, three) ;
V = value(one, two, one) .
% and so on
?- valid_n(V, 10).
V = value(one, one, one, one, one, one, one, one, one, one) .
% and so on
如果你想制作lentgth N的有效值,你可以写:
>>> from unidecode import unidecode
>>> unidecode('serhat kılıç')
'serhat kilic'
>>> unidecode('serhat kilic')
'serhat kilic'
>>> # as a bonus it does much more, like
>>> unidecode('北亰')
'Bei Jing '
答案 1 :(得分:2)
Soo如果我理解正确的话会这样:
%% facts
num(one).
num(two).
num(three).
two(two).
three(three).
%% rules
validValue(Val) :-
contains_two(Val),
contains_three(Val),
valid_numbers(Val).
valid_numbers(value(Num, Num1, Num2, Num3, Num4)):-
num(Num),
num(Num1),
num(Num2),
num(Num3),
num(Num4).
contains_two(value(Num, Num1, Num2, Num3, Num4)):-
two(Num);
two(Num1);
two(Num2);
two(Num3);
two(Num4).
contains_three(value(Num, Num1, Num2, Num3, Num4)):-
three(Num);
three(Num1);
three(Num2);
three(Num3);
three(Num4).
test:-
validValue(value(two,one,one,one,three)),
\+ validValue(value(two,one,one,one,one)).
这将验证包含三和二的所有值,并且所有数字都是有效数字。
您还可以进行查询以查找有效数字,例如:
?- validValue(value(Num, Num1, Num2, Num3, Num4)).
Num = two,
Num1 = three,
Num2 = Num3, Num3 = Num4, Num4 = one
如果您想要所有可能的数字,可以查询:
?- findall(X, validValue(X), Result).
Result = [value(two, three, one, one, one), value(two, three, one, one, two), value(two, three, one, one, three), value(two, three, one, two, one), value(two, three, one, two, two), value(two, three, one, two, three), value(two, three, one, three, one), value(two, three, one, three, two), value(..., ..., ..., ..., ...)|...].