@@ -32,22 +32,23 @@ use crate::{
32
32
pub const MAPFEEDBACK_PREFIX : & str = "mapfeedback_metadata_" ;
33
33
34
34
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
35
- pub type AflMapFeedback < O , S , T > = MapFeedback < DifferentIsNovel , O , OrReducer , S , T > ;
35
+ pub type AflMapFeedback < O , S , T , A > = MapFeedback < DifferentIsNovel , O , OrReducer , S , T , A > ;
36
36
37
37
/// A [`MapFeedback`] that strives to maximize the map contents.
38
- pub type MaxMapFeedback < O , S , T > = MapFeedback < DifferentIsNovel , O , MaxReducer , S , T > ;
38
+ pub type MaxMapFeedback < O , S , T , A > = MapFeedback < DifferentIsNovel , O , MaxReducer , S , T , A > ;
39
39
/// A [`MapFeedback`] that strives to minimize the map contents.
40
- pub type MinMapFeedback < O , S , T > = MapFeedback < DifferentIsNovel , O , MinReducer , S , T > ;
40
+ pub type MinMapFeedback < O , S , T , A > = MapFeedback < DifferentIsNovel , O , MinReducer , S , T , A > ;
41
41
42
42
/// A [`MapFeedback`] that always returns `true` for `is_interesting`. Useful for tracing all executions.
43
- pub type AlwaysInterestingMapFeedback < O , S , T > = MapFeedback < AllIsNovel , O , NopReducer , S , T > ;
43
+ pub type AlwaysInterestingMapFeedback < O , S , T , A > = MapFeedback < AllIsNovel , O , NopReducer , S , T , A > ;
44
44
45
45
/// A [`MapFeedback`] that strives to maximize the map contents,
46
46
/// but only, if a value is larger than `pow2` of the previous.
47
- pub type MaxMapPow2Feedback < O , S , T > = MapFeedback < NextPow2IsNovel , O , MaxReducer , S , T > ;
47
+ pub type MaxMapPow2Feedback < O , S , T , A > = MapFeedback < NextPow2IsNovel , O , MaxReducer , S , T , A > ;
48
48
/// A [`MapFeedback`] that strives to maximize the map contents,
49
49
/// but only, if a value is larger than `pow2` of the previous.
50
- pub type MaxMapOneOrFilledFeedback < O , S , T > = MapFeedback < OneOrFilledIsNovel , O , MaxReducer , S , T > ;
50
+ pub type MaxMapOneOrFilledFeedback < O , S , T , A > =
51
+ MapFeedback < OneOrFilledIsNovel , O , MaxReducer , S , T , A > ;
51
52
52
53
/// A `Reducer` function is used to aggregate values for the novelty search
53
54
pub trait Reducer < T > : ' static
@@ -365,7 +366,7 @@ where
365
366
366
367
/// The most common AFL-like feedback type
367
368
#[ derive( Clone , Debug ) ]
368
- pub struct MapFeedback < N , O , R , S , T > {
369
+ pub struct MapFeedback < N , O , R , S , T , A > {
369
370
/// For tracking, always keep indexes and/or novelties, even if the map isn't considered `interesting`.
370
371
always_track : bool ,
371
372
/// New indexes observed in the last observation
@@ -377,24 +378,26 @@ pub struct MapFeedback<N, O, R, S, T> {
377
378
/// Name of the feedback as shown in the `UserStats`
378
379
stats_name : String ,
379
380
/// Phantom Data of Reducer
380
- phantom : PhantomData < ( N , O , R , S , T ) > ,
381
+ phantom : PhantomData < ( N , O , R , S , T , A ) > ,
381
382
}
382
383
383
- impl < N , O , R , S , T > UsesObserver < S > for MapFeedback < N , O , R , S , T >
384
+ impl < N , O , R , S , T , A > UsesObserver < S > for MapFeedback < N , O , R , S , T , A >
384
385
where
385
386
S : UsesInput ,
386
387
O : Observer < S > ,
388
+ A : AsRef < O > + Observer < S > ,
387
389
{
388
- type Observer = O ;
390
+ type Observer = A ;
389
391
}
390
392
391
- impl < N , O , R , S , T > Feedback < S > for MapFeedback < N , O , R , S , T >
393
+ impl < N , O , R , S , T , A > Feedback < S > for MapFeedback < N , O , R , S , T , A >
392
394
where
393
395
N : IsNovel < T > ,
394
- O : MapObserver < Entry = T > + for < ' it > AsIter < ' it , Item = T > + TrackingHinted ,
396
+ O : MapObserver < Entry = T > + for < ' it > AsIter < ' it , Item = T > ,
395
397
R : Reducer < T > ,
396
398
S : State + HasNamedMetadata ,
397
399
T : Default + Copy + Serialize + for < ' de > Deserialize < ' de > + PartialEq + Debug + ' static ,
400
+ A : AsRef < O > + TrackingHinted ,
398
401
{
399
402
fn init_state ( & mut self , state : & mut S ) -> Result < ( ) , Error > {
400
403
// Initialize `MapFeedbackMetadata` with an empty vector and add it to the state.
@@ -448,7 +451,10 @@ where
448
451
let meta = MapNoveltiesMetadata :: new ( novelties) ;
449
452
testcase. add_metadata ( meta) ;
450
453
}
451
- let observer = observers. match_name :: < O > ( & self . observer_name ) . unwrap ( ) ;
454
+ let observer = observers
455
+ . match_name :: < A > ( & self . observer_name )
456
+ . unwrap ( )
457
+ . as_ref ( ) ;
452
458
let initial = observer. initial ( ) ;
453
459
let map_state = state
454
460
. named_metadata_map_mut ( )
@@ -460,7 +466,7 @@ where
460
466
}
461
467
462
468
let history_map = map_state. history_map . as_mut_slice ( ) ;
463
- if O :: INDICES {
469
+ if A :: INDICES {
464
470
let mut indices = Vec :: new ( ) ;
465
471
466
472
for ( i, value) in observer
@@ -490,11 +496,12 @@ where
490
496
491
497
/// Specialize for the common coverage map size, maximization of u8s
492
498
#[ rustversion:: nightly]
493
- impl < O , S > Feedback < S > for MapFeedback < DifferentIsNovel , O , MaxReducer , S , u8 >
499
+ impl < O , S , A > Feedback < S > for MapFeedback < DifferentIsNovel , O , MaxReducer , S , u8 , A >
494
500
where
495
- O : MapObserver < Entry = u8 > + AsSlice < Entry = u8 > + TrackingHinted ,
501
+ O : MapObserver < Entry = u8 > + AsSlice < Entry = u8 > ,
496
502
for < ' it > O : AsIter < ' it , Item = u8 > ,
497
503
S : State + HasNamedMetadata ,
504
+ A : AsRef < O > + TrackingHinted ,
498
505
{
499
506
#[ allow( clippy:: wrong_self_convention) ]
500
507
#[ allow( clippy:: needless_range_loop) ]
@@ -515,7 +522,10 @@ where
515
522
516
523
let mut interesting = false ;
517
524
// TODO Replace with match_name_type when stable
518
- let observer = observers. match_name :: < O > ( & self . observer_name ) . unwrap ( ) ;
525
+ let observer = observers
526
+ . match_name :: < A > ( & self . observer_name )
527
+ . unwrap ( )
528
+ . as_ref ( ) ;
519
529
520
530
let map_state = state
521
531
. named_metadata_map_mut ( )
@@ -632,14 +642,14 @@ where
632
642
}
633
643
}
634
644
635
- impl < N , O , R , S , T > Named for MapFeedback < N , O , R , S , T > {
645
+ impl < N , O , R , S , T , A > Named for MapFeedback < N , O , R , S , T , A > {
636
646
#[ inline]
637
647
fn name ( & self ) -> & str {
638
648
self . name . as_str ( )
639
649
}
640
650
}
641
651
642
- impl < N , O , R , S , T > HasObserverName for MapFeedback < N , O , R , S , T >
652
+ impl < N , O , R , S , T , A > HasObserverName for MapFeedback < N , O , R , S , T , A >
643
653
where
644
654
T : PartialEq + Default + Copy + ' static + Serialize + DeserializeOwned + Debug ,
645
655
R : Reducer < T > ,
@@ -658,20 +668,22 @@ fn create_stats_name(name: &str) -> String {
658
668
name. to_lowercase ( )
659
669
}
660
670
661
- impl < N , O , R , S , T > MapFeedback < N , O , R , S , T >
671
+ impl < N , O , R , S , T , A > MapFeedback < N , O , R , S , T , A >
662
672
where
663
673
T : PartialEq + Default + Copy + ' static + Serialize + DeserializeOwned + Debug ,
664
674
R : Reducer < T > ,
665
- O : MapObserver < Entry = T > + TrackingHinted ,
675
+ O : MapObserver < Entry = T > ,
666
676
for < ' it > O : AsIter < ' it , Item = T > ,
667
677
N : IsNovel < T > ,
668
678
S : UsesInput + HasNamedMetadata ,
679
+ A : AsRef < O > + TrackingHinted ,
669
680
{
670
681
/// Create new `MapFeedback`
671
682
#[ must_use]
672
- pub fn new ( map_observer : & O ) -> Self {
683
+ pub fn new ( map_observer : & A ) -> Self {
684
+ let map_observer = map_observer. as_ref ( ) ;
673
685
Self {
674
- novelties : if O :: NOVELTIES { Some ( vec ! [ ] ) } else { None } ,
686
+ novelties : if A :: NOVELTIES { Some ( vec ! [ ] ) } else { None } ,
675
687
name : MAPFEEDBACK_PREFIX . to_string ( ) + map_observer. name ( ) ,
676
688
observer_name : map_observer. name ( ) . to_string ( ) ,
677
689
stats_name : create_stats_name ( map_observer. name ( ) ) ,
@@ -680,19 +692,6 @@ where
680
692
}
681
693
}
682
694
683
- /// Create new `MapFeedback`
684
- #[ must_use]
685
- pub fn with_names ( name : & ' static str , observer_name : & ' static str ) -> Self {
686
- Self {
687
- novelties : if O :: NOVELTIES { Some ( vec ! [ ] ) } else { None } ,
688
- name : name. to_string ( ) ,
689
- observer_name : observer_name. to_string ( ) ,
690
- stats_name : create_stats_name ( name) ,
691
- phantom : PhantomData ,
692
- always_track : false ,
693
- }
694
- }
695
-
696
695
/// For tracking, enable `always_track` mode, that also adds `novelties` or `indexes`,
697
696
/// even if the map is not novel for this feedback.
698
697
/// This is useful in combination with `load_initial_inputs_forced`, or other feedbacks.
@@ -704,9 +703,10 @@ where
704
703
/// feedback is needed twice, but with a different history. Using `new()` always results in the
705
704
/// same name and therefore also the same history.
706
705
#[ must_use]
707
- pub fn with_name ( name : & ' static str , map_observer : & O ) -> Self {
706
+ pub fn with_name ( name : & ' static str , map_observer : & A ) -> Self {
707
+ let map_observer = map_observer. as_ref ( ) ;
708
708
Self {
709
- novelties : if O :: NOVELTIES { Some ( vec ! [ ] ) } else { None } ,
709
+ novelties : if A :: NOVELTIES { Some ( vec ! [ ] ) } else { None } ,
710
710
name : name. to_string ( ) ,
711
711
observer_name : map_observer. name ( ) . to_string ( ) ,
712
712
stats_name : create_stats_name ( name) ,
0 commit comments