code: def _constraint_compare(
      self,
      truth_cons,
      gen_cons,
      slot_appear_num=None,
      slot_correct_num=None,
  ):
      tp, fp, fn = 0, 0, 0
      false_slot = []
      for slot in gen_cons:
          v_gen = gen_cons[slot]
          if slot in truth_cons and self.value_similar(
              v_gen, truth_cons[slot]
          ):  # v_truth = truth_cons[slot]
              tp += 1
              if slot_correct_num is not None:
                  slot_correct_num[slot] = (
                      1
                      if not slot_correct_num.get(slot)
                      else slot_correct_num.get(slot) + 1
                  )
          else:
              fp += 1
              false_slot.append(slot)
      for slot in truth_cons:
          v_truth = truth_cons[slot]
          if slot_appear_num is not None:
              slot_appear_num[slot] = (
                  1
                  if not slot_appear_num.get(slot)
                  else slot_appear_num.get(slot) + 1
              )
          if slot not in gen_cons or not self.value_similar(
              v_truth, gen_cons[slot]
          ):
              fn += 1
              false_slot.append(slot)
      acc = len(self.all_info_slot) - fp - fn
      return tp, fp, fn, acc, list(set(false_slot))
  
imports: import math, logging, copy, json
  from collections import Counter, OrderedDict
  from nltk.util import ngrams
  from .None import ontology
  from .clean_dataset import clean_slot_values
label_desc: Use image node_id 11 for calling the MultiWozEvaluator obj's underlying member method code with example usage: obj._constraint_compare(truth_cons, gen_cons, slot_appear_num, slot_correct_num) and returns: tp,  fp,  fn,  acc,  list