#!/usr/bin/perl -w use strict; use warnings; use List::Util 'shuffle'; # SR's targets (fields: target form, age in days, stress, final coda, complex onset) my @speech; push(@speech,["tapuax",426,"penult","voiceless","no"]); push(@speech,["toda",426,"final","none","no"]); push(@speech,["savta",433,"penult","none","no"]); push(@speech,["tapuax",433,"penult","voiceless","no"]); push(@speech,["tapuax",433,"penult","voiceless","no"]); push(@speech,["tapuax",433,"penult","voiceless","no"]); push(@speech,["toda",433,"final","none","no"]); push(@speech,["tapuax",442,"penult","voiceless","no"]); push(@speech,["tapuax",442,"penult","voiceless","no"]); push(@speech,["tapuax",446,"penult","voiceless","no"]); push(@speech,["tapuax",446,"penult","voiceless","no"]); push(@speech,["toda",446,"final","none","no"]); push(@speech,["dasi",450,"penult","none","no"]); push(@speech,["tapuax",450,"penult","voiceless","no"]); push(@speech,["toda",450,"final","none","no"]); push(@speech,["agas",462,"final","voiceless","none"]); push(@speech,["agas",462,"final","voiceless","none"]); push(@speech,["bakbuk",462,"final","voiceless","no"]); push(@speech,["bakbuk",462,"final","voiceless","no"]); push(@speech,["dasi",462,"penult","none","no"]); push(@speech,["hine",462,"penult","none","none"]); push(@speech,["pil",462,"mono","sonorant","no"]); push(@speech,["tapuax",462,"penult","voiceless","no"]); push(@speech,["toda",462,"final","none","no"]); push(@speech,["bakbuk",471,"final","voiceless","no"]); push(@speech,["dasi",471,"penult","none","no"]); push(@speech,["hine",471,"penult","none","none"]); push(@speech,["kapit",471,"final","voiceless","no"]); push(@speech,["saba",471,"penult","none","no"]); push(@speech,["saba",471,"penult","none","no"]); push(@speech,["tapuax",471,"penult","voiceless","no"]); push(@speech,["disk",476,"mono","voiceless","no"]); push(@speech,["disk",476,"mono","voiceless","no"]); push(@speech,["ets",476,"mono","voiceless","none"]); push(@speech,["kapit",476,"final","voiceless","no"]); push(@speech,["tapuax",476,"penult","voiceless","no"]); push(@speech,["ani",482,"final","none","none"]); push(@speech,["dasi",482,"penult","none","no"]); push(@speech,["djip",482,"mono","voiceless","no"]); push(@speech,["ets",482,"mono","voiceless","none"]); push(@speech,["kapit",482,"final","voiceless","no"]); push(@speech,["roni",482,"penult","none","no"]); push(@speech,["savta",482,"penult","none","no"]); push(@speech,["tapuax",482,"penult","voiceless","no"]); push(@speech,["tapuax",482,"penult","voiceless","no"]); push(@speech,["tuki",482,"penult","none","no"]); push(@speech,["tuki",482,"penult","none","no"]); push(@speech,["agas",490,"final","voiceless","none"]); push(@speech,["banana",490,"penult","none","no"]); push(@speech,["banana",490,"penult","none","no"]); push(@speech,["banana",490,"penult","none","no"]); push(@speech,["djip",490,"mono","voiceless","no"]); push(@speech,["hipopotam",490,"final","sonorant","none"]); push(@speech,["kapit",490,"final","voiceless","no"]); push(@speech,["kof",490,"mono","voiceless","no"]); push(@speech,["maim",490,"penult","sonorant","no"]); push(@speech,["or",490,"mono","sonorant","none"]); push(@speech,["panas",490,"final","voiceless","no"]); push(@speech,["pu",490,"mono","none","no"]); push(@speech,["roni",490,"penult","none","no"]); push(@speech,["tapuax",490,"penult","voiceless","no"]); push(@speech,["tapuax",490,"penult","voiceless","no"]); push(@speech,["televizya",490,"penult","none","no"]); push(@speech,["televizya",490,"penult","none","no"]); push(@speech,["tuki",490,"penult","none","no"]); push(@speech,["agas",497,"final","voiceless","none"]); push(@speech,["bakbuk",497,"final","voiceless","no"]); push(@speech,["banana",497,"penult","none","no"]); push(@speech,["djip",497,"mono","voiceless","no"]); push(@speech,["djirafa",497,"penult","none","no"]); push(@speech,["kapit",497,"final","voiceless","no"]); push(@speech,["kenguru",497,"ante","none","no"]); push(@speech,["kenguru",497,"ante","none","no"]); push(@speech,["kof",497,"mono","voiceless","no"]); push(@speech,["maim",497,"penult","sonorant","no"]); push(@speech,["mita",497,"final","none","no"]); push(@speech,["pil",497,"mono","sonorant","no"]); push(@speech,["pu",497,"mono","none","no"]); push(@speech,["tanin",497,"final","sonorant","no"]); push(@speech,["tapuax",497,"penult","voiceless","no"]); push(@speech,["tsav",497,"mono","voiced","no"]); push(@speech,["tuki",497,"penult","none","no"]); push(@speech,["tut",497,"mono","voiceless","no"]); push(@speech,["agala",504,"final","none","none"]); push(@speech,["ani",504,"final","none","none"]); push(@speech,["bambi",504,"penult","none","no"]); push(@speech,["banana",504,"penult","none","no"]); push(@speech,["beytsa",504,"final","none","no"]); push(@speech,["beytsa",504,"final","none","no"]); push(@speech,["beytsa",504,"final","none","no"]); push(@speech,["djirafa",504,"penult","none","no"]); push(@speech,["geshem",504,"penult","sonorant","no"]); push(@speech,["hipopotam",504,"final","sonorant","none"]); push(@speech,["hipopotam",504,"final","sonorant","none"]); push(@speech,["hipopotam",504,"final","sonorant","none"]); push(@speech,["kaftor",504,"final","sonorant","no"]); push(@speech,["kof",504,"mono","voiceless","no"]); push(@speech,["maim",504,"penult","sonorant","no"]); push(@speech,["motsets",504,"final","voiceless","no"]); push(@speech,["para",504,"final","none","no"]); push(@speech,["pil",504,"mono","sonorant","no"]); push(@speech,["roni",504,"penult","none","no"]); push(@speech,["tapuax",504,"penult","voiceless","no"]); push(@speech,["tarnegolet",504,"penult","voiceless","no"]); push(@speech,["tuki",504,"penult","none","no"]); push(@speech,["afifon",511,"final","sonorant","none"]); push(@speech,["ani",511,"final","none","none"]); push(@speech,["aviron",511,"final","sonorant","none"]); push(@speech,["aviron",511,"final","sonorant","none"]); push(@speech,["bakbuk",511,"final","voiceless","no"]); push(@speech,["djirafa",511,"penult","none","no"]); push(@speech,["ets",511,"mono","voiceless","none"]); push(@speech,["etsem",511,"penult","sonorant","none"]); push(@speech,["gavoha",511,"final","none","no"]); push(@speech,["geshem",511,"penult","sonorant","no"]); push(@speech,["hipopotam",511,"final","sonorant","none"]); push(@speech,["hipopotam",511,"final","sonorant","none"]); push(@speech,["kenguru",511,"ante","none","no"]); push(@speech,["kof",511,"mono","voiceless","no"]); push(@speech,["kova",511,"penult","none","no"]); push(@speech,["kova",511,"penult","none","no"]); push(@speech,["kubiya",511,"final","none","no"]); push(@speech,["lail",511,"penult","sonorant","no"]); push(@speech,["maim",511,"penult","sonorant","no"]); push(@speech,["or",511,"mono","sonorant","none"]); push(@speech,["oto",511,"penult","none","none"]); push(@speech,["para",511,"final","none","no"]); push(@speech,["perax",511,"penult","voiceless","no"]); push(@speech,["pil",511,"mono","sonorant","no"]); push(@speech,["tanin",511,"final","sonorant","no"]); push(@speech,["tapuax",511,"penult","voiceless","no"]); push(@speech,["tuki",511,"penult","none","no"]); push(@speech,["af",522,"mono","voiceless","none"]); push(@speech,["arox",522,"final","voiceless","none"]); push(@speech,["arye",522,"final","none","none"]); push(@speech,["aviron",522,"final","sonorant","none"]); push(@speech,["aviron",522,"final","sonorant","none"]); push(@speech,["bakbuk",522,"final","voiceless","no"]); push(@speech,["bakbuk",522,"final","voiceless","no"]); push(@speech,["bakbuk",522,"final","voiceless","no"]); push(@speech,["beten",522,"penult","sonorant","no"]); push(@speech,["bifnim",522,"final","sonorant","no"]); push(@speech,["cinderella",522,"penult","none","no"]); push(@speech,["djirafa",522,"penult","none","no"]); push(@speech,["dolfin",522,"final","sonorant","no"]); push(@speech,["ets",522,"mono","voiceless","none"]); push(@speech,["etsba",522,"penult","none","none"]); push(@speech,["garbayim",522,"penult","sonorant","no"]); push(@speech,["garbayim",522,"penult","sonorant","no"]); push(@speech,["gorila",522,"penult","none","no"]); push(@speech,["hipopotam",522,"final","sonorant","none"]); push(@speech,["hipopotam",522,"final","sonorant","none"]); push(@speech,["kenguru",522,"ante","none","no"]); push(@speech,["kof",522,"mono","voiceless","no"]); push(@speech,["kova",522,"penult","none","no"]); push(@speech,["lail",522,"penult","sonorant","no"]); push(@speech,["maim",522,"penult","sonorant","no"]); push(@speech,["mits",522,"mono","voiceless","no"]); push(@speech,["odpam",522,"penult","sonorant","no"]); push(@speech,["oto",522,"penult","none","none"]); push(@speech,["pil",522,"mono","sonorant","no"]); push(@speech,["pinuki",522,"penult","none","no"]); push(@speech,["pita",522,"penult","none","no"]); push(@speech,["pupik",522,"penult","voiceless","no"]); push(@speech,["pupik",522,"penult","voiceless","no"]); push(@speech,["regel",522,"penult","sonorant","no"]); push(@speech,["roni",522,"penult","none","no"]); push(@speech,["sus",522,"mono","voiceless","no"]); push(@speech,["tanin",522,"final","sonorant","no"]); push(@speech,["tsfardea",522,"penult","none","yes"]); push(@speech,["yad",522,"mono","voiced","no"]); push(@speech,["adom",526,"final","sonorant","none"]); push(@speech,["afifon",526,"final","sonorant","none"]); push(@speech,["agas",526,"final","voiceless","none"]); push(@speech,["agvanya",526,"final","none","none"]); push(@speech,["ani",526,"final","none","none"]); push(@speech,["arye",526,"final","none","none"]); push(@speech,["avatiax",526,"penult","voiceless","none"]); push(@speech,["banana",526,"penult","none","no"]); push(@speech,["dasi",526,"penult","none","no"]); push(@speech,["dasi",526,"penult","none","no"]); push(@speech,["djip",526,"mono","voiceless","no"]); push(@speech,["djirafa",526,"penult","none","no"]); push(@speech,["duvdevan",526,"final","sonorant","no"]); push(@speech,["efroax",526,"penult","voiceless","none"]); push(@speech,["gadol",526,"final","sonorant","no"]); push(@speech,["glida",526,"penult","none","yes"]); push(@speech,["hipopotam",526,"final","sonorant","none"]); push(@speech,["katom",526,"final","sonorant","no"]); push(@speech,["kof",526,"mono","voiceless","no"]); push(@speech,["koxav",526,"final","voiced","no"]); push(@speech,["koxav",526,"final","voiced","no"]); push(@speech,["lail",526,"penult","sonorant","no"]); push(@speech,["lail",526,"penult","sonorant","no"]); push(@speech,["meshulash",526,"final","voiceless","no"]); push(@speech,["migdal",526,"final","sonorant","no"]); push(@speech,["naal",526,"penult","sonorant","no"]); push(@speech,["namer",526,"final","sonorant","no"]); push(@speech,["odpam",526,"penult","sonorant","no"]); push(@speech,["oto",526,"penult","none","none"]); push(@speech,["para",526,"final","none","no"]); push(@speech,["pax",526,"mono","voiceless","no"]); push(@speech,["pazel",526,"penult","sonorant","no"]); push(@speech,["perax",526,"penult","voiceless","no"]); push(@speech,["pil",526,"mono","sonorant","no"]); push(@speech,["pilpel",526,"penult","sonorant","no"]); push(@speech,["po",526,"mono","none","no"]); push(@speech,["roni",526,"penult","none","no"]); push(@speech,["sevivon",526,"final","sonorant","no"]); push(@speech,["sheket",526,"penult","voiceless","no"]); push(@speech,["sika",526,"final","none","no"]); push(@speech,["sus",526,"mono","voiceless","no"]); push(@speech,["tanin",526,"final","sonorant","no"]); push(@speech,["tapuax",526,"penult","voiceless","no"]); push(@speech,["tapuzim",526,"final","sonorant","no"]); push(@speech,["tarnegolet",526,"penult","voiceless","no"]); push(@speech,["tarnegolet",526,"penult","voiceless","no"]); push(@speech,["televizya",526,"penult","none","no"]); push(@speech,["traktor",526,"penult","sonorant","yes"]); push(@speech,["tsipor",526,"final","sonorant","no"]); push(@speech,["tsiporim",526,"final","sonorant","no"]); push(@speech,["tut",526,"mono","voiceless","no"]); push(@speech,["yareax",526,"penult","voiceless","no"]); push(@speech,["yarok",526,"final","voiceless","no"]); push(@speech,["adom",533,"final","sonorant","none"]); push(@speech,["agas",533,"final","voiceless","none"]); push(@speech,["agas",533,"final","voiceless","none"]); push(@speech,["ananim",533,"final","sonorant","none"]); push(@speech,["arye",533,"final","none","none"]); push(@speech,["arye",533,"final","none","none"]); push(@speech,["axbar",533,"final","sonorant","none"]); push(@speech,["djirafa",533,"penult","none","no"]); push(@speech,["djirafa",533,"penult","none","no"]); push(@speech,["dov",533,"mono","voiced","no"]); push(@speech,["ez",533,"mono","voiced","none"]); push(@speech,["ez",533,"mono","voiced","none"]); push(@speech,["galgal",533,"final","sonorant","no"]); push(@speech,["gamad",533,"final","voiced","no"]); push(@speech,["ha#batsal",533,"final","sonorant","none"]); push(@speech,["hipopotam",533,"final","sonorant","none"]); push(@speech,["hipopotam",533,"final","sonorant","none"]); push(@speech,["hipopotam",533,"final","sonorant","none"]); push(@speech,["ido",533,"final","none","none"]); push(@speech,["ido",533,"final","none","none"]); push(@speech,["ido",533,"final","none","none"]); push(@speech,["karnayim",533,"penult","sonorant","no"]); push(@speech,["kelev",533,"penult","voiced","no"]); push(@speech,["kivsa",533,"final","none","no"]); push(@speech,["kivsa",533,"final","none","no"]); push(@speech,["kivsa",533,"final","none","no"]); push(@speech,["kof",533,"mono","voiceless","no"]); push(@speech,["kova",533,"penult","none","no"]); push(@speech,["koxav",533,"final","voiced","no"]); push(@speech,["lail",533,"penult","sonorant","no"]); push(@speech,["maim",533,"penult","sonorant","no"]); push(@speech,["naalayim",533,"penult","sonorant","no"]); push(@speech,["neshika",533,"final","none","no"]); push(@speech,["odpam",533,"penult","sonorant","no"]); push(@speech,["odpam",533,"penult","sonorant","no"]); push(@speech,["oto",533,"penult","none","none"]); push(@speech,["para",533,"final","none","no"]); push(@speech,["pe",533,"mono","none","no"]); push(@speech,["perax",533,"penult","voiceless","no"]); push(@speech,["pil",533,"mono","sonorant","no"]); push(@speech,["shemesh",533,"penult","voiceless","no"]); push(@speech,["sipur",533,"final","sonorant","no"]); push(@speech,["sira",533,"final","none","no"]); push(@speech,["sus",533,"mono","voiceless","no"]); push(@speech,["tapuax",533,"penult","voiceless","no"]); push(@speech,["tik",533,"mono","voiceless","no"]); push(@speech,["tova",533,"final","none","no"]); push(@speech,["tsiporim",533,"final","sonorant","no"]); push(@speech,["tsiporim",533,"final","sonorant","no"]); push(@speech,["tsvi",533,"mono","none","yes"]); push(@speech,["xatul",533,"final","sonorant","no"]); push(@speech,["xatula",533,"penult","none","no"]); push(@speech,["adom",539,"final","sonorant","none"]); push(@speech,["agvanya",539,"final","none","none"]); push(@speech,["bakbuk",539,"final","voiceless","no"]); push(@speech,["banana",539,"penult","none","no"]); push(@speech,["batata",539,"penult","none","no"]); push(@speech,["dasi",539,"penult","none","no"]); push(@speech,["gadol",539,"final","sonorant","no"]); push(@speech,["kapit",539,"final","voiceless","no"]); push(@speech,["kaved",539,"final","voiced","no"]); push(@speech,["keara",539,"final","none","no"]); push(@speech,["keara",539,"final","none","no"]); push(@speech,["kos",539,"mono","voiceless","no"]); push(@speech,["koxav",539,"final","voiced","no"]); push(@speech,["leviva",539,"final","none","no"]); push(@speech,["leviva",539,"final","none","no"]); push(@speech,["maim",539,"penult","sonorant","no"]); push(@speech,["melafefon",539,"final","sonorant","no"]); push(@speech,["mesanenet",539,"penult","voiceless","no"]); push(@speech,["muzika",539,"ante","none","no"]); push(@speech,["ner",539,"mono","sonorant","no"]); push(@speech,["odpam",539,"penult","sonorant","no"]); push(@speech,["odpam",539,"penult","sonorant","no"]); push(@speech,["of",539,"mono","voiceless","none"]); push(@speech,["or",539,"mono","sonorant","none"]); push(@speech,["pumpiya",539,"final","none","no"]); push(@speech,["pumpiya",539,"final","none","no"]); push(@speech,["ritspa",539,"final","none","no"]); push(@speech,["rotem",539,"penult","sonorant","no"]); push(@speech,["sevivon",539,"final","sonorant","no"]); push(@speech,["sufganya",539,"final","none","no"]); push(@speech,["sufganya",539,"final","none","no"]); push(@speech,["sufganya",539,"final","none","no"]); push(@speech,["taim",539,"final","sonorant","no"]); push(@speech,["tapuax",539,"penult","voiceless","no"]); push(@speech,["tapuz",539,"final","voiced","no"]); push(@speech,["tapuzim",539,"final","sonorant","no"]); push(@speech,["tik",539,"mono","voiceless","no"]); push(@speech,["tsiporim",539,"final","sonorant","no"]); push(@speech,["yad",539,"mono","voiced","no"]); push(@speech,["yareax",539,"penult","voiceless","no"]); push(@speech,["zvuvim",539,"final","sonorant","yes"]); push(@speech,["adom",547,"final","sonorant","none"]); push(@speech,["agas",547,"final","voiceless","none"]); push(@speech,["ali~baba",547,"penult","none","none"]); push(@speech,["aron",547,"final","sonorant","none"]); push(@speech,["arye",547,"final","none","none"]); push(@speech,["aviron",547,"final","sonorant","none"]); push(@speech,["axbar",547,"final","sonorant","none"]); push(@speech,["banana",547,"penult","none","no"]); push(@speech,["galgal",547,"final","sonorant","no"]); push(@speech,["galil",547,"final","sonorant","no"]); push(@speech,["harbe",547,"final","none","none"]); push(@speech,["kelev",547,"penult","voiced","no"]); push(@speech,["kivsa",547,"final","none","no"]); push(@speech,["kof",547,"mono","voiceless","no"]); push(@speech,["lail",547,"penult","sonorant","no"]); push(@speech,["melafefon",547,"final","sonorant","no"]); push(@speech,["mitriya",547,"final","none","no"]); push(@speech,["mitriya",547,"final","none","no"]); push(@speech,["motsets",547,"final","voiceless","no"]); push(@speech,["muzika",547,"ante","none","no"]); push(@speech,["namer",547,"final","sonorant","no"]); push(@speech,["odpam",547,"penult","sonorant","no"]); push(@speech,["para",547,"final","none","no"]); push(@speech,["pil",547,"mono","sonorant","no"]); push(@speech,["pilpel",547,"penult","sonorant","no"]); push(@speech,["pilpel",547,"penult","sonorant","no"]); push(@speech,["pkak",547,"mono","voiceless","yes"]); push(@speech,["raglayim",547,"penult","sonorant","no"]); push(@speech,["shaxar",547,"penult","sonorant","no"]); push(@speech,["sheket",547,"penult","voiceless","no"]); push(@speech,["sus",547,"mono","voiceless","no"]); push(@speech,["tanin",547,"final","sonorant","no"]); push(@speech,["tishu",547,"penult","none","no"]); push(@speech,["tushi",547,"penult","none","no"]); push(@speech,["adom",550,"final","sonorant","none"]); push(@speech,["adom",550,"final","sonorant","none"]); push(@speech,["ale",550,"final","none","none"]); push(@speech,["amok",550,"final","voiceless","none"]); push(@speech,["avanim",550,"final","sonorant","none"]); push(@speech,["bakbuk",550,"final","voiceless","no"]); push(@speech,["bots",550,"mono","voiceless","no"]); push(@speech,["dag",550,"mono","voiced","no"]); push(@speech,["delet",550,"penult","voiceless","no"]); push(@speech,["deshe",550,"penult","none","no"]); push(@speech,["gader",550,"final","sonorant","no"]); push(@speech,["gadol",550,"final","sonorant","no"]); push(@speech,["kaki",550,"penult","none","no"]); push(@speech,["kelev",550,"penult","voiced","no"]); push(@speech,["kotsim",550,"final","sonorant","no"]); push(@speech,["la#gina",550,"final","none","no"]); push(@speech,["lail",550,"penult","sonorant","no"]); push(@speech,["lemala",550,"penult","none","no"]); push(@speech,["madrega",550,"final","none","no"]); push(@speech,["maim",550,"penult","sonorant","no"]); push(@speech,["or",550,"mono","sonorant","none"]); push(@speech,["orna",550,"penult","none","none"]); push(@speech,["oto",550,"penult","none","none"]); push(@speech,["panas",550,"final","voiceless","no"]); push(@speech,["panas",550,"final","voiceless","no"]); push(@speech,["pax",550,"mono","voiceless","no"]); push(@speech,["perax",550,"penult","voiceless","no"]); push(@speech,["safsal",550,"final","sonorant","no"]); push(@speech,["safsal",550,"final","sonorant","no"]); push(@speech,["safsal",550,"final","sonorant","no"]); push(@speech,["shalom",550,"final","sonorant","no"]); push(@speech,["shaxar",550,"penult","sonorant","no"]); push(@speech,["shlulit",550,"final","voiceless","yes"]); push(@speech,["tik",550,"mono","voiceless","no"]); push(@speech,["tova",550,"final","none","no"]); push(@speech,["tsipor",550,"final","sonorant","no"]); push(@speech,["tsiporim",550,"final","sonorant","no"]); push(@speech,["xatul",550,"final","sonorant","no"]); push(@speech,["xatul",550,"final","sonorant","no"]); push(@speech,["yadayim",550,"penult","sonorant","no"]); push(@speech,["yalda",550,"final","none","no"]); push(@speech,["yona",550,"final","none","no"]); push(@speech,["yona",550,"final","none","no"]); push(@speech,["zanav",550,"final","voiced","no"]); push(@speech,["zevel",550,"penult","sonorant","no"]); push(@speech,["arnav",560,"final","voiced","none"]); push(@speech,["arnav",560,"final","voiced","none"]); push(@speech,["beseder",560,"penult","sonorant","no"]); push(@speech,["bob",560,"mono","voiced","no"]); push(@speech,["djirafa",560,"penult","none","no"]); push(@speech,["dubi",560,"penult","none","no"]); push(@speech,["eynayim",560,"penult","sonorant","none"]); push(@speech,["glida",560,"penult","none","yes"]); push(@speech,["ish",560,"mono","voiceless","none"]); push(@speech,["kadur",560,"final","sonorant","no"]); push(@speech,["kadur",560,"final","sonorant","no"]); push(@speech,["kaved",560,"final","voiced","no"]); push(@speech,["kof",560,"mono","voiceless","no"]); push(@speech,["kova",560,"penult","none","no"]); push(@speech,["kubiyot",560,"final","voiceless","no"]); push(@speech,["lemala",560,"penult","none","no"]); push(@speech,["levad",560,"final","voiced","no"]); push(@speech,["misparayim",560,"penult","sonorant","no"]); push(@speech,["motsets",560,"final","voiceless","no"]); push(@speech,["muzika",560,"ante","none","no"]); push(@speech,["odpam",560,"penult","sonorant","no"]); push(@speech,["oto",560,"penult","none","none"]); push(@speech,["oto",560,"penult","none","none"]); push(@speech,["pe",560,"mono","none","no"]); push(@speech,["pe",560,"mono","none","no"]); push(@speech,["poteyto",560,"penult","none","no"]); push(@speech,["raashan",560,"final","sonorant","no"]); push(@speech,["raglayim",560,"penult","sonorant","no"]); push(@speech,["regel",560,"penult","sonorant","no"]); push(@speech,["shir",560,"mono","sonorant","no"]); push(@speech,["shira",560,"penult","none","no"]); push(@speech,["sipur",560,"final","sonorant","no"]); push(@speech,["traktor",560,"penult","sonorant","yes"]); push(@speech,["xatul",560,"final","sonorant","no"]); push(@speech,["zehirut",560,"final","voiceless","no"]); push(@speech,["adom",568,"final","sonorant","none"]); push(@speech,["arye",568,"final","none","none"]); push(@speech,["bakbuk",568,"final","voiceless","no"]); push(@speech,["bel",568,"mono","sonorant","no"]); push(@speech,["bevakasha",568,"final","none","no"]); push(@speech,["bob",568,"mono","voiced","no"]); push(@speech,["brexa",568,"final","none","yes"]); push(@speech,["daysa",568,"final","none","no"]); push(@speech,["djirafa",568,"penult","none","no"]); push(@speech,["dov",568,"mono","voiced","no"]); push(@speech,["eser",568,"penult","sonorant","none"]); push(@speech,["galgal",568,"final","sonorant","no"]); push(@speech,["ha#banay",568,"final","sonorant","none"]); push(@speech,["hipopotam",568,"final","sonorant","none"]); push(@speech,["hipopotam",568,"final","sonorant","none"]); push(@speech,["kaf",568,"mono","voiceless","no"]); push(@speech,["kaki",568,"penult","none","no"]); push(@speech,["kan",568,"mono","sonorant","no"]); push(@speech,["karnaf",568,"final","voiceless","no"]); push(@speech,["kaxol",568,"final","sonorant","no"]); push(@speech,["keara",568,"final","none","no"]); push(@speech,["kelev",568,"penult","voiced","no"]); push(@speech,["kfits",568,"mono","voiceless","yes"]); push(@speech,["kivsa",568,"final","none","no"]); push(@speech,["koxavim",568,"final","sonorant","no"]); push(@speech,["lail",568,"penult","sonorant","no"]); push(@speech,["lemala",568,"penult","none","no"]); push(@speech,["lemala",568,"penult","none","no"]); push(@speech,["leytsan",568,"final","sonorant","no"]); push(@speech,["leytsan",568,"final","sonorant","no"]); push(@speech,["livyatan",568,"final","sonorant","no"]); push(@speech,["livyatan",568,"final","sonorant","no"]); push(@speech,["maim",568,"penult","sonorant","no"]); push(@speech,["meilim",568,"final","sonorant","no"]); push(@speech,["miki",568,"penult","none","no"]); push(@speech,["mita",568,"final","none","no"]); push(@speech,["mita",568,"final","none","no"]); push(@speech,["naknik",568,"final","voiceless","no"]); push(@speech,["odpam",568,"penult","sonorant","no"]); push(@speech,["oto",568,"penult","none","none"]); push(@speech,["pankeyk",568,"penult","voiceless","no"]); push(@speech,["pil",568,"mono","sonorant","no"]); push(@speech,["ratuv",568,"final","voiced","no"]); push(@speech,["regel",568,"penult","sonorant","no"]); push(@speech,["roni",568,"penult","none","no"]); push(@speech,["shaxar",568,"penult","sonorant","no"]); push(@speech,["shemesh",568,"penult","voiceless","no"]); push(@speech,["shir",568,"mono","sonorant","no"]); push(@speech,["shmone",568,"penult","none","yes"]); push(@speech,["shtayim",568,"penult","sonorant","yes"]); push(@speech,["sipur",568,"final","sonorant","no"]); push(@speech,["sira",568,"final","none","no"]); push(@speech,["tanin",568,"final","sonorant","no"]); push(@speech,["tesha",568,"penult","none","no"]); push(@speech,["toda",568,"final","none","no"]); push(@speech,["traktor",568,"penult","sonorant","yes"]); push(@speech,["xatuna",568,"final","none","no"]); push(@speech,["adom",574,"final","sonorant","none"]); push(@speech,["af",574,"mono","voiceless","none"]); push(@speech,["agol",574,"final","sonorant","none"]); push(@speech,["akavish",574,"final","voiceless","none"]); push(@speech,["ananim",574,"final","sonorant","none"]); push(@speech,["avigayil",574,"penult","sonorant","none"]); push(@speech,["aviron",574,"final","sonorant","none"]); push(@speech,["axbar",574,"final","sonorant","none"]); push(@speech,["ayelet",574,"penult","voiceless","none"]); push(@speech,["ba#panim",574,"final","sonorant","no"]); push(@speech,["banana",574,"penult","none","no"]); push(@speech,["banana",574,"penult","none","no"]); push(@speech,["bayit",574,"penult","voiceless","no"]); push(@speech,["dag",574,"mono","voiced","no"]); push(@speech,["dagim",574,"final","sonorant","no"]); push(@speech,["dasi",574,"penult","none","no"]); push(@speech,["djirafa",574,"penult","none","no"]); push(@speech,["dolfin",574,"final","sonorant","no"]); push(@speech,["dov",574,"mono","voiced","no"]); push(@speech,["dubim",574,"final","sonorant","no"]); push(@speech,["dvora",574,"final","none","yes"]); push(@speech,["ets",574,"mono","voiceless","none"]); push(@speech,["flamingo",574,"penult","none","yes"]); push(@speech,["gamad",574,"final","voiced","no"]); push(@speech,["gamadim",574,"final","sonorant","no"]); push(@speech,["gamal",574,"final","sonorant","no"]); push(@speech,["gav",574,"mono","voiced","no"]); push(@speech,["ha#rosh",574,"final","voiceless","none"]); push(@speech,["hipopotam",574,"final","sonorant","none"]); push(@speech,["hipopotam",574,"final","sonorant","none"]); push(@speech,["ido",574,"final","none","none"]); push(@speech,["ish",574,"mono","voiceless","none"]); push(@speech,["kafe",574,"final","none","no"]); push(@speech,["kaki",574,"penult","none","no"]); push(@speech,["kan",574,"mono","sonorant","no"]); push(@speech,["karish",574,"final","voiceless","no"]); push(@speech,["katan",574,"final","sonorant","no"]); push(@speech,["kaved",574,"final","voiced","no"]); push(@speech,["kaxa",574,"penult","none","no"]); push(@speech,["kelev",574,"penult","voiced","no"]); push(@speech,["kipod",574,"final","voiced","no"]); push(@speech,["kis",574,"mono","voiceless","no"]); push(@speech,["kise",574,"final","none","no"]); push(@speech,["kivsa",574,"final","none","no"]); push(@speech,["klemantina",574,"penult","none","yes"]); push(@speech,["kof",574,"mono","voiceless","no"]); push(@speech,["kos",574,"mono","voiceless","no"]); push(@speech,["koxav",574,"final","voiced","no"]); push(@speech,["koxavim",574,"final","sonorant","no"]); push(@speech,["lail",574,"penult","sonorant","no"]); push(@speech,["layla",574,"penult","none","no"]); push(@speech,["leytsan",574,"final","sonorant","no"]); push(@speech,["livyatan",574,"final","sonorant","no"]); push(@speech,["maim",574,"penult","sonorant","no"]); push(@speech,["masait",574,"final","voiceless","no"]); push(@speech,["meduza",574,"penult","none","no"]); push(@speech,["motsets",574,"final","voiceless","no"]); push(@speech,["naxash",574,"final","voiceless","no"]); push(@speech,["nemala",574,"final","none","no"]); push(@speech,["nemalim",574,"final","sonorant","no"]); push(@speech,["or",574,"mono","sonorant","none"]); push(@speech,["oto",574,"penult","none","none"]); push(@speech,["otobus",574,"ante","voiceless","none"]); push(@speech,["para",574,"final","none","no"]); push(@speech,["pax",574,"mono","voiceless","no"]); push(@speech,["perax",574,"penult","voiceless","no"]); push(@speech,["pil",574,"mono","sonorant","no"]); push(@speech,["pipi",574,"penult","none","no"]); push(@speech,["pu",574,"mono","none","no"]); push(@speech,["rosh",574,"mono","voiceless","no"]); push(@speech,["sandal",574,"final","sonorant","no"]); push(@speech,["shalat",574,"final","voiceless","no"]); push(@speech,["shalom",574,"final","sonorant","no"]); push(@speech,["shaxar",574,"penult","sonorant","no"]); push(@speech,["shemesh",574,"penult","voiceless","no"]); push(@speech,["sira",574,"final","none","no"]); push(@speech,["sus",574,"mono","voiceless","no"]); push(@speech,["susim",574,"final","sonorant","no"]); push(@speech,["tamnun",574,"final","sonorant","no"]); push(@speech,["tarnegol",574,"final","sonorant","no"]); push(@speech,["tfilayla",574,"penult","none","yes"]); push(@speech,["traktor",574,"penult","sonorant","yes"]); push(@speech,["tsav",574,"mono","voiced","no"]); push(@speech,["tsipor",574,"final","sonorant","no"]); push(@speech,["ugiya",574,"final","none","none"]); push(@speech,["ugiyot",574,"final","voiceless","none"]); push(@speech,["xatser",574,"final","sonorant","no"]); push(@speech,["xatul",574,"final","sonorant","no"]); push(@speech,["xibuk",574,"final","voiceless","no"]); push(@speech,["xilazon",574,"final","sonorant","no"]); push(@speech,["xipushit",574,"final","voiceless","no"]); push(@speech,["yalda",574,"final","none","no"]); push(@speech,["yanshuf",574,"final","voiceless","no"]); push(@speech,["yareax",574,"penult","voiceless","no"]); push(@speech,["zaxal",574,"penult","sonorant","no"]); push(@speech,["zebra",574,"penult","none","no"]); push(@speech,["adom",581,"final","sonorant","none"]); push(@speech,["aduma",581,"final","none","none"]); push(@speech,["agol",581,"final","sonorant","none"]); push(@speech,["arye",581,"final","none","none"]); push(@speech,["atsuv",581,"final","voiced","none"]); push(@speech,["aviron",581,"final","sonorant","none"]); push(@speech,["bakbuk",581,"final","voiceless","no"]); push(@speech,["bubot",581,"final","voiceless","no"]); push(@speech,["dag",581,"mono","voiced","no"]); push(@speech,["djirafa",581,"penult","none","no"]); push(@speech,["ets",581,"mono","voiceless","none"]); push(@speech,["eynayim",581,"penult","sonorant","none"]); push(@speech,["eynayim",581,"penult","sonorant","none"]); push(@speech,["galgal",581,"final","sonorant","no"]); push(@speech,["gamal",581,"final","sonorant","no"]); push(@speech,["ha#pe",581,"final","none","none"]); push(@speech,["haxutsa",581,"penult","none","none"]); push(@speech,["hipopotam",581,"final","sonorant","none"]); push(@speech,["igulim",581,"final","sonorant","none"]); push(@speech,["kadur",581,"final","sonorant","no"]); push(@speech,["kaktus",581,"penult","voiceless","no"]); push(@speech,["karnaf",581,"final","voiceless","no"]); push(@speech,["karusela",581,"penult","none","no"]); push(@speech,["kelev",581,"penult","voiced","no"]); push(@speech,["kenguru",581,"ante","none","no"]); push(@speech,["kof",581,"mono","voiceless","no"]); push(@speech,["kova",581,"penult","none","no"]); push(@speech,["lail",581,"penult","sonorant","no"]); push(@speech,["magafayim",581,"penult","sonorant","no"]); push(@speech,["makom",581,"final","sonorant","no"]); push(@speech,["makom",581,"final","sonorant","no"]); push(@speech,["mapa",581,"final","none","no"]); push(@speech,["mapa",581,"final","none","no"]); push(@speech,["meil",581,"final","sonorant","no"]); push(@speech,["mitriya",581,"final","none","no"]); push(@speech,["muzika",581,"ante","none","no"]); push(@speech,["namer",581,"final","sonorant","no"]); push(@speech,["naxash",581,"final","voiceless","no"]); push(@speech,["odpam",581,"penult","sonorant","no"]); push(@speech,["or",581,"mono","sonorant","none"]); push(@speech,["oto",581,"penult","none","none"]); push(@speech,["otobus",581,"ante","voiceless","none"]); push(@speech,["para",581,"final","none","no"]); push(@speech,["pax",581,"mono","voiceless","no"]); push(@speech,["pazel",581,"penult","sonorant","no"]); push(@speech,["perax",581,"penult","voiceless","no"]); push(@speech,["pil",581,"mono","sonorant","no"]); push(@speech,["pil",581,"mono","sonorant","no"]); push(@speech,["pu",581,"mono","none","no"]); push(@speech,["sartan",581,"final","sonorant","no"]); push(@speech,["shalom",581,"final","sonorant","no"]); push(@speech,["shaxar",581,"penult","sonorant","no"]); push(@speech,["sheli",581,"final","none","no"]); push(@speech,["shual",581,"final","sonorant","no"]); push(@speech,["sulam",581,"final","sonorant","no"]); push(@speech,["sus",581,"mono","voiceless","no"]); push(@speech,["Tal",581,"mono","sonorant","no"]); push(@speech,["tapuax",581,"penult","voiceless","no"]); push(@speech,["televizya",581,"penult","none","no"]); push(@speech,["teyp",581,"mono","voiceless","no"]); push(@speech,["tik",581,"mono","voiceless","no"]); push(@speech,["traktor",581,"penult","sonorant","yes"]); push(@speech,["tsahov",581,"final","voiced","no"]); push(@speech,["tuki",581,"penult","none","no"]); push(@speech,["xalon",581,"final","sonorant","no"]); push(@speech,["xatul",581,"final","sonorant","no"]); push(@speech,["xayot",581,"final","voiceless","no"]); push(@speech,["xayot",581,"final","voiceless","no"]); push(@speech,["yad",581,"mono","voiced","no"]); push(@speech,["yalda",581,"final","none","no"]); push(@speech,["yam",581,"mono","sonorant","no"]); push(@speech,["yareax",581,"penult","voiceless","no"]); push(@speech,["yeled",581,"penult","voiced","no"]); push(@speech,["yeled",581,"penult","voiced","no"]); push(@speech,["yona",581,"final","none","no"]); push(@speech,["zebra",581,"penult","none","no"]); push(@speech,["zebra",581,"penult","none","no"]); push(@speech,["zehirut",581,"final","voiceless","no"]); push(@speech,["zehirut",581,"final","voiceless","no"]); push(@speech,["af",588,"mono","voiceless","none"]); push(@speech,["agala",588,"final","none","none"]); push(@speech,["agala",588,"final","none","none"]); push(@speech,["agas",588,"final","voiceless","none"]); push(@speech,["agvanya",588,"final","none","none"]); push(@speech,["akavish",588,"final","voiceless","none"]); push(@speech,["al kulam",588,"final","sonorant","none"]); push(@speech,["ambulans",588,"ante","voiceless","none"]); push(@speech,["ambulans",588,"ante","voiceless","none"]); push(@speech,["anavim",588,"final","sonorant","none"]); push(@speech,["arnav",588,"final","voiced","none"]); push(@speech,["arye",588,"final","none","none"]); push(@speech,["aviron",588,"final","sonorant","none"]); push(@speech,["axbar",588,"final","sonorant","none"]); push(@speech,["axer",588,"final","sonorant","none"]); push(@speech,["axer",588,"final","sonorant","none"]); push(@speech,["axer",588,"final","sonorant","none"]); push(@speech,["ayin",588,"penult","sonorant","none"]); push(@speech,["bakbuk",588,"final","voiceless","no"]); push(@speech,["bamba",588,"penult","none","no"]); push(@speech,["bamba",588,"penult","none","no"]); push(@speech,["banana",588,"penult","none","no"]); push(@speech,["beytsa",588,"final","none","no"]); push(@speech,["buba",588,"final","none","no"]); push(@speech,["dag",588,"mono","voiced","no"]); push(@speech,["dagim",588,"final","sonorant","no"]); push(@speech,["djirafa",588,"penult","none","no"]); push(@speech,["djuk",588,"mono","voiceless","no"]); push(@speech,["dov",588,"mono","voiced","no"]); push(@speech,["dubi",588,"penult","none","no"]); push(@speech,["dvora",588,"final","none","yes"]); push(@speech,["efroax",588,"penult","voiceless","none"]); push(@speech,["efroax",588,"penult","voiceless","none"]); push(@speech,["esh",588,"mono","voiceless","none"]); push(@speech,["ets",588,"mono","voiceless","none"]); push(@speech,["eynayim",588,"penult","sonorant","none"]); push(@speech,["ez",588,"mono","voiced","none"]); push(@speech,["gadol",588,"final","sonorant","no"]); push(@speech,["gamal",588,"final","sonorant","no"]); push(@speech,["geshem",588,"penult","sonorant","no"]); push(@speech,["gezer",588,"penult","sonorant","no"]); push(@speech,["ha#kenguru",588,"ante","none","none"]); push(@speech,["ha#kof",588,"final","voiceless","none"]); push(@speech,["ha#pil",588,"final","sonorant","none"]); push(@speech,["haftaa",588,"final","none","none"]); push(@speech,["haftaa",588,"final","none","none"]); push(@speech,["hayom",588,"final","sonorant","none"]); push(@speech,["hipopotam",588,"final","sonorant","none"]); push(@speech,["ish",588,"mono","voiceless","none"]); push(@speech,["kadur",588,"final","sonorant","no"]); push(@speech,["kan",588,"mono","sonorant","no"]); push(@speech,["katan",588,"final","sonorant","no"]); push(@speech,["kaxol",588,"final","sonorant","no"]); push(@speech,["kelev",588,"penult","voiced","no"]); push(@speech,["kenguru",588,"ante","none","no"]); push(@speech,["kenguru",588,"ante","none","no"]); push(@speech,["kipod",588,"final","voiced","no"]); push(@speech,["kipod",588,"final","voiced","no"]); push(@speech,["kise",588,"final","none","no"]); push(@speech,["kiyor",588,"final","sonorant","no"]); push(@speech,["klemantina",588,"penult","none","yes"]); push(@speech,["kof",588,"mono","voiceless","no"]); push(@speech,["kofim",588,"final","sonorant","no"]); push(@speech,["kofim",588,"final","sonorant","no"]); push(@speech,["kofim",588,"final","sonorant","no"]); push(@speech,["kova",588,"penult","none","no"]); push(@speech,["kova",588,"penult","none","no"]); push(@speech,["ktana",588,"final","none","yes"]); push(@speech,["kulam",588,"final","sonorant","no"]); push(@speech,["kvish",588,"mono","voiceless","yes"]); push(@speech,["lashon",588,"final","sonorant","no"]); push(@speech,["lavan",588,"final","sonorant","no"]); push(@speech,["lemala",588,"penult","none","no"]); push(@speech,["lemala",588,"penult","none","no"]); push(@speech,["lemala",588,"penult","none","no"]); push(@speech,["levia",588,"final","none","no"]); push(@speech,["lexem",588,"penult","sonorant","no"]); push(@speech,["livyatan",588,"final","sonorant","no"]); push(@speech,["livyatan",588,"final","sonorant","no"]); push(@speech,["livyatan",588,"final","sonorant","no"]); push(@speech,["mafteax",588,"penult","voiceless","no"]); push(@speech,["magafayim",588,"penult","sonorant","no"]); push(@speech,["magevet",588,"penult","voiceless","no"]); push(@speech,["masait",588,"final","voiceless","no"]); push(@speech,["mashrokit",588,"final","voiceless","no"]); push(@speech,["meavrer",588,"final","sonorant","no"]); push(@speech,["mishkafayim",588,"penult","sonorant","no"]); push(@speech,["mitriya",588,"final","none","no"]); push(@speech,["mixnasayim",588,"penult","sonorant","no"]); push(@speech,["mixnasayim",588,"penult","sonorant","no"]); push(@speech,["motsets",588,"final","voiceless","no"]); push(@speech,["namer",588,"final","sonorant","no"]); push(@speech,["naxash",588,"final","voiceless","no"]); push(@speech,["notsa",588,"final","none","no"]); push(@speech,["or",588,"mono","sonorant","none"]); push(@speech,["oto",588,"penult","none","none"]); push(@speech,["oto",588,"penult","none","none"]); push(@speech,["ozen",588,"penult","sonorant","none"]); push(@speech,["pazel",588,"penult","sonorant","no"]); push(@speech,["pe",588,"mono","none","no"]); push(@speech,["perax",588,"penult","voiceless","no"]); push(@speech,["pil",588,"mono","sonorant","no"]); push(@speech,["pilpel",588,"penult","sonorant","no"]); push(@speech,["pilpilon",588,"final","sonorant","no"]); push(@speech,["pilpilon",588,"final","sonorant","no"]); push(@speech,["praxim",588,"final","sonorant","yes"]); push(@speech,["raglayim",588,"penult","sonorant","no"]); push(@speech,["ratuv",588,"final","voiced","no"]); push(@speech,["roni",588,"penult","none","no"]); push(@speech,["sapa",588,"final","none","no"]); push(@speech,["seara",588,"final","none","no"]); push(@speech,["sefer",588,"penult","sonorant","no"]); push(@speech,["shaxar",588,"penult","sonorant","no"]); push(@speech,["shinayim",588,"penult","sonorant","no"]); push(@speech,["simla",588,"final","none","no"]); push(@speech,["snai",588,"final","none","yes"]); push(@speech,["spageti",588,"penult","none","no"]); push(@speech,["sulam",588,"final","sonorant","no"]); push(@speech,["sus",588,"mono","voiceless","no"]); push(@speech,["susi",588,"final","none","no"]); push(@speech,["susi",588,"final","none","no"]); push(@speech,["susim",588,"final","sonorant","no"]); push(@speech,["tanin",588,"final","sonorant","no"]); push(@speech,["tapuax",588,"penult","voiceless","no"]); push(@speech,["tapuz",588,"final","voiced","no"]); push(@speech,["tarnegol",588,"final","sonorant","no"]); push(@speech,["tarnegol",588,"final","sonorant","no"]); push(@speech,["tarnegolet",588,"penult","voiceless","no"]); push(@speech,["tinok",588,"final","voiceless","no"]); push(@speech,["traktor",588,"penult","sonorant","yes"]); push(@speech,["tships",588,"mono","voiceless","no"]); push(@speech,["tsipor",588,"final","sonorant","no"]); push(@speech,["tsipor",588,"final","sonorant","no"]); push(@speech,["tuki",588,"penult","none","no"]); push(@speech,["tut",588,"mono","voiceless","no"]); push(@speech,["xatul",588,"final","sonorant","no"]); push(@speech,["xayot",588,"final","voiceless","no"]); push(@speech,["xayot",588,"final","voiceless","no"]); push(@speech,["xor",588,"mono","sonorant","no"]); push(@speech,["yad",588,"mono","voiced","no"]); push(@speech,["yadayim",588,"penult","sonorant","no"]); push(@speech,["yalda",588,"final","none","no"]); push(@speech,["yarok",588,"final","voiceless","no"]); push(@speech,["yeled",588,"penult","voiced","no"]); push(@speech,["zebra",588,"penult","none","no"]); push(@speech,["zvuv",588,"mono","voiced","yes"]); # randomize the targets to make sure there is stuff to avoid early on @speech = shuffle(@speech); # takes a list of violation vectors, returns the list of the most harmonic ones (i.e. doesn't presuppose a single winner) sub findWinner { my $harmonyMatrix = shift; my @harmonyMatrix = @{$harmonyMatrix}; my @winners = (0); for (my $i=0; $i<@harmonyMatrix; $i++) { my $harmony = isMoreHarmonic($harmonyMatrix[$winners[0]],$harmonyMatrix[$i]); if ($harmony == 1) { @winners = ($i); } else { push(@winners,$i) if ($harmony == 0 and $i!=0); } } return @winners; } # takes a pair of violation vectors, sees which one is more harmonic sub isMoreHarmonic { my $vector1 = shift; my $vector2 = shift; my @vector1 = @{$vector1}; my @vector2 = @{$vector2}; my $moreHarmonic = 0; for(my $i=0; $i < @vector1 ; $i++) { if ($vector1[$i] < $vector2[$i]) { $moreHarmonic = -1 ; last; } if ($vector1[$i] > $vector2[$i]) { $moreHarmonic = 1 ; last; } } return $moreHarmonic; } # prints the names of the constraints in an array of references to constraints sub printGrammar { my $gram = shift; my @gram = @{$gram}; $gram = ""; for (@gram) { my $name = $_->("",""," "); $name =~ s/^.//; $gram .= $name . " > "; } $gram =~ s/ \> $//; return $gram; } # the constraint *SonorantCoda. # the name of the constraint is composed of "m" for "markedness" plus the actual name my $SonCoda = sub { my $inputForm = shift ; my $outputForm = shift; my $name = shift; return "mSonCoda" if ($name); my $violations = 0; $outputForm =~ /(.)$/; $violations++ if ($1 =~ /[lmnryw]/); return $violations; }; my $VoicedCoda = sub { my $inputForm = shift ; my $outputForm = shift; my $name = shift; return "mVoicedCoda" if ($name); my $violations = 0; $outputForm =~ /(.)$/; $violations++ if ($1 =~ /[bdgvzj]/); return $violations; }; # this constraint just has a list of SR's targets that have a complex onset, # because the targets are not in IPA (e.g. "sh", "ts" are single segments) my $ComplexOns = sub { my $inputForm = shift ; my $outputForm = shift; my $name = shift; return "mComplexOns" if ($name); my $violations = 0; $violations++ if ($outputForm =~ /brexa|dvora|flamingo|glida|kfits|klemantina|ktana|kvish|pkak|praxim|shlulit|shmone|shtayim|snai|tfilayla|traktor|tsfardea|tsvi|zvuv|zvuvim/); return $violations; }; # this constraint demands input-output identity my $F = sub { my $inputForm = shift ; my $outputForm = shift; my $name = shift; return "fF" if ($name); my $violations = 0; $violations++ if (($outputForm ne $inputForm) and ($outputForm ne "0")); return $violations; }; # "0" stands for the null parse my $MParse = sub { my $inputForm = shift ; my $outputForm = shift; my $name = shift; return "pMParse" if ($name); my $violations = 0; $violations++ if ($outputForm eq "0"); return $violations; }; # the list of universal constraints - doesn't change! my @CON = ($MParse,$F,$SonCoda,$ComplexOns); # the grammars that the learner will go through - will change over time my @grammar = ($MParse,$F,$SonCoda,$ComplexOns); my %cache; # stores the learner's errors my @support; # stores ERC's (ranking arguments) my %lexicon; # the learner's types are stored here # use the support to learn a new grammar sub updateGrammar { # new grammar. starts empty, will be filled with constraints as they are installed my @newGrammar; # new support will get gradually emptied out as constraints are installed; the actual support only grows my @newSupport = @support; print "\n\n old grammar: ". printGrammar(\@grammar) . "\n"; my $repeat = 1; # this is how I do "recursion" :-) SUP: while($repeat) { # by default: markedness >> faithfullness >> mparse my @mConstraints; my @fConstraints; my @pConstraints; # collect constraints that prefer no losers CONS: for (my $i=0; $i<@CON; $i++) { #find the CON constraint in @grammar #skip if not found (presumably already installed) my $gramPos = -1; for (my $j=0; $j<@grammar; $j++) { if ($grammar[$j] and $CON[$i] == $grammar[$j]) { $gramPos = $j; } } if ($gramPos == -1) { next CONS } my $name = $CON[$i]->(undef,undef," "); my $kind = substr($name,0,1); die unless ($kind); my $prefNoLosers = 1; my $prefWinners = 0; for my $erc (@newSupport) { my @ERC = split(/ /,$erc); $prefNoLosers = 0 if ($ERC[$i] eq "L"); $prefWinners++ if ($ERC[$i] eq "W"); } if ($prefNoLosers) { push(@mConstraints,[$i,$prefWinners]) if ($kind eq "m"); push(@fConstraints,[$i,$prefWinners]) if ($kind eq "f" and $prefWinners); push(@pConstraints,[$i,$prefWinners]) if ($kind eq "p" and $prefWinners); } } # no. of constraints to install my $toInstall = scalar(@mConstraints) + scalar(@fConstraints) + scalar(@pConstraints); # the index of the one chosen for installation my $install =-1; # prefer markedness, then faithfulness, then mparse if (@mConstraints) { $install = ${$mConstraints[0]}[0]; } else { if (@fConstraints) { # which F or MParse constraint frees more markedness? # what should really happen here is that each F and MParse # are checked for how many Markedness constraints would free. # instead, I am being lazy and just counting W's my @conCandidates = (@fConstraints,@pConstraints); my @maxFree = (); # the list of most W havers my $maxFreeScore = 0; for my $concan (@conCandidates) { my $prefW = ${$concan}[1]; if ($prefW == $maxFreeScore) { push(@maxFree, ${$concan}[0]); }; if ($prefW > $maxFreeScore) { @maxFree = (${$concan}[0]); $maxFreeScore=$prefW; }; } die unless (@maxFree); # here I am just taking the first of the constraints that have # the most W's. This is only okay because F went into @conCandidates # in front of MParse, so this makes sure to prefer F if there is more # then one kind to choose from. $install = $maxFree[0]; } else { if (@pConstraints) { # no M or F to install, so install MParse $install = ${$pConstraints[0]}[0]; } else { die "Didn't find any constraints to install!"; } } } # install! #find the CON constraint in @grammar my $gramPos = -1; for (my $j=0; $j<@grammar; $j++) { if ($grammar[$j] and $CON[$install] == $grammar[$j]) { $gramPos = $j; } } if ($gramPos == -1) { die "OMG Can't find this stupid constraint"; } # add to the new grammar push(@newGrammar, splice (@grammar, $gramPos, 1, "")); # remove the ERC's this constraint accounts for (i.e. has W) for (my $erc=0; $erc<@newSupport; $erc++) { my @ERC = split(/ /,$newSupport[$erc]); if ($ERC[$install] eq "W") { splice(@newSupport,$erc,1); $erc--; } } # if the support is not empty, or there are more installable constraints, repeat $repeat=0 if (@newSupport<1 and $toInstall<2); } # add any remaining constraints at the end, again m >> f >> mparse my @mConstraints; my @fConstraints; my @pConstraints; for my $cons (@grammar) { if ($cons) { my $name = $cons->(undef,undef," "); my $kind = substr($name,0,1); push(@mConstraints,$cons) if ($kind eq "m"); push(@fConstraints,$cons) if ($kind eq "f"); push(@pConstraints,$cons) if ($kind eq "p"); } } push(@newGrammar,@mConstraints); push(@newGrammar,@fConstraints); push(@newGrammar,@pConstraints); print " new grammar: ". printGrammar(\@newGrammar) . "\n Support: " . join("\n ",@support) . "\n\n"; @grammar = @newGrammar; } # start by arranging the constraints updateGrammar(); open (OUTPUT, ">" . "simulation.csv") or die "Can't open output file $!"; print OUTPUT '"pOnsetSimple","pOnsetComplex","pCodaUnmarked","pCodaSonorant","tOnsetSimple","tOnsetComplex","tCodaUnmarked","tCodaSonorant"' . "\n"; # now go over the words to say for my $word (@speech) { # add the current word to lexicon if it isn't already there my @item = @{$word}; $lexicon{$item[0]} = [$item[0],$item[2],$item[4]]; # GEN - make candidates my $input = $item[0]; my @candidates; $candidates[0] = $item[0]; # the faithful candidate $candidates[1] = "0"; # the null parse # make a guess at an unfaithful candidate if ($SonCoda->("",$item[0]) or $VoicedCoda->("",$item[0])) { $item[0] =~ /^(.+).$/; $candidates[2] = $1; } if ($ComplexOns->("",$item[0])) { $item[0] =~ /^(b|sh|d|z|p|ts|t|f|s|k|g).(.+)$/; $candidates[2] = $1 . $2; if ($SonCoda->("",$candidates[2])) { $candidates[2] =~ /^(.+).$/; $candidates[3] = $1; } } # EVAL - makes violation vectors for the candidate set my @harmony; for (my $i=0; $i<@candidates; $i++) { my @violationVector = (); for (my $j=0; $j<@grammar; $j++) { push(@violationVector, $grammar[$j]->($input,$candidates[$i])); } push(@harmony,\@violationVector); } # choose a winner my $output = ""; my @winners = findWinner(\@harmony); if (@winners != 1) { # can't deal with multiple winners at the moment die "OMG what happened can't find a winner"; } else { # who is the winner? if($candidates[$winners[0]] eq $input) { $output = "0 $input $candidates[$winners[0]]"; # 0 = faithful } else { # the winner is unfaithful = error made # make a winner-loser pair, record it in the cache my @adultVV = @{$harmony[0]}; my @childVV = @{$harmony[$winners[0]]}; # tempERC has the constraints in the same order as @grammar, so we need to # shuffle into the @CON order to keep them organized my @tempERC; for (my $i=0; $i<@adultVV; $i++) { push(@tempERC,"L") if ($adultVV[$i]> $childVV[$i]); push(@tempERC,"W") if ($adultVV[$i]< $childVV[$i]); push(@tempERC,"e") if ($adultVV[$i]==$childVV[$i]); } my @ERC; for my $c (@CON) { for (my $g=0; $g<@grammar; $g++) { if ($c==$grammar[$g]) { push(@ERC,$tempERC[$g]); } } } if (@ERC<@CON) { die "OMG Where are my constraints?!?!?!"; } $cache{"@ERC"}++; if($candidates[$winners[0]] eq "0") { $output = "1 $input $candidates[$winners[0]]"; # 1 = avoided } else { $output = "2 $input $candidates[$winners[0]]" ; # 2 = unfaithful } } } # check the cache to see if the number of errors made justifies learning for my $erc (keys %cache) { if(($erc =~ /L e$/ and $cache{$erc}>50) or ($erc =~ /L$/ and $cache{$erc}>7)) { # more than ten items gave evidence for a learning, so go for it # move the error to the Support, clear the cache push(@support,$erc); $cache{$erc} = 0; updateGrammar(); } } my %outputs; $outputs{"production_codas"} = [0,0]; # non-sonorant / sonorant $outputs{"production_onsets"} = [0,0]; # simple / complex $outputs{"attempt_codas"} = [0,0]; # simple / complex $outputs{"attempt_onsets"} = [0,0]; # simple / complex for my $lexicalItem (keys %lexicon) { my $input = ${$lexicon{$lexicalItem}}[0]; my @candidates; $candidates[0] = $input; # the faithful candidate $candidates[1] = "0"; # the null parse # make a guess at an unfaithful candidate if ($SonCoda->("",$input)) { $input =~ /^(.+).$/; $candidates[2] = $1; } if ($ComplexOns->("",$input)) { $input =~ /^(b|sh|d|z|p|ts|t|f|s|k|g).(.+)$/; $candidates[2] = $1 . $2; if ($SonCoda->("",$candidates[2])) { $candidates[2] =~ /^(.+).$/; $candidates[3] = $1; } } # EVAL - makes violation vectors for the candidate set my @harmony; for (my $i=0; $i<@candidates; $i++) { my @violationVector = (); for (my $j=0; $j<@grammar; $j++) { push(@violationVector, $grammar[$j]->($input,$candidates[$i])); } push(@harmony,\@violationVector); } # choose a winner my @winners = findWinner(\@harmony); if (@winners != 1) { # can't deal with multiple winners at the moment die "OMG what happened can't find a winner"; } ${$outputs{"production_codas"}}[$SonCoda->("",$candidates[$winners[0]])]++; ${$outputs{"production_onsets"}}[$ComplexOns->("",$candidates[$winners[0]])]++; ${$outputs{"attempt_codas"}}[$SonCoda->("",$input)]++ unless ($candidates[$winners[0]] eq "0"); ${$outputs{"attempt_onsets"}}[$ComplexOns->("",$input)]++ unless ($candidates[$winners[0]] eq "0"); } print OUTPUT "\"${$outputs{production_onsets}}[0]\",\"${$outputs{production_onsets}}[1]\",\"${$outputs{production_codas}}[0]\",\"${$outputs{production_codas}}[1]\","; print OUTPUT "\"${$outputs{attempt_onsets}}[0]\",\"${$outputs{attempt_onsets}}[1]\",\"${$outputs{attempt_codas}}[0]\",\"${$outputs{attempt_codas}}[1]\"\n"; } close(OUTPUT) or die "OMG Can't close output file $!";