summaryrefslogtreecommitdiff
path: root/sorsyl/lib/feature.ml
blob: f67a300c10956d40f80d54ebacf97192798dc3b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
(** Module for handling phonological features and segments *)

(* module Feature = struct *)

(** Type representing a phonological feature value *)
type feature_value = Plus | Minus | Zero

(** Type representing a phonological feature *)
type feature =
  | Syllabic
  | Sonorant
  | Consonantal
  | Continuant
  | DelayedRelease
  | Lateral
  | Nasal
  | Strident
  | Voiced
  | SpreadGlottis
  | ConstrictedGlottis
  | Anterior
  | Coronal
  | Distributed
  | Labial
  | High
  | Low
  | Back
  | Rounded
  | Velaric
  | Tense
  | Long
  | HighTone
  | HighReg (*high registry?*)

type feature_spec = feature * feature_value
(** Type representing a feature specification as a (value, feature) pair *)

type segment = feature_spec list

(** Convert a string feature value to the feature_value type *)
let value_of_string = function
  | "+" -> Plus
  | "-" -> Minus
  | "0" -> Zero
  | s -> failwith (Printf.sprintf "Invalid feature value: %s" s)

let string_of_value = function Plus -> "+" | Minus -> "-" | Zero -> "0"

let feature_of_string = function
  | "syl" -> Syllabic
  | "son" -> Sonorant
  | "cons" -> Consonantal
  | "cont" -> Continuant
  | "delrel" -> DelayedRelease
  | "lat" -> Lateral
  | "nas" -> Nasal
  | "strid" -> Strident
  | "voi" -> Voiced
  | "sg" -> SpreadGlottis
  | "cg" -> ConstrictedGlottis
  | "ant" -> Anterior
  | "cor" -> Coronal
  | "distr" -> Distributed
  | "lab" -> Labial
  | "hi" -> High
  | "lo" -> Low
  | "back" -> Back
  | "round" -> Rounded
  | "velaric" -> Velaric
  | "tense" -> Tense
  | "long" -> Long
  | "hitone" -> HighTone
  | "hireg" -> HighReg
  | _ -> failwith "not a valid feature"

let string_of_feature = function
  | Syllabic -> "syl"
  | Sonorant -> "son"
  | Consonantal -> "cons"
  | Continuant -> "cont"
  | DelayedRelease -> "delrel"
  | Lateral -> "lat"
  | Nasal -> "nas"
  | Strident -> "strid"
  | Voiced -> "voi"
  | SpreadGlottis -> "sg"
  | ConstrictedGlottis -> "cg"
  | Anterior -> "ant"
  | Coronal -> "cor"
  | Distributed -> "distr"
  | Labial -> "lab"
  | High -> "hi"
  | Low -> "lo"
  | Back -> "back"
  | Rounded -> "round"
  | Velaric -> "velaric"
  | Tense -> "tense"
  | Long -> "long"
  | HighTone -> "hitone"
  | HighReg -> "hireg"

let string_of_segment segment =
  Base.List.fold segment ~init:"" ~f:(fun acc (feature, value) ->
      let item =
        Printf.sprintf "%s:%s"
          (string_of_feature feature)
          (string_of_value value)
      in
      Printf.sprintf "%s\n%s" acc item)

(** Check if a segment has a specific feature with a given value *)
let has_feature (value, feature_name) segment =
  List.exists (fun (v, f) -> v = value && f = feature_name) segment

(** Create a feature test function for use in the decision tree *)
let test feature_spec segment = has_feature feature_spec segment
(* end *)