packages feed

huff-0.1.0.0: src/Huff/Compile/Problem.hs

{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}

module Huff.Compile.Problem (
    genProblemOperators,
    addNegativePreconditions,
  ) where

import Huff.Compile.AST

import qualified Data.Set as Set


-- | Generate operators from the problem description.  This corresponds to the
-- "Initial Conditions and Goals" section.
genProblemOperators :: Problem -> (Problem, Operator a)
genProblemOperators Problem { .. } = (prob, goalOp)
  where

  goalAtom = LAtom (Atom "$goal-achieved" [])

  prob = Problem { probGoal = TLit goalAtom
                 , ..
                 }

  goalOp = Operator { opName    = "$goal-operator"
                    , opDerived = True
                    , opParams  = []
                    , opPrecond = probGoal
                    , opEffects = ELit goalAtom
                    , opVal     = Nothing
                    }


-- | Modify the initial state to include assumptions about negative
-- preconditions.
addNegativePreconditions :: Set.Set Atom -> Problem -> Problem
addNegativePreconditions negs Problem { .. } =
  Problem { probInit = initNegs negs probInit, .. }


-- | Generate the initial state, given the set of atoms that show up as negative
-- preconditions, and the existing initial state.
initNegs :: Set.Set Atom -> [Literal] -> [Literal]

-- pass non-negative atoms through, that are mentioned in the initial state
initNegs negs (LAtom a : ls)
  | a `Set.member` negs = LAtom a : initNegs (Set.delete a negs) ls
  | otherwise           = LAtom a : initNegs               negs  ls

-- we can safely remove negative initial conditions that aren't used as negative
-- preconditions
initNegs negs (LNot a : ls)
  | a `Set.member` negs = LAtom (negAtom a) : initNegs (Set.delete a negs) ls
  | otherwise           =                     initNegs (Set.delete a negs) ls

-- the remaining set of atoms are depended on as negative preconditions, but
-- unset in the initial state.  their negative variants are set.
initNegs negs [] =
  [ LAtom (negAtom a) | a <- Set.toList negs ]