<taskModel about="urn:cetask.wpi.edu:examples:Inquiry" xmlns="http://ce.org/cea-2018">

 <!-- 
      Mike Sao Pedro
      mikesp@wpi.edu
      
      Main task: perform all parts of the scientific method.
      
      Here, I envision perhaps noticing what window the user clicks
      (hypoth spec, experiment spec, conclusion spec) in order to do
      the decomposition. 
  -->
  <task id="PerformExperiment">
  

  	<input name="experiment" type="Experiment"/>
  	<input name="trial" type="number"/>
    
  	<!-- 
  	   Have student perform all parts of the scientific method. 
  	   Here the student will be asked to fill in specific tests.
  	-->
  	<subtasks id="allScientificMethod">
  	
  	   <step name="formHypothesis" task="FormHypothesis"/>
  	   <step name="runExperiments" task="RunExperiments"/>
  	   <step name="formConclusions" task="FormConclusions"/>
  	    
  	   <!-- The experiments are geared towards the hypothesis selected -->
  	   <binding slot="$formHypothesis.simulation"
  	            value="$this.experiment.simulation"/>
  	     	   
  	   <binding slot="$runExperiments.hypothesis" 
  	            value="$formHypothesis.hypothesis"/>
  	   <binding slot="$formConclusions.table" 
  	            value="$runExperiments.table"/>
  	   <binding slot="$formConclusions.hypothesis"
  	            value="$formHypothesis.hypothesis"/>
  	</subtasks>
  </task>

  <task id="RunExperiments">
    <input name="hypothesis" type="Hypothesis"/>
    <output name="table" type="number"/>
  </task>
  
  <task id="FormConclusions">
    <input name="hypothesis" type="Hypothesis"/>
    <input name="table" type="number"/>
  </task>
  
  <!-- 
      Given a simulation specification, make a student fill in
      a hypothesis. Forming a hypothesis consists of seeing how
      and independent variable affects an outcome variable.
   -->
  <task id="FormHypothesis">
  	<input name="simulation" type="Simulation"/>
  	<output name="hypothesis" type="Hypothesis"/>

  	<subtasks id="fillHypothesisTemplate">
  	   <step name="independentVar" task="SelectIndependentVar" />
  	   <step name="comparator" task="SelectComparator" />
  	   <step name="outcomeVar" task="SelectOutcomeVar" />
  	   
  	   <!-- input bindings: indep/dep vars come from simulation def. -->
  	   <binding slot="$independentVar.choices" value="$this.simulation.independentVariables"/>
  	   <binding slot="$outcomeVar.choices" value="$this.simulation.outcomeVariables"/>
 
       <binding slot="$this.hypothesis" value="Hypothesis($independentVar.selection, $outcomeVar.selection, $comparator.selection)"/> 	   
  	</subtasks>
  	  	
  </task>
  
  <!-- Side effect: will fill in IndependentVariable for hypothesis -->
  <task id="SelectIndependentVar">
  	<input name="choices" type="VariableCollection"/>
  	<output name="selection" type="IndependentVariable"/>
  	
  	<postcondition>
  	  $this.selection != null;
  	  if($this.selection != null) { $this.selection != undefined; }
  	  contains($this.choices.vars, $this.selection);
  	</postcondition>
  	
  	<!-- 
  	   If user can't do the step for whatever reason, this script will do it.
  	   This enables the task to be done by the pedagogical agent instead of the user
  	   (maybe if it's in a demonstration mode) 
  	 -->
  	<script>
  	  $this.selection = random_selection($this.choices.vars);
  	</script>
  </task>
  
  <!-- Side effect: will fill in OutcomeVariable for hypothesis -->
  <task id="SelectOutcomeVar">
  	<input name="choices" type="VariableCollection"/>
  	<output name="selection" type="String"/>
  	
  	<postcondition>
  	  $this.selection != undefined;
  	  contains($this.choices.vars, $this.selection);
  	</postcondition>
  	
  	<script>
  	  $this.selection = random_selection($this.choices.vars);
  	</script>	
  </task>
  
  <!-- Side effect: will fill in Comparator for hypothesis -->
  <task id="SelectComparator">
  	<output name="selection" type="Variable"/>
  	
  	<postcondition>
  	  $this.selection != undefined;
  	  contains(comparators, $this.selection);
  	</postcondition>
  	
  	<script>
  	  $this.selection = random_selection(comparators);
  	</script>
  	
  </task>
  
  
  <!-- Define all the elements associated with the system -->
  <script init="true">
  
    var IndependentVariableNames = ["leftRampAngle", "rightRampAngle", "ballStartPosition", "leftRampFriction", "rightRampFriction"];
    var OutcomeVariableNames = ["distance", "time"];
    var comparators = ["increases", "decreases", "no_effect"];    

   function IndependentVariable (name, value) 
    {
      this.name = name;
      this.value = value;
    }
    
    function OutcomeVariable (name, value) 
    {
      this.name = name;
      this.value = value;
    }
    
    function Simulation (indepVars, outcomeVars)
    {
      this.independentVariables = indepVars;
      this.outcomeVariables = outcomeVars;
    }
    
    function Hypothesis (indepVar, outcomeVar, comp)
    {
      this.comparator = comp;
      this.independentVariable = indepVar;
      this.outcomeVariable = outcomeVar;
    }
    
    function Experiment (sim)
    {
      this.simulation = sim;
    }
    
    function VariableCollection(vs)
    {
      this.vars = vs;
    }
        
    // +list: list of elements,
    // +elt: element potentially in list
    //
    // return: true if elt in list, false otherwise.
    function contains (list, elt) 
    {
       //print(list)
       //print(elt)
       if(elt == undefined) return false;
       
       return list.indexOf(elt) != -1;
    }

    // return: random element in the list
    function random_selection(list)
    {
       return list[(Math.floor( Math.random() * (list.length)) % list.length)];
    }
    
    // --- TEST OBJECTS ---
    var leftRampAngle = new IndependentVariable("leftRampAngle", 0.0);
    var rightRampAngle = new IndependentVariable("rightRampAngle", 0.0);
    var ballStartPosition = new IndependentVariable("ballStartPosition", 0.0);
    var leftRampSurfaceType = new IndependentVariable("leftRampSurfaceType", 0.0);
    var rightRampSurfaceType = new IndependentVariable("rightRampSurfaceType", 0.0);
    var ballType = new IndependentVariable("ballType", "golf");
    var distance = new OutcomeVariable("distance", 0.0);
    var time = new OutcomeVariable("time", 0.0);
    
    var indepVars = 
       new VariableCollection([leftRampAngle, rightRampAngle, ballStartPosition, 
                               leftRampSurfaceType, rightRampSurfaceType, ballType]);
    
    var outcomeVars = new VariableCollection([distance, time]);
                      
    var sim = new Simulation(indepVars, outcomeVars);
    
    var exp = new Experiment(sim);
   
  </script>

</taskModel>