打印条件

时间:2012-01-13 05:07:06

标签: ocaml

我在这个问题中清楚地提出了这个问题。 我有一个这样的图表:

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"]);
]

我提取了一个列表definedundefined,结果如下:

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。我不希望这样。

而且我不知道如何用最后一个函数为我编写最后一个函数。

1 个答案:

答案 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很大时。

鉴于我已经明确说明了每种情况的条件,您应该能够将这些功能插入到您的程序中。