All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.sv.dialog_state_tracking.Utils Maven / Gradle / Ivy

Go to download

A library that allows rapid prototyping of dialog systems (language understanding, discourse modelling, dialog management, language generation).

There is a newer version: 0.7.0
Show newest version
package edu.cmu.sv.dialog_state_tracking;

import edu.cmu.sv.database.Ontology;
import edu.cmu.sv.domain.ontology.Noun;
import edu.cmu.sv.domain.ontology.Role;
import edu.cmu.sv.domain.ontology.Verb;
import edu.cmu.sv.semantics.SemanticsModel;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.json.simple.JSONObject;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by David Cohen on 10/17/14.
 */
public class Utils {

    public static double discourseUnitContextProbability(DialogState dialogState,
                                                         DiscourseUnit predecessor){
        return discourseUnitRecency(dialogState, predecessor) *
                Math.pow(.1, numberOfLinksRespondingToDiscourseUnit(predecessor, dialogState));
    }

    public static double discourseUnitRecency(DialogState dialogState, DiscourseUnit predecessor){
        return Math.pow(.1, numberOfIntermediateDiscourseUnitsBySpeaker(predecessor, dialogState, "system")) *
                Math.pow(.1, numberOfIntermediateDiscourseUnitsBySpeaker(predecessor, dialogState, "user"));
    }

    public static int numberOfIntermediateDiscourseUnitsBySpeaker(DiscourseUnit predecessorDu,
                                                           DialogState dialogState, String speaker){
        int ans = 0;
        for (String discourseUnitIdentifier : dialogState.getDiscourseUnitHypothesisMap().keySet()){
            DiscourseUnit otherPredecessor = dialogState.getDiscourseUnitHypothesisMap().get(discourseUnitIdentifier);
            if (otherPredecessor==predecessorDu)
                continue;
            if (otherPredecessor.getInitiator().equals(speaker) &&
                    otherPredecessor.getMostRecentContributionTime() > predecessorDu.getMostRecentContributionTime())
                ans += 1;
        }
        return ans;
    }

    public static int numberOfLinksRespondingToDiscourseUnit(DiscourseUnit contextDu,
                                                             DialogState dialogState){
        int ans = 0;
        for (DialogState.ArgumentationLink link : dialogState.getArgumentationLinks()){
            if (dialogState.getDiscourseUnitHypothesisMap().get(link.getPredecessor())==contextDu)
                ans += 1;
        }
        return ans;
    }

    /*
    * return Triple
    * */
    public static Triple, Set, Set> resolutionInformation(DiscourseUnit discourseUnit) {

        Set slotPathsToResolve = new HashSet<>();
        SemanticsModel spokenByThem = discourseUnit.getSpokenByThem();
        SemanticsModel currentGroundedInterpretation = discourseUnit.getGroundInterpretation();
        String verb = (String) spokenByThem.newGetSlotPathFiller("verb.class");
        Verb verbClass = Ontology.verbNameMap.get(verb);
        Set requiredGroundedRoles = verbClass.getRequiredGroundedRoles();
        Set requiredDescriptions = verbClass.getRequiredDescriptions();

        for (String path : spokenByThem.getAllInternalNodePaths().stream().
                sorted((x, y) -> Integer.compare(x.length(), y.length())).collect(Collectors.toList())) {
            if (slotPathsToResolve.contains(path)
                    || Arrays.asList("", "dialogAct", "verb").contains(path)
                    || slotPathsToResolve.stream().anyMatch(x -> path.startsWith(x)))
                continue;
            if (!Ontology.nounNameMap.containsKey(((JSONObject) spokenByThem.newGetSlotPathFiller(path)).get("class")))
                continue;
            if (requiredDescriptions.stream().map(x -> "verb." + x.name).collect(Collectors.toList()).contains(path))
                continue;
            slotPathsToResolve.add(path);
        }


        // collect the paths that have already been resolved
        Set alreadyResolvedPaths;
        if (currentGroundedInterpretation != null) {
            alreadyResolvedPaths = slotPathsToResolve.stream().filter(x -> currentGroundedInterpretation.newGetSlotPathFiller(x) != null).collect(Collectors.toSet());
        } else {
            alreadyResolvedPaths = new HashSet<>();
        }
        slotPathsToResolve.removeAll(alreadyResolvedPaths);

        //todo: add roles missing from prepositions
        Set pathsToInfer = requiredGroundedRoles.stream().
                map(x -> "verb." + x.name).
                filter(x -> !alreadyResolvedPaths.contains(x)).
                filter(x -> !slotPathsToResolve.contains(x)).
                collect(Collectors.toSet());

        return new ImmutableTriple<>(slotPathsToResolve, pathsToInfer, alreadyResolvedPaths);
    }


    public static Set filterSlotPathsByRangeClass(Set slotPaths, String rangeClassName){
        Set ans = new HashSet<>();
        for (String slotPath : slotPaths){
            String lastRoleName = slotPath.split("\\.")[slotPath.split("\\.").length-1];
            if (!Ontology.roleNameMap.containsKey(lastRoleName))
                continue;
            if (!Ontology.nounNameMap.containsKey(rangeClassName))
                continue;
            Role roleClass = Ontology.roleNameMap.get(lastRoleName);
            Noun contentClass = Ontology.nounNameMap.get(rangeClassName);
            Set range = roleClass.getRange();
            for (Object rangeCls : range) {
                if (rangeCls instanceof Noun && (Ontology.nounInherits((Noun) rangeCls, contentClass) ||
                        Ontology.nounInherits(contentClass, (Noun) rangeCls))) {
                    ans.add(slotPath);
                    break;
                }
            }
        }
        return ans;
    }

    /*
    * Update the discourse unit by bringing it back to a grounded state from a non-grounded state
    * Leave the resolved meanings from the initiator alone
    * */
    public static void returnToGround(DiscourseUnit predecessor,
                                      SemanticsModel newSpokenByInitiator,
                                      long timeStamp){
        if (predecessor.initiator.equals("user")){
            predecessor.timeOfLastActByThem = timeStamp;
            predecessor.spokenByThem = newSpokenByInitiator;
            predecessor.spokenByMe = null;
            predecessor.groundTruth = null;
            predecessor.timeOfLastActByMe = null;
        } else { // if predecessor.initiator.equals("system")
            predecessor.timeOfLastActByThem = null;
            predecessor.spokenByThem = null;
            predecessor.groundInterpretation = null;
            predecessor.spokenByMe = newSpokenByInitiator;
            predecessor.timeOfLastActByMe = timeStamp;
        }
    }

    /*
    * Update the discourse unit by un-grounding it
    * */
    public static void unground(DiscourseUnit predecessor,
                                SemanticsModel newSpokenByOther,
                                SemanticsModel groundedByOther,
                                long timeStamp){
        if (predecessor.initiator.equals("user")){
            predecessor.spokenByMe = newSpokenByOther;
            predecessor.groundTruth = groundedByOther;
            predecessor.timeOfLastActByMe = timeStamp;
        } else { // if predecessor.initiator.equals("system")
            predecessor.spokenByThem = newSpokenByOther;
            predecessor.groundInterpretation = groundedByOther;
            predecessor.timeOfLastActByThem = timeStamp;
        }
    }


}