diff --git a/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/Rules.scala b/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/Rules.scala index 85b8f51..44c9fac 100644 --- a/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/Rules.scala +++ b/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/Rules.scala @@ -171,6 +171,7 @@ trait Rules extends DimRules { ) private def intersectToken(options: Options, td1: TimeData, td2: TimeData): Option[Token] = { + println(td1, td2) // 破除(y-m)-d和y-(m-d)均构造出来的问题 if (td1.hint == YearMonth && td2.hint == DayOnly) None // 固定顺序,避免(y-m)-(d H-M-S) 以及(y)-(m-d H-M-S)出现 @@ -221,8 +222,7 @@ trait Rules extends DimRules { name = "intersect: ", // "一日"单独是latent,但是可以参与组合 pattern = List(isNotLatent.predicate, "的".regex, or(or(isNotLatent, isLatent0oClockOfDay), isADayOfMonth).predicate), - prod = { - case (options, (t1@Token(Time, td1: TimeData)) :: _ :: (t2@Token(Time, td2: TimeData)) :: _) + prod = {case (options, (t1@Token(Time, td1: TimeData)) :: _ :: (t2@Token(Time, td2: TimeData)) :: _) if td1.timeGrain > td2.timeGrain || // 上午的8-9点 td1.timeGrain == td2.timeGrain && td1.timeGrain == Hour && isAPartOfDay(t1) && !isAPartOfDay(t2) => diff --git a/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/date/Rules.scala b/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/date/Rules.scala index 8eca993..3ed5400 100644 --- a/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/date/Rules.scala +++ b/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/date/Rules.scala @@ -336,6 +336,37 @@ trait Rules extends DimRules { } }) + def intersectProd(td1: TimeData, td2: TimeData) : Option[Token] = { + // 破除(y-m)-d和y-(m-d)均构造出来的问题 + if (td1.hint == YearMonth && td2.hint == Hint.DayOnly) None + // 固定顺序,避免(y-m)-(d H-M-S) 以及(y)-(m-d H-M-S)出现 + else if (td1.timeGrain > Day && td2.timeGrain < Day) None + // 避免多路解析 [2017年三月2号早上][10点半] 和 [2017年三月2号][早上10点半] + // else if (td1.timeGrain == Day && td2.timeGrain == Hour) None + else { + // 十月不能与十月一日求交 + val isAlreadySet = td2.timePred match { + case tdp: TimeDatePredicate => + td1.timeGrain match { + case Year => tdp.year.nonEmpty + case Month => tdp.month.nonEmpty + case Day => tdp.dayOfMonth.nonEmpty + case _ => true + } + case _ => false + } + if (isAlreadySet) None + else { + val hint = + if (td1.timeGrain == Year && td2.hint == Hint.MonthOnly) YearMonth + else NoHint + for (td <- intersect(td1, td2)) yield { + Token(Date, td.copy(hint = hint)) + } + } + } + } + val ruleIntersect = Rule( name = "dates: intersect", @@ -347,34 +378,7 @@ trait Rules extends DimRules { prod = tokens { case Token(Date, td1: TimeData) :: Token(Date, td2: TimeData) :: _ if td1.timeGrain > td2.timeGrain => - // 破除(y-m)-d和y-(m-d)均构造出来的问题 - if (td1.hint == YearMonth && td2.hint == Hint.DayOnly) None - // 固定顺序,避免(y-m)-(d H-M-S) 以及(y)-(m-d H-M-S)出现 - else if (td1.timeGrain > Day && td2.timeGrain < Day) None - // 避免多路解析 [2017年三月2号早上][10点半] 和 [2017年三月2号][早上10点半] - // else if (td1.timeGrain == Day && td2.timeGrain == Hour) None - else { - // 十月不能与十月一日求交 - val isAlreadySet = td2.timePred match { - case tdp: TimeDatePredicate => - td1.timeGrain match { - case Year => tdp.year.nonEmpty - case Month => tdp.month.nonEmpty - case Day => tdp.dayOfMonth.nonEmpty - case _ => true - } - case _ => false - } - if (isAlreadySet) None - else { - val hint = - if (td1.timeGrain == Year && td2.hint == Hint.MonthOnly) YearMonth - else NoHint - for (td <- intersect(td1, td2)) yield { - Token(Date, td.copy(hint = hint)) - } - } - } + intersectProd(td1, td2) } ) @@ -389,15 +393,7 @@ trait Rules extends DimRules { prod = tokens { case Token(Date, td1: TimeData) :: _ :: Token(Date, td2: TimeData) :: _ if td1.timeGrain > td2.timeGrain => - if (td1.timeGrain > Day && td2.timeGrain < Day) None - else { - val hint = - if (td1.timeGrain == Year && td2.hint == Hint.MonthOnly) YearMonth - else NoHint - for (td <- intersect(td1, td2)) yield { - Token(Date, td.copy(hint = hint)) - } - } + intersectProd(td1, td2) } ) diff --git a/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/rule/Times.scala b/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/rule/Times.scala index 0ae0326..fb3ffd4 100644 --- a/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/rule/Times.scala +++ b/duckling-fork-chinese/core/src/main/scala/com/xiaomi/duckling/dimension/time/rule/Times.scala @@ -108,6 +108,17 @@ object Times { } ) + val ruleDimTimePartOfDay1 = Rule( + name = "", + pattern = List(isADayOfMonth.predicate, "的".regex, and(isAPartOfDay, isNotLatent).predicate), + prod = tokens { + case Token(Time, td1: TimeData) :: _ :: Token(Time, td2: TimeData) :: _ => + for (td <- intersect(td1, td2)) yield { + tt(td.copy(form = td2.form, hint = Hint.PartOfDayAtLast)) + } + } + ) + val rulePartOfDayDimTime = Rule( name = " ", pattern = List(isAPartOfDay.predicate, isNotLatent.predicate), @@ -192,6 +203,7 @@ object Times { ruleTimeOfDayOClock, ruleIntegerLatentTimeOfDay, ruleDimTimePartOfDay, + ruleDimTimePartOfDay1, ruleHhmmssCN_TimeOfDay, // ruleRelativeMinutesAfterPastIntegerOClockOfDay, ruleRelativeMinutesAfterPastIntegerHourOfDay, diff --git a/duckling-fork-chinese/core/src/test/scala/com/xiaomi/duckling/dimension/time/FormTest.scala b/duckling-fork-chinese/core/src/test/scala/com/xiaomi/duckling/dimension/time/FormTest.scala index 0b909d8..c7ba334 100644 --- a/duckling-fork-chinese/core/src/test/scala/com/xiaomi/duckling/dimension/time/FormTest.scala +++ b/duckling-fork-chinese/core/src/test/scala/com/xiaomi/duckling/dimension/time/FormTest.scala @@ -10,6 +10,8 @@ class FormTest extends UnitSpec { describe("Form") { val cases = Table[String, Option[Form]](("query", "form") + , ("周五的上午", PartOfDay("上午")) + , ("周五上午", PartOfDay("上午")) , ("每个月五号的早上", PartOfDay("早上")) , ("23号8点", TimeOfDay(8, true)) , ("23号上午8点", TimeOfDay(8, false))