我在这个问题中清楚地提出了这个问题。 我有一个这样的图表:
a <-> b -> e -> f
| |
v v
h <------- g
| |
v v
u k
依赖关系描述在列表entries
let entries = [
("a", ["b"; "h"]);
("b", ["a"; "e"]);
("e", ["f"; "g"]);
("g", ["h"; "k"]);
("h", ["u"]);
]
我提取了一个列表defined
和undefined
,结果如下:
let defined = ["a"; "b"; "e"; "g"; "h"; "u"]
let undefined = ["f"; "k"]
计算完毕后,我得到了一个新订单:
let ordered = [["u"];["h"]; ["k"]; ["g"]; ["f"]; ["e"]; ["b"; "a"]]
我想编写一个函数,在这样的条件下打印ordered
的输出:
1)我希望有一个函数可以在列表ordered
中生成一个新列表,如果undefined
中的元素出现它将删除它。我期待newordered
像这样:
newordered = [["u"]; ["h"]; ["g"]; ["e"]; ["b"; "a"]]
2)我想打印他们的依赖条件:
当它只是一种类型依赖时,它将打印:
Definition name := type depend.
当它是等值(a&lt; - &gt; b)时,它将打印:
Inductive name1 := type depend 1
with name2 := type depend 2.
当它是一个类型依赖的列表时,它将打印:
Inductive name := type depend.
当它看到undefined
列表中的类型,并且当它不依赖类型时,它将打印出来:
Definition name := name.
以及newordered
列表
我期待的输出如下:
Definition k := k.
Definition f := f.
Definition u := u.
Definition h := u.
Inductive g := h -> k.
Inductive e := f -> g.
Inductive b := a -> e
with a := b -> h.
我编写这些函数,首先打印未定义列表中的所有元素:
let print_undfined =
List.iter (fun name -> Printf.printf "\nDefinition %s := %s." name name;
print_string "\n")undefined
我有一个打印条目列表右侧的函数:
let defn_of =
List.iter (fun (_, xs) ->
List.iter (fun t -> Printf.printf "%s" t) xs)
我有另一个功能可以删除ordered
列表中带有undefined
列表的副本
let rec uniquify = function
| [] -> []
| x::xs -> x :: uniquify (List.filter ((<>) x) xs)
let new_sort = uniquify (undefined @ List.flatten ordered)
但是这个列表是string list
,它在字体中添加了undefined
列表。因此,如果我打印我的上一个函数,如果我选择先打印undefined
中的所有元素,它将复制undefined
。我不希望这样。
而且我不知道如何用最后一个函数为我编写最后一个函数。
答案 0 :(得分:1)
首先,我通过查找defn_of
来更正entries
函数以返回标签关系的字符串表示形式:
let defn_of label =
try
let (_, xs) = List.find (fun (l, ys) -> l = label) entries in
String.concat "->" xs
with
Not_found -> ""
其次,你在new_sort
(应该是newordered
)中返回的内容显然是错误的。你真正想要的是过滤掉undefined
中出现一个元素的所有列表:
let newordered = List.filter (function [x] -> List.for_all((<>) x) undefined
| _ -> true) ordered
与往常一样,打印功能基于Printf模块和String.concat
中的功能。
打印任务有两种情况:
undefined
中的所有标签, 案例1 ,请使用上面的print_undfined
功能。
xs
中的任何列表newordered
, 案例2 ,如果xs
只有一个元素,则表示不存在等价类。如果xs
至少有两个元素,则应打印等价类:
let print_defined_equivalence xs =
match xs with
| [] -> ()
| [x] -> Printf.printf "\nInductive %s := %s." x (defn_of x)
| _ ->
let ys = String.concat "\nwith"
(List.map (fun x ->
Printf.sprintf "%s := %s" x (defn_of x))
xs) in
Printf.printf "\nInductive %s." ys
作为旁注,我选择将空列表作为newordered
的元素处理,尽管在您的测试用例中没有出现。另一件事是entries
被遍历多次以查找元素,它应该更改为Map
数据类型,尤其是当entries
很大时。
鉴于我已经明确说明了每种情况的条件,您应该能够将这些功能插入到您的程序中。