对称关系递归 SML
Symmetric Relation Recursive SML
在 ML isRelationSymmetric 中定义一个递归谓词,它接受关系 r(表示为元组列表)并且 returns 如果 r 是对称的则为真,否则为假。
这是我目前的情况。
fun isRelationSymmetric([]) = false
| isRelationSymmetric((a,b)::rest) =
val x = [(1,2),(2,1),(2,3),(3,2)]; //suppose to come out true
val y = [(1,1),(1,3)]; //suppose to come out false
val z = [(1,2),(2,1),(1,3)]; //suppose to come out false
isRelationSymmetric(x);
isRelationSymmetric(y);
isRelationSymmetric(z);
我只能检查前两个元素的对称性,但我需要检查其余部分。
fun isRelationSymmetric(relation) =
let
fun testOne((a, b), []) = false
| testOne((a, b), (c, d)::rest) =
(b = c) andalso (a = d) orelse testOne((a, b), rest);
fun test([]) = true
| test((a,b)::rest) = testOne((a, b), relation) andalso test(rest);
in
test(relation)
end;
(* Test cases *)
val x = [(1, 2), (2, 1), (2, 3), (3, 2)]; (* true *)
isRelationSymmetric(x);
val y = [(1, 1), (2, 3)]; (* false *)
isRelationSymmetric(y);
val z = [(1, 2), (2, 1)]; (* true *)
isRelationSymmetric(z);
@jwolf 似乎已经解决了这个问题,另一种方法利用了 List.exists
.
fun sym(relation) =
let
fun sym'([]) = true
| sym'((a, b)::rest) =
List.exists (fn (c, d) => a = d andalso b = c) relation
andalso sym'(rest)
in
sym'(relation)
end;
但是,为了澄清,[(1, 2), (2, 1), (2, 3), (3, 2), (3, 2)]
是否应该测试对称,因为 (3, 2)
有两个实例而 (2, 3)
只有 1 个实例?
如果我们想抓住这一点,我们可以使用 List.filter
找到我们正在考虑的对的任何反向,然后计算该列表的长度。该列表的长度应等于与当前配对匹配的列表的长度。
fun sym(relation) =
let
fun sym'([]) = true
| sym'((a, b)::rest) =
let
val len = List.length(List.filter (fn (c, d) => a = d andalso b = c) relation)
val len' = List.length(List.filter (fn (c, d) => a = c andalso b = d) relation)
in
len = len' andalso sym'(rest)
end
in
sym'(relation)
end;
在 ML isRelationSymmetric 中定义一个递归谓词,它接受关系 r(表示为元组列表)并且 returns 如果 r 是对称的则为真,否则为假。
这是我目前的情况。
fun isRelationSymmetric([]) = false
| isRelationSymmetric((a,b)::rest) =
val x = [(1,2),(2,1),(2,3),(3,2)]; //suppose to come out true
val y = [(1,1),(1,3)]; //suppose to come out false
val z = [(1,2),(2,1),(1,3)]; //suppose to come out false
isRelationSymmetric(x);
isRelationSymmetric(y);
isRelationSymmetric(z);
我只能检查前两个元素的对称性,但我需要检查其余部分。
fun isRelationSymmetric(relation) =
let
fun testOne((a, b), []) = false
| testOne((a, b), (c, d)::rest) =
(b = c) andalso (a = d) orelse testOne((a, b), rest);
fun test([]) = true
| test((a,b)::rest) = testOne((a, b), relation) andalso test(rest);
in
test(relation)
end;
(* Test cases *)
val x = [(1, 2), (2, 1), (2, 3), (3, 2)]; (* true *)
isRelationSymmetric(x);
val y = [(1, 1), (2, 3)]; (* false *)
isRelationSymmetric(y);
val z = [(1, 2), (2, 1)]; (* true *)
isRelationSymmetric(z);
@jwolf 似乎已经解决了这个问题,另一种方法利用了 List.exists
.
fun sym(relation) =
let
fun sym'([]) = true
| sym'((a, b)::rest) =
List.exists (fn (c, d) => a = d andalso b = c) relation
andalso sym'(rest)
in
sym'(relation)
end;
但是,为了澄清,[(1, 2), (2, 1), (2, 3), (3, 2), (3, 2)]
是否应该测试对称,因为 (3, 2)
有两个实例而 (2, 3)
只有 1 个实例?
如果我们想抓住这一点,我们可以使用 List.filter
找到我们正在考虑的对的任何反向,然后计算该列表的长度。该列表的长度应等于与当前配对匹配的列表的长度。
fun sym(relation) =
let
fun sym'([]) = true
| sym'((a, b)::rest) =
let
val len = List.length(List.filter (fn (c, d) => a = d andalso b = c) relation)
val len' = List.length(List.filter (fn (c, d) => a = c andalso b = d) relation)
in
len = len' andalso sym'(rest)
end
in
sym'(relation)
end;